diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2008-04-13 20:51:21 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2008-04-13 20:51:21 +0000 |
commit | 226837e57eb6092b160e7272e7d09a3748c0eb47 (patch) | |
tree | 9d69fdeed5f89838191d2ba223e0d7a920bd4797 /src/backend/executor/nodeIndexscan.c | |
parent | 24558da14a26337e945732d3b435b07edcbb6733 (diff) | |
download | postgresql-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.c | 94 |
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 */ } |