aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/backend/executor/execMain.c20
-rw-r--r--src/backend/executor/execParallel.c2
-rw-r--r--src/backend/nodes/copyfuncs.c2
-rw-r--r--src/backend/nodes/outfuncs.c4
-rw-r--r--src/backend/nodes/readfuncs.c2
-rw-r--r--src/backend/optimizer/plan/planner.c6
-rw-r--r--src/backend/optimizer/plan/subselect.c35
-rw-r--r--src/backend/optimizer/util/clauses.c2
-rw-r--r--src/include/nodes/plannodes.h2
-rw-r--r--src/include/nodes/relation.h6
10 files changed, 53 insertions, 28 deletions
diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c
index 493ff82775f..47f21316429 100644
--- a/src/backend/executor/execMain.c
+++ b/src/backend/executor/execMain.c
@@ -195,9 +195,14 @@ standard_ExecutorStart(QueryDesc *queryDesc, int eflags)
*/
estate->es_param_list_info = queryDesc->params;
- if (queryDesc->plannedstmt->nParamExec > 0)
+ if (queryDesc->plannedstmt->paramExecTypes != NIL)
+ {
+ int nParamExec;
+
+ nParamExec = list_length(queryDesc->plannedstmt->paramExecTypes);
estate->es_param_exec_vals = (ParamExecData *)
- palloc0(queryDesc->plannedstmt->nParamExec * sizeof(ParamExecData));
+ palloc0(nParamExec * sizeof(ParamExecData));
+ }
estate->es_sourceText = queryDesc->sourceText;
@@ -3032,9 +3037,11 @@ EvalPlanQualBegin(EPQState *epqstate, EState *parentestate)
MemSet(estate->es_epqScanDone, 0, rtsize * sizeof(bool));
/* Recopy current values of parent parameters */
- if (parentestate->es_plannedstmt->nParamExec > 0)
+ if (parentestate->es_plannedstmt->paramExecTypes != NIL)
{
- int i = parentestate->es_plannedstmt->nParamExec;
+ int i;
+
+ i = list_length(parentestate->es_plannedstmt->paramExecTypes);
while (--i >= 0)
{
@@ -3122,10 +3129,11 @@ EvalPlanQualStart(EPQState *epqstate, EState *parentestate, Plan *planTree)
* already set from other parts of the parent's plan tree.
*/
estate->es_param_list_info = parentestate->es_param_list_info;
- if (parentestate->es_plannedstmt->nParamExec > 0)
+ if (parentestate->es_plannedstmt->paramExecTypes != NIL)
{
- int i = parentestate->es_plannedstmt->nParamExec;
+ int i;
+ i = list_length(parentestate->es_plannedstmt->paramExecTypes);
estate->es_param_exec_vals = (ParamExecData *)
palloc0(i * sizeof(ParamExecData));
while (--i >= 0)
diff --git a/src/backend/executor/execParallel.c b/src/backend/executor/execParallel.c
index 1b477baecb8..fd7e7cbf3d3 100644
--- a/src/backend/executor/execParallel.c
+++ b/src/backend/executor/execParallel.c
@@ -195,7 +195,7 @@ ExecSerializePlan(Plan *plan, EState *estate)
pstmt->rowMarks = NIL;
pstmt->relationOids = NIL;
pstmt->invalItems = NIL; /* workers can't replan anyway... */
- pstmt->nParamExec = estate->es_plannedstmt->nParamExec;
+ pstmt->paramExecTypes = estate->es_plannedstmt->paramExecTypes;
pstmt->utilityStmt = NULL;
pstmt->stmt_location = -1;
pstmt->stmt_len = -1;
diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c
index cadd253ef17..76e75459b46 100644
--- a/src/backend/nodes/copyfuncs.c
+++ b/src/backend/nodes/copyfuncs.c
@@ -97,7 +97,7 @@ _copyPlannedStmt(const PlannedStmt *from)
COPY_NODE_FIELD(rowMarks);
COPY_NODE_FIELD(relationOids);
COPY_NODE_FIELD(invalItems);
- COPY_SCALAR_FIELD(nParamExec);
+ COPY_NODE_FIELD(paramExecTypes);
COPY_NODE_FIELD(utilityStmt);
COPY_LOCATION_FIELD(stmt_location);
COPY_LOCATION_FIELD(stmt_len);
diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c
index 291d1eeb46f..dc35df9e4fe 100644
--- a/src/backend/nodes/outfuncs.c
+++ b/src/backend/nodes/outfuncs.c
@@ -282,7 +282,7 @@ _outPlannedStmt(StringInfo str, const PlannedStmt *node)
WRITE_NODE_FIELD(rowMarks);
WRITE_NODE_FIELD(relationOids);
WRITE_NODE_FIELD(invalItems);
- WRITE_INT_FIELD(nParamExec);
+ WRITE_NODE_FIELD(paramExecTypes);
WRITE_NODE_FIELD(utilityStmt);
WRITE_LOCATION_FIELD(stmt_location);
WRITE_LOCATION_FIELD(stmt_len);
@@ -2181,7 +2181,7 @@ _outPlannerGlobal(StringInfo str, const PlannerGlobal *node)
WRITE_NODE_FIELD(rootResultRelations);
WRITE_NODE_FIELD(relationOids);
WRITE_NODE_FIELD(invalItems);
- WRITE_INT_FIELD(nParamExec);
+ WRITE_NODE_FIELD(paramExecTypes);
WRITE_UINT_FIELD(lastPHId);
WRITE_UINT_FIELD(lastRowMarkId);
WRITE_INT_FIELD(lastPlanNodeId);
diff --git a/src/backend/nodes/readfuncs.c b/src/backend/nodes/readfuncs.c
index 42c595dc039..593658dd8a8 100644
--- a/src/backend/nodes/readfuncs.c
+++ b/src/backend/nodes/readfuncs.c
@@ -1480,7 +1480,7 @@ _readPlannedStmt(void)
READ_NODE_FIELD(rowMarks);
READ_NODE_FIELD(relationOids);
READ_NODE_FIELD(invalItems);
- READ_INT_FIELD(nParamExec);
+ READ_NODE_FIELD(paramExecTypes);
READ_NODE_FIELD(utilityStmt);
READ_LOCATION_FIELD(stmt_location);
READ_LOCATION_FIELD(stmt_len);
diff --git a/src/backend/optimizer/plan/planner.c b/src/backend/optimizer/plan/planner.c
index 9b7a8fd82c4..607f7cd2518 100644
--- a/src/backend/optimizer/plan/planner.c
+++ b/src/backend/optimizer/plan/planner.c
@@ -243,7 +243,7 @@ standard_planner(Query *parse, int cursorOptions, ParamListInfo boundParams)
glob->rootResultRelations = NIL;
glob->relationOids = NIL;
glob->invalItems = NIL;
- glob->nParamExec = 0;
+ glob->paramExecTypes = NIL;
glob->lastPHId = 0;
glob->lastRowMarkId = 0;
glob->lastPlanNodeId = 0;
@@ -415,7 +415,7 @@ standard_planner(Query *parse, int cursorOptions, ParamListInfo boundParams)
* set_plan_references' tree traversal, but for now it has to be separate
* because we need to visit subplans before not after main plan.
*/
- if (glob->nParamExec > 0)
+ if (glob->paramExecTypes != NIL)
{
Assert(list_length(glob->subplans) == list_length(glob->subroots));
forboth(lp, glob->subplans, lr, glob->subroots)
@@ -466,7 +466,7 @@ standard_planner(Query *parse, int cursorOptions, ParamListInfo boundParams)
result->rowMarks = glob->finalrowmarks;
result->relationOids = glob->relationOids;
result->invalItems = glob->invalItems;
- result->nParamExec = glob->nParamExec;
+ result->paramExecTypes = glob->paramExecTypes;
/* utilityStmt should be null, but we might as well copy it */
result->utilityStmt = parse->utilityStmt;
result->stmt_location = parse->stmt_location;
diff --git a/src/backend/optimizer/plan/subselect.c b/src/backend/optimizer/plan/subselect.c
index 8f75fa98edc..2e3abeea3d0 100644
--- a/src/backend/optimizer/plan/subselect.c
+++ b/src/backend/optimizer/plan/subselect.c
@@ -131,7 +131,9 @@ assign_param_for_var(PlannerInfo *root, Var *var)
pitem = makeNode(PlannerParamItem);
pitem->item = (Node *) var;
- pitem->paramId = root->glob->nParamExec++;
+ pitem->paramId = list_length(root->glob->paramExecTypes);
+ root->glob->paramExecTypes = lappend_oid(root->glob->paramExecTypes,
+ var->vartype);
root->plan_params = lappend(root->plan_params, pitem);
@@ -234,7 +236,9 @@ assign_param_for_placeholdervar(PlannerInfo *root, PlaceHolderVar *phv)
pitem = makeNode(PlannerParamItem);
pitem->item = (Node *) phv;
- pitem->paramId = root->glob->nParamExec++;
+ pitem->paramId = list_length(root->glob->paramExecTypes);
+ root->glob->paramExecTypes = lappend_oid(root->glob->paramExecTypes,
+ exprType((Node *) phv->phexpr));
root->plan_params = lappend(root->plan_params, pitem);
@@ -323,7 +327,9 @@ replace_outer_agg(PlannerInfo *root, Aggref *agg)
pitem = makeNode(PlannerParamItem);
pitem->item = (Node *) agg;
- pitem->paramId = root->glob->nParamExec++;
+ pitem->paramId = list_length(root->glob->paramExecTypes);
+ root->glob->paramExecTypes = lappend_oid(root->glob->paramExecTypes,
+ agg->aggtype);
root->plan_params = lappend(root->plan_params, pitem);
@@ -348,6 +354,7 @@ replace_outer_grouping(PlannerInfo *root, GroupingFunc *grp)
Param *retval;
PlannerParamItem *pitem;
Index levelsup;
+ Oid ptype;
Assert(grp->agglevelsup > 0 && grp->agglevelsup < root->query_level);
@@ -362,17 +369,20 @@ replace_outer_grouping(PlannerInfo *root, GroupingFunc *grp)
grp = copyObject(grp);
IncrementVarSublevelsUp((Node *) grp, -((int) grp->agglevelsup), 0);
Assert(grp->agglevelsup == 0);
+ ptype = exprType((Node *) grp);
pitem = makeNode(PlannerParamItem);
pitem->item = (Node *) grp;
- pitem->paramId = root->glob->nParamExec++;
+ pitem->paramId = list_length(root->glob->paramExecTypes);
+ root->glob->paramExecTypes = lappend_oid(root->glob->paramExecTypes,
+ ptype);
root->plan_params = lappend(root->plan_params, pitem);
retval = makeNode(Param);
retval->paramkind = PARAM_EXEC;
retval->paramid = pitem->paramId;
- retval->paramtype = exprType((Node *) grp);
+ retval->paramtype = ptype;
retval->paramtypmod = -1;
retval->paramcollid = InvalidOid;
retval->location = grp->location;
@@ -385,7 +395,8 @@ replace_outer_grouping(PlannerInfo *root, GroupingFunc *grp)
*
* This is used to create Params representing subplan outputs.
* We don't need to build a PlannerParamItem for such a Param, but we do
- * need to record the PARAM_EXEC slot number as being allocated.
+ * need to make sure we record the type in paramExecTypes (otherwise,
+ * there won't be a slot allocated for it).
*/
static Param *
generate_new_param(PlannerInfo *root, Oid paramtype, int32 paramtypmod,
@@ -395,7 +406,9 @@ generate_new_param(PlannerInfo *root, Oid paramtype, int32 paramtypmod,
retval = makeNode(Param);
retval->paramkind = PARAM_EXEC;
- retval->paramid = root->glob->nParamExec++;
+ retval->paramid = list_length(root->glob->paramExecTypes);
+ root->glob->paramExecTypes = lappend_oid(root->glob->paramExecTypes,
+ paramtype);
retval->paramtype = paramtype;
retval->paramtypmod = paramtypmod;
retval->paramcollid = paramcollation;
@@ -415,7 +428,11 @@ generate_new_param(PlannerInfo *root, Oid paramtype, int32 paramtypmod,
int
SS_assign_special_param(PlannerInfo *root)
{
- return root->glob->nParamExec++;
+ int paramId = list_length(root->glob->paramExecTypes);
+
+ root->glob->paramExecTypes = lappend_oid(root->glob->paramExecTypes,
+ InvalidOid);
+ return paramId;
}
/*
@@ -2098,7 +2115,7 @@ SS_identify_outer_params(PlannerInfo *root)
* If no parameters have been assigned anywhere in the tree, we certainly
* don't need to do anything here.
*/
- if (root->glob->nParamExec == 0)
+ if (root->glob->paramExecTypes == NIL)
return;
/*
diff --git a/src/backend/optimizer/util/clauses.c b/src/backend/optimizer/util/clauses.c
index 30cdd3da4c5..66e098f488a 100644
--- a/src/backend/optimizer/util/clauses.c
+++ b/src/backend/optimizer/util/clauses.c
@@ -1095,7 +1095,7 @@ is_parallel_safe(PlannerInfo *root, Node *node)
* in this expression. But otherwise we don't need to look.
*/
if (root->glob->maxParallelHazard == PROPARALLEL_SAFE &&
- root->glob->nParamExec == 0)
+ root->glob->paramExecTypes == NIL)
return true;
/* Else use max_parallel_hazard's search logic, but stop on RESTRICTED */
context.max_hazard = PROPARALLEL_SAFE;
diff --git a/src/include/nodes/plannodes.h b/src/include/nodes/plannodes.h
index dd74efa9a41..a127682b0e7 100644
--- a/src/include/nodes/plannodes.h
+++ b/src/include/nodes/plannodes.h
@@ -89,7 +89,7 @@ typedef struct PlannedStmt
List *invalItems; /* other dependencies, as PlanInvalItems */
- int nParamExec; /* number of PARAM_EXEC Params used */
+ List *paramExecTypes; /* type OIDs for PARAM_EXEC Params */
Node *utilityStmt; /* non-null if this is utility stmt */
diff --git a/src/include/nodes/relation.h b/src/include/nodes/relation.h
index 05fc9a3f485..9e68e65cc63 100644
--- a/src/include/nodes/relation.h
+++ b/src/include/nodes/relation.h
@@ -114,7 +114,7 @@ typedef struct PlannerGlobal
List *invalItems; /* other dependencies, as PlanInvalItems */
- int nParamExec; /* number of PARAM_EXEC Params used */
+ List *paramExecTypes; /* type OIDs for PARAM_EXEC Params */
Index lastPHId; /* highest PlaceHolderVar ID assigned */
@@ -2219,8 +2219,8 @@ typedef struct MinMaxAggInfo
* from subplans (values that are setParam items for those subplans). These
* IDs need not be tracked via PlannerParamItems, since we do not need any
* duplicate-elimination nor later processing of the represented expressions.
- * Instead, we just record the assignment of the slot number by incrementing
- * root->glob->nParamExec.
+ * Instead, we just record the assignment of the slot number by appending to
+ * root->glob->paramExecTypes.
*/
typedef struct PlannerParamItem
{