Further cleanup of indxpath logic related to IndexOptInfo.opfamily array.
authorTom Lane <[email protected]>
Sat, 20 Nov 2010 20:07:16 +0000 (15:07 -0500)
committerTom Lane <[email protected]>
Sat, 20 Nov 2010 20:07:16 +0000 (15:07 -0500)
We no longer need the terminating zero entry in opfamily[], so get rid of
it.  Also replace assorted ad-hoc looping logic with simple for and foreach
constructs.  This code is now noticeably more readable than it was an hour
ago; credit to Robert for seeing that it could be simplified.

src/backend/optimizer/path/indxpath.c
src/backend/optimizer/util/plancat.c
src/include/nodes/relation.h

index e14d0f5f02c3c2b9aee52e29e7b4f5eb1e569dbb..d8fc12068fb6113c0baf8aa4e5941e0150ce3521 100644 (file)
@@ -1047,14 +1047,14 @@ group_clauses_by_indexkey(IndexOptInfo *index,
 {
    List       *clausegroup_list = NIL;
    bool        found_outer_clause = false;
-   int         indexcol = 0;
+   int         indexcol;
 
    *found_clause = false;      /* default result */
 
    if (clauses == NIL && outer_clauses == NIL)
        return NIL;             /* cannot succeed */
 
-   do
+   for (indexcol = 0; indexcol < index->ncolumns; indexcol++)
    {
        List       *clausegroup = NIL;
        ListCell   *l;
@@ -1102,10 +1102,7 @@ group_clauses_by_indexkey(IndexOptInfo *index,
            return NIL;
 
        clausegroup_list = lappend(clausegroup_list, clausegroup);
-
-       indexcol++;
-
-   } while (indexcol < index->ncolumns);
+   }
 
    if (!*found_clause && !found_outer_clause)
        return NIL;             /* no indexable clauses anywhere */
@@ -1163,8 +1160,8 @@ group_clauses_by_indexkey(IndexOptInfo *index,
  *
  * 'index' is the index of interest.
  * 'indexcol' is a column number of 'index' (counting from 0).
- * 'opfamily' is the corresponding operator family.
  * 'rinfo' is the clause to be tested (as a RestrictInfo node).
+ * 'outer_relids' lists rels whose Vars can be considered pseudoconstant.
  * 'saop_control' indicates whether ScalarArrayOpExpr clauses can be used.
  *
  * Returns true if the clause can be used with this index key.
@@ -1180,12 +1177,12 @@ match_clause_to_indexcol(IndexOptInfo *index,
                         SaOpControl saop_control)
 {
    Expr       *clause = rinfo->clause;
+   Oid         opfamily = index->opfamily[indexcol];
    Node       *leftop,
               *rightop;
    Relids      left_relids;
    Relids      right_relids;
    Oid         expr_op;
-   Oid         opfamily = index->opfamily[indexcol];
    bool        plain_op;
 
    /*
@@ -1571,9 +1568,9 @@ matches_any_index(RestrictInfo *rinfo, RelOptInfo *rel, Relids outer_relids)
    foreach(l, rel->indexlist)
    {
        IndexOptInfo *index = (IndexOptInfo *) lfirst(l);
-       int         indexcol = 0;
+       int         indexcol;
 
-       do
+       for (indexcol = 0; indexcol < index->ncolumns; indexcol++)
        {
            if (match_clause_to_indexcol(index,
                                         indexcol,
@@ -1581,9 +1578,7 @@ matches_any_index(RestrictInfo *rinfo, RelOptInfo *rel, Relids outer_relids)
                                         outer_relids,
                                         SAOP_ALLOW))
                return true;
-
-           indexcol++;
-       } while (indexcol < index->ncolumns);
+       }
    }
 
    return false;
@@ -1605,9 +1600,9 @@ eclass_matches_any_index(EquivalenceClass *ec, EquivalenceMember *em,
    foreach(l, rel->indexlist)
    {
        IndexOptInfo *index = (IndexOptInfo *) lfirst(l);
-       int         indexcol = 0;
+       int         indexcol;
 
-       do
+       for (indexcol = 0; indexcol < index->ncolumns; indexcol++)
        {
            Oid         curFamily = index->opfamily[indexcol];
 
@@ -1625,9 +1620,7 @@ eclass_matches_any_index(EquivalenceClass *ec, EquivalenceMember *em,
                 list_member_oid(ec->ec_opfamilies, curFamily)) &&
                match_index_to_operand((Node *) em->em_expr, indexcol, index))
                return true;
-
-           indexcol++;
-       } while (indexcol < index->ncolumns);
+       }
    }
 
    return false;
@@ -2360,21 +2353,25 @@ List *
 expand_indexqual_conditions(IndexOptInfo *index, List *clausegroups)
 {
    List       *resultquals = NIL;
-   ListCell   *clausegroup_item;
-   int         indexcol = 0;
+   ListCell   *lc;
+   int         indexcol;
 
    if (clausegroups == NIL)
        return NIL;
 
-   clausegroup_item = list_head(clausegroups);
-   do
+   /* clausegroups must correspond to index columns */
+   Assert(list_length(clausegroups) <= index->ncolumns);
+
+   indexcol = 0;
+   foreach(lc, clausegroups)
    {
+       List       *clausegroup = (List *) lfirst(lc);
        Oid         curFamily = index->opfamily[indexcol];
-       ListCell   *l;
+       ListCell   *lc2;
 
-       foreach(l, (List *) lfirst(clausegroup_item))
+       foreach(lc2, clausegroup)
        {
-           RestrictInfo *rinfo = (RestrictInfo *) lfirst(l);
+           RestrictInfo *rinfo = (RestrictInfo *) lfirst(lc2);
            Expr       *clause = rinfo->clause;
 
            /* First check for boolean cases */
@@ -2426,12 +2423,8 @@ expand_indexqual_conditions(IndexOptInfo *index, List *clausegroups)
                     (int) nodeTag(clause));
        }
 
-       clausegroup_item = lnext(clausegroup_item);
-
        indexcol++;
-   } while (clausegroup_item != NULL && indexcol < index->ncolumns);
-
-   Assert(clausegroup_item == NULL);   /* else more groups than indexkeys */
+   }
 
    return resultquals;
 }
index aafaf843fcc290a971589324c261a6fe08eb4c98..73132ddf5ca8e6a7a4abb29eca4e67eb58d22480 100644 (file)
@@ -192,13 +192,13 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent,
 
            /*
             * Allocate per-column info arrays.  To save a few palloc cycles
-            * we allocate all the Oid-type arrays in one request.  Note that
-            * the opfamily array needs an extra, terminating zero at the end.
-            * We pre-zero the ordering info in case the index is unordered.
+            * we allocate all the Oid-type arrays in one request.  We must
+            * pre-zero the sortop and nulls_first arrays in case the index is
+            * unordered.
             */
            info->indexkeys = (int *) palloc(sizeof(int) * ncolumns);
-           info->opfamily = (Oid *) palloc0(sizeof(Oid) * (4 * ncolumns + 1));
-           info->opcintype = info->opfamily + (ncolumns + 1);
+           info->opfamily = (Oid *) palloc0(sizeof(Oid) * (4 * ncolumns));
+           info->opcintype = info->opfamily + ncolumns;
            info->fwdsortop = info->opcintype + ncolumns;
            info->revsortop = info->fwdsortop + ncolumns;
            info->nulls_first = (bool *) palloc0(sizeof(bool) * ncolumns);
index 81126a236656cdec77a822b3fb3a50b59364d81e..677134dcec9e1443bef255eab7a5679fa7ca1e6c 100644 (file)
@@ -427,9 +427,6 @@ typedef struct RelOptInfo
  *
  *     opfamily[], indexkeys[], opcintype[], fwdsortop[], revsortop[],
  *     and nulls_first[] each have ncolumns entries.
- *     Note: for historical reasons, the opfamily array has an extra entry
- *     that is always zero.  Some code scans until it sees a zero entry,
- *     rather than looking at ncolumns.
  *
  *     Zeroes in the indexkeys[] array indicate index columns that are
  *     expressions; there is one element in indexprs for each such column.