diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2002-12-13 19:46:01 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2002-12-13 19:46:01 +0000 |
commit | 3a4f7dde16ad81b2319b9a4924a6023710a2fefd (patch) | |
tree | 248cf66fd94d40072b5ba8bb8e5437a6ea8399e5 /src/backend/executor/nodeIndexscan.c | |
parent | 77b7a740f95250af7d78f69e9c906c3e53f32e7b (diff) | |
download | postgresql-3a4f7dde16ad81b2319b9a4924a6023710a2fefd.tar.gz postgresql-3a4f7dde16ad81b2319b9a4924a6023710a2fefd.zip |
Phase 3 of read-only-plans project: ExecInitExpr now builds expression
execution state trees, and ExecEvalExpr takes an expression state tree
not an expression plan tree. The plan tree is now read-only as far as
the executor is concerned. Next step is to begin actually exploiting
this property.
Diffstat (limited to 'src/backend/executor/nodeIndexscan.c')
-rw-r--r-- | src/backend/executor/nodeIndexscan.c | 128 |
1 files changed, 31 insertions, 97 deletions
diff --git a/src/backend/executor/nodeIndexscan.c b/src/backend/executor/nodeIndexscan.c index 0112d3641de..1e36e93113d 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.73 2002/12/12 15:49:24 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/executor/nodeIndexscan.c,v 1.74 2002/12/13 19:45:52 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -283,7 +283,7 @@ ExecIndexReScan(IndexScanState *node, ExprContext *exprCtxt) int numIndices; IndexScanDescPtr scanDescs; ScanKey *scanKeys; - int **runtimeKeyInfo; + ExprState ***runtimeKeyInfo; int *numScanKeys; Index scanrelid; int i; @@ -328,29 +328,18 @@ ExecIndexReScan(IndexScanState *node, ExprContext *exprCtxt) */ if (runtimeKeyInfo) { - List *indxqual; - - indxqual = node->indxqual; for (i = 0; i < numIndices; i++) { - List *qual = lfirst(indxqual); int n_keys; ScanKey scan_keys; - int *run_keys; - List *listscan; + ExprState **run_keys; - indxqual = lnext(indxqual); n_keys = numScanKeys[i]; scan_keys = scanKeys[i]; run_keys = runtimeKeyInfo[i]; - listscan = qual; for (j = 0; j < n_keys; j++) { - Expr *clause = lfirst(listscan); - - listscan = lnext(listscan); - /* * If we have a run-time key, then extract the run-time * expression and evaluate it with respect to the current @@ -364,17 +353,12 @@ ExecIndexReScan(IndexScanState *node, ExprContext *exprCtxt) * is wrong, we could copy the result into our context * explicitly, but I think that's not necessary... */ - if (run_keys[j] != NO_OP) + if (run_keys[j] != NULL) { - Node *scanexpr; Datum scanvalue; bool isNull; - scanexpr = (run_keys[j] == RIGHT_OP) ? - (Node *) get_rightop(clause) : - (Node *) get_leftop(clause); - - scanvalue = ExecEvalExprSwitchContext(scanexpr, + scanvalue = ExecEvalExprSwitchContext(run_keys[j], econtext, &isNull, NULL); @@ -424,7 +408,7 @@ ExecIndexReScan(IndexScanState *node, ExprContext *exprCtxt) void ExecEndIndexScan(IndexScanState *node) { - int **runtimeKeyInfo; + ExprState ***runtimeKeyInfo; ScanKey *scanKeys; int *numScanKeys; int numIndices; @@ -585,7 +569,7 @@ ExecInitIndexScan(IndexScan *node, EState *estate) int *numScanKeys; RelationPtr indexDescs; IndexScanDescPtr scanDescs; - int **runtimeKeyInfo; + ExprState ***runtimeKeyInfo; bool have_runtime_keys; RangeTblEntry *rtentry; Index relid; @@ -610,16 +594,16 @@ ExecInitIndexScan(IndexScan *node, EState *estate) * initialize child expressions */ indexstate->ss.ps.targetlist = (List *) - ExecInitExpr((Node *) node->scan.plan.targetlist, + ExecInitExpr((Expr *) node->scan.plan.targetlist, (PlanState *) indexstate); indexstate->ss.ps.qual = (List *) - ExecInitExpr((Node *) node->scan.plan.qual, + ExecInitExpr((Expr *) node->scan.plan.qual, (PlanState *) indexstate); indexstate->indxqual = (List *) - ExecInitExpr((Node *) node->indxqual, + ExecInitExpr((Expr *) node->indxqual, (PlanState *) indexstate); indexstate->indxqualorig = (List *) - ExecInitExpr((Node *) node->indxqualorig, + ExecInitExpr((Expr *) node->indxqualorig, (PlanState *) indexstate); #define INDEXSCAN_NSLOTS 2 @@ -672,7 +656,7 @@ ExecInitIndexScan(IndexScan *node, EState *estate) * initialize space for runtime key info (may not be needed) */ have_runtime_keys = false; - runtimeKeyInfo = (int **) palloc(numIndices * sizeof(int *)); + runtimeKeyInfo = (ExprState ***) palloc0(numIndices * sizeof(ExprState **)); /* * build the index scan keys from the index qualification @@ -684,15 +668,15 @@ ExecInitIndexScan(IndexScan *node, EState *estate) List *qual; int n_keys; ScanKey scan_keys; - int *run_keys; + ExprState **run_keys; qual = lfirst(indxqual); indxqual = lnext(indxqual); n_keys = length(qual); scan_keys = (n_keys <= 0) ? (ScanKey) NULL : (ScanKey) palloc(n_keys * sizeof(ScanKeyData)); - run_keys = (n_keys <= 0) ? (int *) NULL : - (int *) palloc(n_keys * sizeof(int)); + run_keys = (n_keys <= 0) ? (ExprState **) NULL : + (ExprState **) palloc(n_keys * sizeof(ExprState *)); CXT1_printf("ExecInitIndexScan: context is %d\n", CurrentMemoryContext); @@ -704,8 +688,8 @@ ExecInitIndexScan(IndexScan *node, EState *estate) for (j = 0; j < n_keys; j++) { OpExpr *clause; /* one clause of index qual */ - Node *leftop; /* expr on lhs of operator */ - Node *rightop; /* expr on rhs ... */ + Expr *leftop; /* expr on lhs of operator */ + Expr *rightop; /* expr on rhs ... */ bits16 flags = 0; int scanvar; /* which var identifies varattno */ @@ -740,9 +724,9 @@ ExecInitIndexScan(IndexScan *node, EState *estate) * which case we need to recalculate the index scan key at run * time. * - * Hence, we set have_runtime_keys to true and then set the - * appropriate flag in run_keys to LEFT_OP or RIGHT_OP. The - * corresponding scan keys are recomputed at run time. + * Hence, we set have_runtime_keys to true and place the + * appropriate subexpression in run_keys. The corresponding + * scan key values are recomputed at run time. * * XXX Although this code *thinks* it can handle an indexqual * with the indexkey on either side, in fact it cannot. @@ -760,19 +744,20 @@ ExecInitIndexScan(IndexScan *node, EState *estate) */ scanvar = NO_OP; - run_keys[j] = NO_OP; + run_keys[j] = NULL; /* * determine information in leftop */ - leftop = (Node *) get_leftop((Expr *) clause); + leftop = (Expr *) get_leftop((Expr *) clause); if (leftop && IsA(leftop, RelabelType)) - leftop = (Node *) ((RelabelType *) leftop)->arg; + leftop = ((RelabelType *) leftop)->arg; Assert(leftop != NULL); - if (IsA(leftop, Var) &&var_is_rel((Var *) leftop)) + if (IsA(leftop, Var) && + var_is_rel((Var *) leftop)) { /* * if the leftop is a "rel-var", then it means that it is @@ -792,32 +777,6 @@ ExecInitIndexScan(IndexScan *node, EState *estate) if (((Const *) leftop)->constisnull) flags |= SK_ISNULL; } - else if (IsA(leftop, Param)) - { - bool isnull; - - /* - * if the leftop is a Param node then it means it - * identifies the value to place in our scan key. - */ - - /* Life was so easy before ... subselects */ - if (((Param *) leftop)->paramkind == PARAM_EXEC) - { - /* treat Param as runtime key */ - have_runtime_keys = true; - run_keys[j] = LEFT_OP; - } - else - { - /* treat Param like a constant */ - scanvalue = ExecEvalParam((Param *) leftop, - indexstate->ss.ps.ps_ExprContext, - &isnull); - if (isnull) - flags |= SK_ISNULL; - } - } else { /* @@ -826,20 +785,21 @@ ExecInitIndexScan(IndexScan *node, EState *estate) * key. */ have_runtime_keys = true; - run_keys[j] = LEFT_OP; + run_keys[j] = ExecInitExpr(leftop, (PlanState *) indexstate); } /* * now determine information in rightop */ - rightop = (Node *) get_rightop((Expr *) clause); + rightop = (Expr *) get_rightop((Expr *) clause); if (rightop && IsA(rightop, RelabelType)) - rightop = (Node *) ((RelabelType *) rightop)->arg; + rightop = ((RelabelType *) rightop)->arg; Assert(rightop != NULL); - if (IsA(rightop, Var) &&var_is_rel((Var *) rightop)) + if (IsA(rightop, Var) && + var_is_rel((Var *) rightop)) { /* * here we make sure only one op identifies the @@ -867,32 +827,6 @@ ExecInitIndexScan(IndexScan *node, EState *estate) if (((Const *) rightop)->constisnull) flags |= SK_ISNULL; } - else if (IsA(rightop, Param)) - { - bool isnull; - - /* - * if the rightop is a Param node then it means it - * identifies the value to place in our scan key. - */ - - /* Life was so easy before ... subselects */ - if (((Param *) rightop)->paramkind == PARAM_EXEC) - { - /* treat Param as runtime key */ - have_runtime_keys = true; - run_keys[j] = RIGHT_OP; - } - else - { - /* treat Param like a constant */ - scanvalue = ExecEvalParam((Param *) rightop, - indexstate->ss.ps.ps_ExprContext, - &isnull); - if (isnull) - flags |= SK_ISNULL; - } - } else { /* @@ -901,7 +835,7 @@ ExecInitIndexScan(IndexScan *node, EState *estate) * key. */ have_runtime_keys = true; - run_keys[j] = RIGHT_OP; + run_keys[j] = ExecInitExpr(rightop, (PlanState *) indexstate); } /* |