aboutsummaryrefslogtreecommitdiff
path: root/src/backend/executor/nodeIndexscan.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2000-08-13 02:50:35 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2000-08-13 02:50:35 +0000
commit37168b8da43d9a6f7471cf757119ece6c96fb2b9 (patch)
treece7059e77ac05a045f9de7c6272c7e1c8210d96a /src/backend/executor/nodeIndexscan.c
parent766fb7f707f9527be219353f5f970aab3d786554 (diff)
downloadpostgresql-37168b8da43d9a6f7471cf757119ece6c96fb2b9.tar.gz
postgresql-37168b8da43d9a6f7471cf757119ece6c96fb2b9.zip
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.
Diffstat (limited to 'src/backend/executor/nodeIndexscan.c')
-rw-r--r--src/backend/executor/nodeIndexscan.c34
1 files changed, 23 insertions, 11 deletions
diff --git a/src/backend/executor/nodeIndexscan.c b/src/backend/executor/nodeIndexscan.c
index 0eb3b9f5ae9..57770d24058 100644
--- a/src/backend/executor/nodeIndexscan.c
+++ b/src/backend/executor/nodeIndexscan.c
@@ -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.
* ----------------