1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-02 09:02:37 +03:00

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.
This commit is contained in:
Tom Lane
2008-04-13 20:51:21 +00:00
parent 24558da14a
commit 226837e57e
13 changed files with 96 additions and 219 deletions

View File

@ -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 */
}