Further cleanup of indxpath logic related to IndexOptInfo.opfamily array.

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.
This commit is contained in:
Tom Lane 2010-11-20 15:07:16 -05:00
parent 99bc012d51
commit 89a368418c
3 changed files with 30 additions and 40 deletions

View 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
{
Oid curFamily = index->opfamily[indexcol];
ListCell *l;
/* clausegroups must correspond to index columns */
Assert(list_length(clausegroups) <= index->ncolumns);
foreach(l, (List *) lfirst(clausegroup_item))
indexcol = 0;
foreach(lc, clausegroups)
{
List *clausegroup = (List *) lfirst(lc);
Oid curFamily = index->opfamily[indexcol];
ListCell *lc2;
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;
}

View 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);

View 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.