aboutsummaryrefslogtreecommitdiff
path: root/src/backend/executor/nodeIndexscan.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2008-04-13 20:51:21 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2008-04-13 20:51:21 +0000
commit226837e57eb6092b160e7272e7d09a3748c0eb47 (patch)
tree9d69fdeed5f89838191d2ba223e0d7a920bd4797 /src/backend/executor/nodeIndexscan.c
parent24558da14a26337e945732d3b435b07edcbb6733 (diff)
downloadpostgresql-226837e57eb6092b160e7272e7d09a3748c0eb47.tar.gz
postgresql-226837e57eb6092b160e7272e7d09a3748c0eb47.zip
Since createplan.c no longer cares whether index operators are lossy, it has
no particular need to do get_op_opfamily_properties() while building an indexscan plan. Postpone that lookup until executor start. This simplifies createplan.c a lot more than it complicates nodeIndexscan.c, and makes things more uniform since we already had to do it that way for RowCompare expressions. Should be a bit faster too, at least for plans that aren't re-used many times, since we avoid palloc'ing and perhaps copying the intermediate list data structure.
Diffstat (limited to 'src/backend/executor/nodeIndexscan.c')
-rw-r--r--src/backend/executor/nodeIndexscan.c94
1 files changed, 47 insertions, 47 deletions
diff --git a/src/backend/executor/nodeIndexscan.c b/src/backend/executor/nodeIndexscan.c
index 7b6e3df6506..f90c95ed264 100644
--- a/src/backend/executor/nodeIndexscan.c
+++ b/src/backend/executor/nodeIndexscan.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/executor/nodeIndexscan.c,v 1.127 2008/04/13 19:18:14 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/executor/nodeIndexscan.c,v 1.128 2008/04/13 20:51:20 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -576,8 +576,6 @@ ExecInitIndexScan(IndexScan *node, EState *estate, int eflags)
ExecIndexBuildScanKeys((PlanState *) indexstate,
indexstate->iss_RelationDesc,
node->indexqual,
- node->indexstrategy,
- node->indexsubtype,
&indexstate->iss_ScanKeys,
&indexstate->iss_NumScanKeys,
&indexstate->iss_RuntimeKeys,
@@ -655,12 +653,6 @@ ExecInitIndexScan(IndexScan *node, EState *estate, int eflags)
* planstate: executor state node we are working for
* index: the index we are building scan keys for
* quals: indexquals expressions
- * strategies: associated operator strategy numbers
- * subtypes: associated operator subtype OIDs
- *
- * (Any elements of the strategies and subtypes lists that correspond to
- * RowCompareExpr quals are not used here; instead we look up the info
- * afresh.)
*
* Output params are:
*
@@ -675,15 +667,12 @@ ExecInitIndexScan(IndexScan *node, EState *estate, int eflags)
* ScalarArrayOpExpr quals are not supported.
*/
void
-ExecIndexBuildScanKeys(PlanState *planstate, Relation index,
- List *quals, List *strategies, List *subtypes,
+ExecIndexBuildScanKeys(PlanState *planstate, Relation index, List *quals,
ScanKey *scanKeys, int *numScanKeys,
IndexRuntimeKeyInfo **runtimeKeys, int *numRuntimeKeys,
IndexArrayKeyInfo **arrayKeys, int *numArrayKeys)
{
ListCell *qual_cell;
- ListCell *strategy_cell;
- ListCell *subtype_cell;
ScanKey scan_keys;
IndexRuntimeKeyInfo *runtime_keys;
IndexArrayKeyInfo *array_keys;
@@ -725,40 +714,31 @@ ExecIndexBuildScanKeys(PlanState *planstate, Relation index,
extra_scan_keys = n_scan_keys;
/*
- * for each opclause in the given qual, convert each qual's opclause into
+ * for each opclause in the given qual, convert the opclause into
* a single scan key
*/
- qual_cell = list_head(quals);
- strategy_cell = list_head(strategies);
- subtype_cell = list_head(subtypes);
-
- for (j = 0; j < n_scan_keys; j++)
+ j = 0;
+ foreach(qual_cell, quals)
{
- ScanKey this_scan_key = &scan_keys[j];
- Expr *clause; /* one clause of index qual */
+ Expr *clause = (Expr *) lfirst(qual_cell);
+ ScanKey this_scan_key = &scan_keys[j++];
+ Oid opno; /* operator's OID */
RegProcedure opfuncid; /* operator proc id used in scan */
- StrategyNumber strategy; /* op's strategy number */
- Oid subtype; /* op's strategy subtype */
+ Oid opfamily; /* opfamily of index column */
+ int op_strategy; /* operator's strategy number */
+ Oid op_lefttype; /* operator's declared input types */
+ Oid op_righttype;
Expr *leftop; /* expr on lhs of operator */
Expr *rightop; /* expr on rhs ... */
AttrNumber varattno; /* att number used in scan */
- /*
- * extract clause information from the qualification
- */
- clause = (Expr *) lfirst(qual_cell);
- qual_cell = lnext(qual_cell);
- strategy = lfirst_int(strategy_cell);
- strategy_cell = lnext(strategy_cell);
- subtype = lfirst_oid(subtype_cell);
- subtype_cell = lnext(subtype_cell);
-
if (IsA(clause, OpExpr))
{
/* indexkey op const or indexkey op expression */
int flags = 0;
Datum scanvalue;
+ opno = ((OpExpr *) clause)->opno;
opfuncid = ((OpExpr *) clause)->opfuncid;
/*
@@ -776,6 +756,19 @@ ExecIndexBuildScanKeys(PlanState *planstate, Relation index,
elog(ERROR, "indexqual doesn't have key on left side");
varattno = ((Var *) leftop)->varattno;
+ if (varattno < 1 || varattno > index->rd_index->indnatts)
+ elog(ERROR, "bogus index qualification");
+
+ /*
+ * We have to look up the operator's strategy number. This
+ * provides a cross-check that the operator does match the index.
+ */
+ opfamily = index->rd_opfamily[varattno - 1];
+
+ get_op_opfamily_properties(opno, opfamily,
+ &op_strategy,
+ &op_lefttype,
+ &op_righttype);
/*
* rightop is the constant or variable comparison value
@@ -810,8 +803,8 @@ ExecIndexBuildScanKeys(PlanState *planstate, Relation index,
ScanKeyEntryInitialize(this_scan_key,
flags,
varattno, /* attribute number to scan */
- strategy, /* op's strategy */
- subtype, /* strategy subtype */
+ op_strategy, /* op's strategy */
+ op_righttype, /* strategy subtype */
opfuncid, /* reg proc to use */
scanvalue); /* constant */
}
@@ -830,12 +823,6 @@ ExecIndexBuildScanKeys(PlanState *planstate, Relation index,
ScanKey this_sub_key = &scan_keys[extra_scan_keys];
int flags = SK_ROW_MEMBER;
Datum scanvalue;
- Oid opno;
- Oid opfamily;
- int op_strategy;
- Oid op_lefttype;
- Oid op_righttype;
- bool op_recheck;
/*
* leftop should be the index key Var, possibly relabeled
@@ -897,8 +884,7 @@ ExecIndexBuildScanKeys(PlanState *planstate, Relation index,
get_op_opfamily_properties(opno, opfamily,
&op_strategy,
&op_lefttype,
- &op_righttype,
- &op_recheck);
+ &op_righttype);
if (op_strategy != rc->rctype)
elog(ERROR, "RowCompare index qualification contains wrong operator");
@@ -941,6 +927,7 @@ ExecIndexBuildScanKeys(PlanState *planstate, Relation index,
ScalarArrayOpExpr *saop = (ScalarArrayOpExpr *) clause;
Assert(saop->useOr);
+ opno = saop->opno;
opfuncid = saop->opfuncid;
/*
@@ -958,6 +945,19 @@ ExecIndexBuildScanKeys(PlanState *planstate, Relation index,
elog(ERROR, "indexqual doesn't have key on left side");
varattno = ((Var *) leftop)->varattno;
+ if (varattno < 1 || varattno > index->rd_index->indnatts)
+ elog(ERROR, "bogus index qualification");
+
+ /*
+ * We have to look up the operator's strategy number. This
+ * provides a cross-check that the operator does match the index.
+ */
+ opfamily = index->rd_opfamily[varattno - 1];
+
+ get_op_opfamily_properties(opno, opfamily,
+ &op_strategy,
+ &op_lefttype,
+ &op_righttype);
/*
* rightop is the constant or variable array value
@@ -981,8 +981,8 @@ ExecIndexBuildScanKeys(PlanState *planstate, Relation index,
ScanKeyEntryInitialize(this_scan_key,
0, /* flags */
varattno, /* attribute number to scan */
- strategy, /* op's strategy */
- subtype, /* strategy subtype */
+ op_strategy, /* op's strategy */
+ op_righttype, /* strategy subtype */
opfuncid, /* reg proc to use */
(Datum) 0); /* constant */
}
@@ -1013,8 +1013,8 @@ ExecIndexBuildScanKeys(PlanState *planstate, Relation index,
ScanKeyEntryInitialize(this_scan_key,
SK_ISNULL | SK_SEARCHNULL,
varattno, /* attribute number to scan */
- strategy, /* op's strategy */
- subtype, /* strategy subtype */
+ InvalidStrategy, /* no strategy */
+ InvalidOid, /* no strategy subtype */
InvalidOid, /* no reg proc for this */
(Datum) 0); /* constant */
}