summaryrefslogtreecommitdiff
path: root/src/backend/optimizer/plan/createplan.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/optimizer/plan/createplan.c')
-rw-r--r--src/backend/optimizer/plan/createplan.c84
1 files changed, 49 insertions, 35 deletions
diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c
index f50eb792811..0d55dd7f8c3 100644
--- a/src/backend/optimizer/plan/createplan.c
+++ b/src/backend/optimizer/plan/createplan.c
@@ -10,7 +10,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/createplan.c,v 1.142 2003/05/12 00:17:03 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/createplan.c,v 1.143 2003/05/28 16:03:56 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -1198,60 +1198,74 @@ fix_indxqual_operand(Node *node, int baserelid, IndexOptInfo *index,
Oid *opclass)
{
/*
- * Remove any binary-compatible relabeling of the indexkey
- */
- if (IsA(node, RelabelType))
- node = (Node *) ((RelabelType *) node)->arg;
-
- /*
* We represent index keys by Var nodes having the varno of the base
* table but varattno equal to the index's attribute number (index
* column position). This is a bit hokey ... would be cleaner to use
* a special-purpose node type that could not be mistaken for a
* regular Var. But it will do for now.
*/
- if (IsA(node, Var))
+ Var *result;
+ int pos;
+ List *indexprs;
+
+ /*
+ * Remove any binary-compatible relabeling of the indexkey
+ */
+ if (IsA(node, RelabelType))
+ node = (Node *) ((RelabelType *) node)->arg;
+
+ if (IsA(node, Var) &&
+ ((Var *) node)->varno == baserelid)
{
- /* If it's a var, find which index key position it occupies */
- Assert(index->indproc == InvalidOid);
+ /* Try to match against simple index columns */
+ int varatt = ((Var *) node)->varattno;
- if (((Var *) node)->varno == baserelid)
+ if (varatt != 0)
{
- int varatt = ((Var *) node)->varattno;
- int pos;
-
- for (pos = 0; pos < index->nkeys; pos++)
+ for (pos = 0; pos < index->ncolumns; pos++)
{
if (index->indexkeys[pos] == varatt)
{
- Node *newnode = copyObject(node);
-
- ((Var *) newnode)->varattno = pos + 1;
+ result = (Var *) copyObject(node);
+ result->varattno = pos + 1;
/* return the correct opclass, too */
*opclass = index->classlist[pos];
- return newnode;
+ return (Node *) result;
}
}
}
-
- /*
- * Oops, this Var isn't an indexkey!
- */
- elog(ERROR, "fix_indxqual_operand: var is not index attribute");
}
- /*
- * Else, it must be a func expression matching a functional index.
- * Since we currently only support single-column functional indexes,
- * the returned varattno must be 1.
- */
- Assert(index->indproc != InvalidOid);
- Assert(is_funcclause(node)); /* not a very thorough check, but easy */
-
- /* classlist[0] is the only class of a functional index */
- *opclass = index->classlist[0];
+ /* Try to match against index expressions */
+ indexprs = index->indexprs;
+ for (pos = 0; pos < index->ncolumns; pos++)
+ {
+ if (index->indexkeys[pos] == 0)
+ {
+ Node *indexkey;
+
+ if (indexprs == NIL)
+ elog(ERROR, "too few entries in indexprs list");
+ indexkey = (Node *) lfirst(indexprs);
+ if (indexkey && IsA(indexkey, RelabelType))
+ indexkey = (Node *) ((RelabelType *) indexkey)->arg;
+ if (equal(node, indexkey))
+ {
+ /* Found a match */
+ result = makeVar(baserelid, pos + 1,
+ exprType(lfirst(indexprs)), -1,
+ 0);
+ /* return the correct opclass, too */
+ *opclass = index->classlist[pos];
+ return (Node *) result;
+ }
+ indexprs = lnext(indexprs);
+ }
+ }
- return (Node *) makeVar(baserelid, 1, exprType(node), -1, 0);
+ /* Ooops... */
+ elog(ERROR, "fix_indxqual_operand: node is not index attribute");
+ return NULL; /* keep compiler quiet */
}
/*