aboutsummaryrefslogtreecommitdiff
path: root/src/backend/executor
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2003-02-09 00:30:41 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2003-02-09 00:30:41 +0000
commit145014f81151a12ac6a0f8e299899c4f60e0f8c1 (patch)
tree669a8cecd8e2f67fae0966134b91a28df1e2a6e7 /src/backend/executor
parentc15a4c2aef3ca78a530778b735d43aa04d103ea6 (diff)
downloadpostgresql-145014f81151a12ac6a0f8e299899c4f60e0f8c1.tar.gz
postgresql-145014f81151a12ac6a0f8e299899c4f60e0f8c1.zip
Make further use of new bitmapset code: executor's chgParam, extParam,
locParam lists can be converted to bitmapsets to speed updating. Also, replace 'locParam' with 'allParam', which contains all the paramIDs relevant to the node (i.e., the union of extParam and locParam); this saves a step during SetChangedParamList() without costing anything elsewhere.
Diffstat (limited to 'src/backend/executor')
-rw-r--r--src/backend/executor/execAmi.c26
-rw-r--r--src/backend/executor/execProcnode.c10
-rw-r--r--src/backend/executor/execUtils.c37
-rw-r--r--src/backend/executor/nodeAgg.c4
-rw-r--r--src/backend/executor/nodeAppend.c8
-rw-r--r--src/backend/executor/nodeSubplan.c79
-rw-r--r--src/backend/executor/nodeSubqueryscan.c6
-rw-r--r--src/backend/executor/nodeTidscan.c4
8 files changed, 91 insertions, 83 deletions
diff --git a/src/backend/executor/execAmi.c b/src/backend/executor/execAmi.c
index c55e5ecd149..b22ad763498 100644
--- a/src/backend/executor/execAmi.c
+++ b/src/backend/executor/execAmi.c
@@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Header: /cvsroot/pgsql/src/backend/executor/execAmi.c,v 1.68 2002/12/14 00:17:50 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/executor/execAmi.c,v 1.69 2003/02/09 00:30:39 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -55,7 +55,7 @@ ExecReScan(PlanState *node, ExprContext *exprCtxt)
InstrEndLoop(node->instrument);
/* If we have changed parameters, propagate that info */
- if (node->chgParam != NIL)
+ if (node->chgParam != NULL)
{
List *lst;
@@ -64,10 +64,10 @@ ExecReScan(PlanState *node, ExprContext *exprCtxt)
SubPlanState *sstate = (SubPlanState *) lfirst(lst);
PlanState *splan = sstate->planstate;
- if (splan->plan->extParam != NIL) /* don't care about child
- * locParam */
- SetChangedParamList(splan, node->chgParam);
- if (splan->chgParam != NIL)
+ if (splan->plan->extParam != NULL) /* don't care about child
+ * local Params */
+ UpdateChangedParamSet(splan, node->chgParam);
+ if (splan->chgParam != NULL)
ExecReScanSetParamPlan(sstate, node);
}
foreach(lst, node->subPlan)
@@ -75,14 +75,14 @@ ExecReScan(PlanState *node, ExprContext *exprCtxt)
SubPlanState *sstate = (SubPlanState *) lfirst(lst);
PlanState *splan = sstate->planstate;
- if (splan->plan->extParam != NIL)
- SetChangedParamList(splan, node->chgParam);
+ if (splan->plan->extParam != NULL)
+ UpdateChangedParamSet(splan, node->chgParam);
}
/* Well. Now set chgParam for left/right trees. */
if (node->lefttree != NULL)
- SetChangedParamList(node->lefttree, node->chgParam);
+ UpdateChangedParamSet(node->lefttree, node->chgParam);
if (node->righttree != NULL)
- SetChangedParamList(node->righttree, node->chgParam);
+ UpdateChangedParamSet(node->righttree, node->chgParam);
}
switch (nodeTag(node))
@@ -165,10 +165,10 @@ ExecReScan(PlanState *node, ExprContext *exprCtxt)
return;
}
- if (node->chgParam != NIL)
+ if (node->chgParam != NULL)
{
- freeList(node->chgParam);
- node->chgParam = NIL;
+ bms_free(node->chgParam);
+ node->chgParam = NULL;
}
}
diff --git a/src/backend/executor/execProcnode.c b/src/backend/executor/execProcnode.c
index dc5a3085ead..8d2bc0f8bd9 100644
--- a/src/backend/executor/execProcnode.c
+++ b/src/backend/executor/execProcnode.c
@@ -12,7 +12,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/executor/execProcnode.c,v 1.34 2002/12/14 00:17:50 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/executor/execProcnode.c,v 1.35 2003/02/09 00:30:39 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -282,7 +282,7 @@ ExecProcNode(PlanState *node)
if (node == NULL)
return NULL;
- if (node->chgParam != NIL) /* something changed */
+ if (node->chgParam != NULL) /* something changed */
ExecReScan(node, NULL); /* let ReScan handle this */
if (node->instrument)
@@ -504,10 +504,10 @@ ExecEndNode(PlanState *node)
foreach(subp, node->subPlan)
ExecEndSubPlan((SubPlanState *) lfirst(subp));
- if (node->chgParam != NIL)
+ if (node->chgParam != NULL)
{
- freeList(node->chgParam);
- node->chgParam = NIL;
+ bms_free(node->chgParam);
+ node->chgParam = NULL;
}
switch (nodeTag(node))
diff --git a/src/backend/executor/execUtils.c b/src/backend/executor/execUtils.c
index 90bd8adf1ae..b2fe0a2276a 100644
--- a/src/backend/executor/execUtils.c
+++ b/src/backend/executor/execUtils.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/executor/execUtils.c,v 1.96 2003/01/23 05:10:39 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/executor/execUtils.c,v 1.97 2003/02/09 00:30:39 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -874,25 +874,28 @@ ExecInsertIndexTuples(TupleTableSlot *slot,
}
}
+/*
+ * UpdateChangedParamSet
+ * Add changed parameters to a plan node's chgParam set
+ */
void
-SetChangedParamList(PlanState *node, List *newchg)
+UpdateChangedParamSet(PlanState *node, Bitmapset *newchg)
{
- List *nl;
-
- foreach(nl, newchg)
- {
- int paramId = lfirsti(nl);
+ Bitmapset *parmset;
- /* if this node doesn't depend on a param ... */
- if (!intMember(paramId, node->plan->extParam) &&
- !intMember(paramId, node->plan->locParam))
- continue;
- /* if this param is already in list of changed ones ... */
- if (intMember(paramId, node->chgParam))
- continue;
- /* else - add this param to the list */
- node->chgParam = lappendi(node->chgParam, paramId);
- }
+ /*
+ * The plan node only depends on params listed in its allParam set.
+ * Don't include anything else into its chgParam set.
+ */
+ parmset = bms_intersect(node->plan->allParam, newchg);
+ /*
+ * Keep node->chgParam == NULL if there's not actually any members;
+ * this allows the simplest possible tests in executor node files.
+ */
+ if (!bms_is_empty(parmset))
+ node->chgParam = bms_join(node->chgParam, parmset);
+ else
+ bms_free(parmset);
}
/*
diff --git a/src/backend/executor/nodeAgg.c b/src/backend/executor/nodeAgg.c
index 0cb2f3e2b6f..bbdda3540a7 100644
--- a/src/backend/executor/nodeAgg.c
+++ b/src/backend/executor/nodeAgg.c
@@ -45,7 +45,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/executor/nodeAgg.c,v 1.103 2003/02/04 00:48:23 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/executor/nodeAgg.c,v 1.104 2003/02/09 00:30:39 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -1405,7 +1405,7 @@ ExecReScanAgg(AggState *node, ExprContext *exprCtxt)
* if chgParam of subnode is not null then plan will be re-scanned by
* first ExecProcNode.
*/
- if (((PlanState *) node)->lefttree->chgParam == NIL)
+ if (((PlanState *) node)->lefttree->chgParam == NULL)
ExecReScan(((PlanState *) node)->lefttree, exprCtxt);
}
diff --git a/src/backend/executor/nodeAppend.c b/src/backend/executor/nodeAppend.c
index bcb50fb7979..e79d37fd857 100644
--- a/src/backend/executor/nodeAppend.c
+++ b/src/backend/executor/nodeAppend.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/executor/nodeAppend.c,v 1.51 2002/12/05 15:50:33 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/executor/nodeAppend.c,v 1.52 2003/02/09 00:30:39 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -361,14 +361,14 @@ ExecReScanAppend(AppendState *node, ExprContext *exprCtxt)
* ExecReScan doesn't know about my subplans, so I have to do
* changed-parameter signaling myself.
*/
- if (node->ps.chgParam != NIL)
- SetChangedParamList(subnode, node->ps.chgParam);
+ if (node->ps.chgParam != NULL)
+ UpdateChangedParamSet(subnode, node->ps.chgParam);
/*
* if chgParam of subnode is not null then plan will be re-scanned
* by first ExecProcNode.
*/
- if (subnode->chgParam == NIL)
+ if (subnode->chgParam == NULL)
{
/* make sure estate is correct for this subnode (needed??) */
node->as_whichplan = i;
diff --git a/src/backend/executor/nodeSubplan.c b/src/backend/executor/nodeSubplan.c
index d3f32913914..4fd8af2ae4d 100644
--- a/src/backend/executor/nodeSubplan.c
+++ b/src/backend/executor/nodeSubplan.c
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/executor/nodeSubplan.c,v 1.43 2003/01/12 04:03:34 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/executor/nodeSubplan.c,v 1.44 2003/02/09 00:30:39 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -80,7 +80,7 @@ ExecHashSubPlan(SubPlanState *node,
* If first time through or we need to rescan the subplan, build
* the hash table.
*/
- if (node->hashtable == NULL || planstate->chgParam != NIL)
+ if (node->hashtable == NULL || planstate->chgParam != NULL)
buildSubPlanHash(node);
/*
@@ -218,22 +218,18 @@ ExecScanSubPlan(SubPlanState *node,
* Set Params of this plan from parent plan correlation Vars
*/
pvar = node->args;
- if (subplan->parParam != NIL)
+ foreach(lst, subplan->parParam)
{
- foreach(lst, subplan->parParam)
- {
- ParamExecData *prm;
-
- prm = &(econtext->ecxt_param_exec_vals[lfirsti(lst)]);
- Assert(pvar != NIL);
- prm->value = ExecEvalExprSwitchContext((ExprState *) lfirst(pvar),
- econtext,
- &(prm->isnull),
- NULL);
- pvar = lnext(pvar);
- }
- planstate->chgParam = nconc(planstate->chgParam,
- listCopy(subplan->parParam));
+ int paramid = lfirsti(lst);
+ ParamExecData *prm = &(econtext->ecxt_param_exec_vals[paramid]);
+
+ Assert(pvar != NIL);
+ prm->value = ExecEvalExprSwitchContext((ExprState *) lfirst(pvar),
+ econtext,
+ &(prm->isnull),
+ NULL);
+ pvar = lnext(pvar);
+ planstate->chgParam = bms_add_member(planstate->chgParam, paramid);
}
Assert(pvar == NIL);
@@ -686,7 +682,12 @@ ExecInitSubPlan(SubPlanState *node, EState *estate)
/*
* If this plan is un-correlated or undirect correlated one and want
- * to set params for parent plan then prepare parameters.
+ * to set params for parent plan then mark parameters as needing
+ * evaluation.
+ *
+ * Note that in the case of un-correlated subqueries we don't care
+ * about setting parent->chgParam here: indices take care about
+ * it, for others - it doesn't matter...
*/
if (subplan->setParam != NIL)
{
@@ -694,16 +695,11 @@ ExecInitSubPlan(SubPlanState *node, EState *estate)
foreach(lst, subplan->setParam)
{
- ParamExecData *prm = &(estate->es_param_exec_vals[lfirsti(lst)]);
+ int paramid = lfirsti(lst);
+ ParamExecData *prm = &(estate->es_param_exec_vals[paramid]);
prm->execPlan = node;
}
-
- /*
- * Note that in the case of un-correlated subqueries we don't care
- * about setting parent->chgParam here: indices take care about
- * it, for others - it doesn't matter...
- */
}
/*
@@ -884,7 +880,9 @@ ExecSetParamPlan(SubPlanState *node, ExprContext *econtext)
if (subLinkType == EXISTS_SUBLINK)
{
- ParamExecData *prm = &(econtext->ecxt_param_exec_vals[lfirsti(subplan->setParam)]);
+ /* There can be only one param... */
+ int paramid = lfirsti(subplan->setParam);
+ ParamExecData *prm = &(econtext->ecxt_param_exec_vals[paramid]);
prm->execPlan = NULL;
prm->value = BoolGetDatum(true);
@@ -914,9 +912,13 @@ ExecSetParamPlan(SubPlanState *node, ExprContext *econtext)
node->curTuple = tup;
MemoryContextSwitchTo(node->sub_estate->es_query_cxt);
+ /*
+ * Now set all the setParam params from the columns of the tuple
+ */
foreach(lst, subplan->setParam)
{
- ParamExecData *prm = &(econtext->ecxt_param_exec_vals[lfirsti(lst)]);
+ int paramid = lfirsti(lst);
+ ParamExecData *prm = &(econtext->ecxt_param_exec_vals[paramid]);
prm->execPlan = NULL;
prm->value = heap_getattr(tup, i, tdesc, &(prm->isnull));
@@ -928,7 +930,9 @@ ExecSetParamPlan(SubPlanState *node, ExprContext *econtext)
{
if (subLinkType == EXISTS_SUBLINK)
{
- ParamExecData *prm = &(econtext->ecxt_param_exec_vals[lfirsti(subplan->setParam)]);
+ /* There can be only one param... */
+ int paramid = lfirsti(subplan->setParam);
+ ParamExecData *prm = &(econtext->ecxt_param_exec_vals[paramid]);
prm->execPlan = NULL;
prm->value = BoolGetDatum(false);
@@ -938,7 +942,8 @@ ExecSetParamPlan(SubPlanState *node, ExprContext *econtext)
{
foreach(lst, subplan->setParam)
{
- ParamExecData *prm = &(econtext->ecxt_param_exec_vals[lfirsti(lst)]);
+ int paramid = lfirsti(lst);
+ ParamExecData *prm = &(econtext->ecxt_param_exec_vals[paramid]);
prm->execPlan = NULL;
prm->value = (Datum) 0;
@@ -979,12 +984,12 @@ ExecReScanSetParamPlan(SubPlanState *node, PlanState *parent)
EState *estate = parent->state;
List *lst;
- if (subplan->parParam != NULL)
+ if (subplan->parParam != NIL)
elog(ERROR, "ExecReScanSetParamPlan: direct correlated subquery unsupported, yet");
- if (subplan->setParam == NULL)
- elog(ERROR, "ExecReScanSetParamPlan: setParam list is NULL");
- if (planstate->plan->extParam == NULL)
- elog(ERROR, "ExecReScanSetParamPlan: extParam list of plan is NULL");
+ if (subplan->setParam == NIL)
+ elog(ERROR, "ExecReScanSetParamPlan: setParam list is empty");
+ if (bms_is_empty(planstate->plan->extParam))
+ elog(ERROR, "ExecReScanSetParamPlan: extParam set of plan is empty");
/*
* Don't actually re-scan: ExecSetParamPlan does it if needed.
@@ -995,10 +1000,10 @@ ExecReScanSetParamPlan(SubPlanState *node, PlanState *parent)
*/
foreach(lst, subplan->setParam)
{
- ParamExecData *prm = &(estate->es_param_exec_vals[lfirsti(lst)]);
+ int paramid = lfirsti(lst);
+ ParamExecData *prm = &(estate->es_param_exec_vals[paramid]);
prm->execPlan = node;
+ parent->chgParam = bms_add_member(parent->chgParam, paramid);
}
-
- parent->chgParam = nconc(parent->chgParam, listCopy(subplan->setParam));
}
diff --git a/src/backend/executor/nodeSubqueryscan.c b/src/backend/executor/nodeSubqueryscan.c
index c5ad1e9cd5f..ba4804fcebb 100644
--- a/src/backend/executor/nodeSubqueryscan.c
+++ b/src/backend/executor/nodeSubqueryscan.c
@@ -12,7 +12,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/executor/nodeSubqueryscan.c,v 1.17 2003/01/12 22:01:38 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/executor/nodeSubqueryscan.c,v 1.18 2003/02/09 00:30:39 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -261,10 +261,10 @@ ExecSubqueryReScan(SubqueryScanState *node, ExprContext *exprCtxt)
* ExecReScan doesn't know about my subplan, so I have to do
* changed-parameter signaling myself. This is just as well,
* because the subplan has its own memory context in which its
- * chgParam lists live.
+ * chgParam state lives.
*/
if (node->ss.ps.chgParam != NULL)
- SetChangedParamList(node->subplan, node->ss.ps.chgParam);
+ UpdateChangedParamSet(node->subplan, node->ss.ps.chgParam);
/*
* if chgParam of subnode is not null then plan will be re-scanned by
diff --git a/src/backend/executor/nodeTidscan.c b/src/backend/executor/nodeTidscan.c
index e1a2165709e..962d00cd144 100644
--- a/src/backend/executor/nodeTidscan.c
+++ b/src/backend/executor/nodeTidscan.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/executor/nodeTidscan.c,v 1.32 2003/02/03 15:07:07 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/executor/nodeTidscan.c,v 1.33 2003/02/09 00:30:39 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -349,7 +349,7 @@ ExecInitTidScan(TidScan *node, EState *estate)
Oid relid;
Oid reloid;
Relation currentRelation;
- List *execParam = NIL;
+ Bitmapset *execParam = NULL;
/*
* create state structure