Commit 89a36841 authored by Tom Lane's avatar Tom Lane

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.
parent 99bc012d
...@@ -1047,14 +1047,14 @@ group_clauses_by_indexkey(IndexOptInfo *index, ...@@ -1047,14 +1047,14 @@ group_clauses_by_indexkey(IndexOptInfo *index,
{ {
List *clausegroup_list = NIL; List *clausegroup_list = NIL;
bool found_outer_clause = false; bool found_outer_clause = false;
int indexcol = 0; int indexcol;
*found_clause = false; /* default result */ *found_clause = false; /* default result */
if (clauses == NIL && outer_clauses == NIL) if (clauses == NIL && outer_clauses == NIL)
return NIL; /* cannot succeed */ return NIL; /* cannot succeed */
do for (indexcol = 0; indexcol < index->ncolumns; indexcol++)
{ {
List *clausegroup = NIL; List *clausegroup = NIL;
ListCell *l; ListCell *l;
...@@ -1102,10 +1102,7 @@ group_clauses_by_indexkey(IndexOptInfo *index, ...@@ -1102,10 +1102,7 @@ group_clauses_by_indexkey(IndexOptInfo *index,
return NIL; return NIL;
clausegroup_list = lappend(clausegroup_list, clausegroup); clausegroup_list = lappend(clausegroup_list, clausegroup);
}
indexcol++;
} while (indexcol < index->ncolumns);
if (!*found_clause && !found_outer_clause) if (!*found_clause && !found_outer_clause)
return NIL; /* no indexable clauses anywhere */ return NIL; /* no indexable clauses anywhere */
...@@ -1163,8 +1160,8 @@ group_clauses_by_indexkey(IndexOptInfo *index, ...@@ -1163,8 +1160,8 @@ group_clauses_by_indexkey(IndexOptInfo *index,
* *
* 'index' is the index of interest. * 'index' is the index of interest.
* 'indexcol' is a column number of 'index' (counting from 0). * '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). * '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. * 'saop_control' indicates whether ScalarArrayOpExpr clauses can be used.
* *
* Returns true if the clause can be used with this index key. * Returns true if the clause can be used with this index key.
...@@ -1180,12 +1177,12 @@ match_clause_to_indexcol(IndexOptInfo *index, ...@@ -1180,12 +1177,12 @@ match_clause_to_indexcol(IndexOptInfo *index,
SaOpControl saop_control) SaOpControl saop_control)
{ {
Expr *clause = rinfo->clause; Expr *clause = rinfo->clause;
Oid opfamily = index->opfamily[indexcol];
Node *leftop, Node *leftop,
*rightop; *rightop;
Relids left_relids; Relids left_relids;
Relids right_relids; Relids right_relids;
Oid expr_op; Oid expr_op;
Oid opfamily = index->opfamily[indexcol];
bool plain_op; bool plain_op;
/* /*
...@@ -1571,9 +1568,9 @@ matches_any_index(RestrictInfo *rinfo, RelOptInfo *rel, Relids outer_relids) ...@@ -1571,9 +1568,9 @@ matches_any_index(RestrictInfo *rinfo, RelOptInfo *rel, Relids outer_relids)
foreach(l, rel->indexlist) foreach(l, rel->indexlist)
{ {
IndexOptInfo *index = (IndexOptInfo *) lfirst(l); IndexOptInfo *index = (IndexOptInfo *) lfirst(l);
int indexcol = 0; int indexcol;
do for (indexcol = 0; indexcol < index->ncolumns; indexcol++)
{ {
if (match_clause_to_indexcol(index, if (match_clause_to_indexcol(index,
indexcol, indexcol,
...@@ -1581,9 +1578,7 @@ matches_any_index(RestrictInfo *rinfo, RelOptInfo *rel, Relids outer_relids) ...@@ -1581,9 +1578,7 @@ matches_any_index(RestrictInfo *rinfo, RelOptInfo *rel, Relids outer_relids)
outer_relids, outer_relids,
SAOP_ALLOW)) SAOP_ALLOW))
return true; return true;
}
indexcol++;
} while (indexcol < index->ncolumns);
} }
return false; return false;
...@@ -1605,9 +1600,9 @@ eclass_matches_any_index(EquivalenceClass *ec, EquivalenceMember *em, ...@@ -1605,9 +1600,9 @@ eclass_matches_any_index(EquivalenceClass *ec, EquivalenceMember *em,
foreach(l, rel->indexlist) foreach(l, rel->indexlist)
{ {
IndexOptInfo *index = (IndexOptInfo *) lfirst(l); IndexOptInfo *index = (IndexOptInfo *) lfirst(l);
int indexcol = 0; int indexcol;
do for (indexcol = 0; indexcol < index->ncolumns; indexcol++)
{ {
Oid curFamily = index->opfamily[indexcol]; Oid curFamily = index->opfamily[indexcol];
...@@ -1625,9 +1620,7 @@ eclass_matches_any_index(EquivalenceClass *ec, EquivalenceMember *em, ...@@ -1625,9 +1620,7 @@ eclass_matches_any_index(EquivalenceClass *ec, EquivalenceMember *em,
list_member_oid(ec->ec_opfamilies, curFamily)) && list_member_oid(ec->ec_opfamilies, curFamily)) &&
match_index_to_operand((Node *) em->em_expr, indexcol, index)) match_index_to_operand((Node *) em->em_expr, indexcol, index))
return true; return true;
}
indexcol++;
} while (indexcol < index->ncolumns);
} }
return false; return false;
...@@ -2360,21 +2353,25 @@ List * ...@@ -2360,21 +2353,25 @@ List *
expand_indexqual_conditions(IndexOptInfo *index, List *clausegroups) expand_indexqual_conditions(IndexOptInfo *index, List *clausegroups)
{ {
List *resultquals = NIL; List *resultquals = NIL;
ListCell *clausegroup_item; ListCell *lc;
int indexcol = 0; int indexcol;
if (clausegroups == NIL) if (clausegroups == NIL)
return NIL; return NIL;
clausegroup_item = list_head(clausegroups); /* clausegroups must correspond to index columns */
do Assert(list_length(clausegroups) <= index->ncolumns);
indexcol = 0;
foreach(lc, clausegroups)
{ {
List *clausegroup = (List *) lfirst(lc);
Oid curFamily = index->opfamily[indexcol]; 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; Expr *clause = rinfo->clause;
/* First check for boolean cases */ /* First check for boolean cases */
...@@ -2426,12 +2423,8 @@ expand_indexqual_conditions(IndexOptInfo *index, List *clausegroups) ...@@ -2426,12 +2423,8 @@ expand_indexqual_conditions(IndexOptInfo *index, List *clausegroups)
(int) nodeTag(clause)); (int) nodeTag(clause));
} }
clausegroup_item = lnext(clausegroup_item);
indexcol++; indexcol++;
} while (clausegroup_item != NULL && indexcol < index->ncolumns); }
Assert(clausegroup_item == NULL); /* else more groups than indexkeys */
return resultquals; return resultquals;
} }
......
...@@ -192,13 +192,13 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, ...@@ -192,13 +192,13 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent,
/* /*
* Allocate per-column info arrays. To save a few palloc cycles * Allocate per-column info arrays. To save a few palloc cycles
* we allocate all the Oid-type arrays in one request. Note that * we allocate all the Oid-type arrays in one request. We must
* the opfamily array needs an extra, terminating zero at the end. * pre-zero the sortop and nulls_first arrays in case the index is
* We pre-zero the ordering info in case the index is unordered. * unordered.
*/ */
info->indexkeys = (int *) palloc(sizeof(int) * ncolumns); info->indexkeys = (int *) palloc(sizeof(int) * ncolumns);
info->opfamily = (Oid *) palloc0(sizeof(Oid) * (4 * ncolumns + 1)); info->opfamily = (Oid *) palloc0(sizeof(Oid) * (4 * ncolumns));
info->opcintype = info->opfamily + (ncolumns + 1); info->opcintype = info->opfamily + ncolumns;
info->fwdsortop = info->opcintype + ncolumns; info->fwdsortop = info->opcintype + ncolumns;
info->revsortop = info->fwdsortop + ncolumns; info->revsortop = info->fwdsortop + ncolumns;
info->nulls_first = (bool *) palloc0(sizeof(bool) * ncolumns); info->nulls_first = (bool *) palloc0(sizeof(bool) * ncolumns);
......
...@@ -427,9 +427,6 @@ typedef struct RelOptInfo ...@@ -427,9 +427,6 @@ typedef struct RelOptInfo
* *
* opfamily[], indexkeys[], opcintype[], fwdsortop[], revsortop[], * opfamily[], indexkeys[], opcintype[], fwdsortop[], revsortop[],
* and nulls_first[] each have ncolumns entries. * 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 * Zeroes in the indexkeys[] array indicate index columns that are
* expressions; there is one element in indexprs for each such column. * expressions; there is one element in indexprs for each such column.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment