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

Clean up handling of variable-free qual clauses. System now does the

right thing with variable-free clauses that contain noncachable functions,
such as 'WHERE random() < 0.5' --- these are evaluated once per
potential output tuple.  Expressions that contain only Params are
now candidates to be indexscan quals --- for example, 'var = ($1 + 1)'
can now be indexed.  Cope with RelabelType nodes atop potential indexscan
variables --- this oversight prevents 7.0.* from recognizing some
potentially indexscanable situations.
This commit is contained in:
Tom Lane
2000-08-13 02:50:35 +00:00
parent 766fb7f707
commit 37168b8da4
15 changed files with 410 additions and 177 deletions

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/executor/nodeIndexscan.c,v 1.52 2000/07/12 02:37:03 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/executor/nodeIndexscan.c,v 1.53 2000/08/13 02:50:03 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -281,6 +281,16 @@ IndexNext(IndexScan *node)
TupleTableSlot *
ExecIndexScan(IndexScan *node)
{
IndexScanState *indexstate = node->indxstate;
/* ----------------
* If we have runtime keys and they've not already been set up,
* do it now.
* ----------------
*/
if (indexstate->iss_RuntimeKeyInfo && !indexstate->iss_RuntimeKeysReady)
ExecReScan((Plan *) node, NULL, NULL);
/* ----------------
* use IndexNext as access method
* ----------------
@ -335,9 +345,10 @@ ExecIndexReScan(IndexScan *node, ExprContext *exprCtxt, Plan *parent)
scanKeys = indexstate->iss_ScanKeys;
runtimeKeyInfo = indexstate->iss_RuntimeKeyInfo;
numScanKeys = indexstate->iss_NumScanKeys;
indexstate->iss_IndexPtr = -1;
if (ScanDirectionIsBackward(node->indxorderdir))
indexstate->iss_IndexPtr = numIndices;
else
indexstate->iss_IndexPtr = -1;
if (econtext)
{
@ -420,6 +431,9 @@ ExecIndexReScan(IndexScan *node, ExprContext *exprCtxt, Plan *parent)
skey = scanKeys[i];
index_rescan(scan, direction, skey);
}
if (runtimeKeyInfo)
indexstate->iss_RuntimeKeysReady = true;
}
/* ----------------------------------------------------------------
@ -603,7 +617,6 @@ ExecInitIndexScan(IndexScan *node, EState *estate, Plan *parent)
Relation currentRelation;
HeapScanDesc currentScanDesc;
ScanDirection direction;
List *execParam = NIL;
/* ----------------
* assign execution state to node
@ -656,6 +669,7 @@ ExecInitIndexScan(IndexScan *node, EState *estate, Plan *parent)
indexstate->iss_NumScanKeys = NULL;
indexstate->iss_RuntimeKeyInfo = NULL;
indexstate->iss_RuntimeContext = NULL;
indexstate->iss_RuntimeKeysReady = false;
indexstate->iss_RelationDescs = NULL;
indexstate->iss_ScanDescs = NULL;
@ -787,6 +801,9 @@ ExecInitIndexScan(IndexScan *node, EState *estate, Plan *parent)
*/
leftop = (Node *) get_leftop(clause);
if (leftop && IsA(leftop, RelabelType))
leftop = ((RelabelType *) leftop)->arg;
Assert(leftop != NULL);
if (IsA(leftop, Var) && var_is_rel((Var *) leftop))
@ -827,7 +844,6 @@ ExecInitIndexScan(IndexScan *node, EState *estate, Plan *parent)
/* treat Param as runtime key */
have_runtime_keys = true;
run_keys[j] = LEFT_OP;
execParam = lappendi(execParam, ((Param *) leftop)->paramid);
}
else
{
@ -857,6 +873,9 @@ ExecInitIndexScan(IndexScan *node, EState *estate, Plan *parent)
*/
rightop = (Node *) get_rightop(clause);
if (rightop && IsA(rightop, RelabelType))
rightop = ((RelabelType *) rightop)->arg;
Assert(rightop != NULL);
if (IsA(rightop, Var) && var_is_rel((Var *) rightop))
@ -906,7 +925,6 @@ ExecInitIndexScan(IndexScan *node, EState *estate, Plan *parent)
/* treat Param as runtime key */
have_runtime_keys = true;
run_keys[j] = RIGHT_OP;
execParam = lappendi(execParam, ((Param *) rightop)->paramid);
}
else
{
@ -1068,12 +1086,6 @@ ExecInitIndexScan(IndexScan *node, EState *estate, Plan *parent)
indexstate->iss_RelationDescs = relationDescs;
indexstate->iss_ScanDescs = scanDescs;
/*
* if there are some PARAM_EXEC in scankeys then force index rescan on
* first scan.
*/
((Plan *) node)->chgParam = execParam;
/* ----------------
* all done.
* ----------------