Skip to content

Commit e64861c

Browse files
committed
Track in the plan the types associated with PARAM_EXEC parameters.
Up until now, we only tracked the number of parameters, which was sufficient to allocate an array of Datums of the appropriate size, but not sufficient to, for example, know how to serialize a Datum stored in one of those slots. An upcoming patch wants to do that, so add this tracking to make it possible. Patch by me, reviewed by Tom Lane and Amit Kapila. Discussion: http://postgr.es/m/CA+TgmoYqpxDKn8koHdW8BEKk8FMUL0=e8m2Qe=M+r0UBjr3tuQ@mail.gmail.com
1 parent ce4c86a commit e64861c

File tree

10 files changed

+53
-28
lines changed

10 files changed

+53
-28
lines changed

src/backend/executor/execMain.c

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -195,9 +195,14 @@ standard_ExecutorStart(QueryDesc *queryDesc, int eflags)
195195
*/
196196
estate->es_param_list_info = queryDesc->params;
197197

198-
if (queryDesc->plannedstmt->nParamExec > 0)
198+
if (queryDesc->plannedstmt->paramExecTypes != NIL)
199+
{
200+
int nParamExec;
201+
202+
nParamExec = list_length(queryDesc->plannedstmt->paramExecTypes);
199203
estate->es_param_exec_vals = (ParamExecData *)
200-
palloc0(queryDesc->plannedstmt->nParamExec * sizeof(ParamExecData));
204+
palloc0(nParamExec * sizeof(ParamExecData));
205+
}
201206

202207
estate->es_sourceText = queryDesc->sourceText;
203208

@@ -3032,9 +3037,11 @@ EvalPlanQualBegin(EPQState *epqstate, EState *parentestate)
30323037
MemSet(estate->es_epqScanDone, 0, rtsize * sizeof(bool));
30333038

30343039
/* Recopy current values of parent parameters */
3035-
if (parentestate->es_plannedstmt->nParamExec > 0)
3040+
if (parentestate->es_plannedstmt->paramExecTypes != NIL)
30363041
{
3037-
int i = parentestate->es_plannedstmt->nParamExec;
3042+
int i;
3043+
3044+
i = list_length(parentestate->es_plannedstmt->paramExecTypes);
30383045

30393046
while (--i >= 0)
30403047
{
@@ -3122,10 +3129,11 @@ EvalPlanQualStart(EPQState *epqstate, EState *parentestate, Plan *planTree)
31223129
* already set from other parts of the parent's plan tree.
31233130
*/
31243131
estate->es_param_list_info = parentestate->es_param_list_info;
3125-
if (parentestate->es_plannedstmt->nParamExec > 0)
3132+
if (parentestate->es_plannedstmt->paramExecTypes != NIL)
31263133
{
3127-
int i = parentestate->es_plannedstmt->nParamExec;
3134+
int i;
31283135

3136+
i = list_length(parentestate->es_plannedstmt->paramExecTypes);
31293137
estate->es_param_exec_vals = (ParamExecData *)
31303138
palloc0(i * sizeof(ParamExecData));
31313139
while (--i >= 0)

src/backend/executor/execParallel.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@ ExecSerializePlan(Plan *plan, EState *estate)
195195
pstmt->rowMarks = NIL;
196196
pstmt->relationOids = NIL;
197197
pstmt->invalItems = NIL; /* workers can't replan anyway... */
198-
pstmt->nParamExec = estate->es_plannedstmt->nParamExec;
198+
pstmt->paramExecTypes = estate->es_plannedstmt->paramExecTypes;
199199
pstmt->utilityStmt = NULL;
200200
pstmt->stmt_location = -1;
201201
pstmt->stmt_len = -1;

src/backend/nodes/copyfuncs.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ _copyPlannedStmt(const PlannedStmt *from)
9797
COPY_NODE_FIELD(rowMarks);
9898
COPY_NODE_FIELD(relationOids);
9999
COPY_NODE_FIELD(invalItems);
100-
COPY_SCALAR_FIELD(nParamExec);
100+
COPY_NODE_FIELD(paramExecTypes);
101101
COPY_NODE_FIELD(utilityStmt);
102102
COPY_LOCATION_FIELD(stmt_location);
103103
COPY_LOCATION_FIELD(stmt_len);

src/backend/nodes/outfuncs.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,7 @@ _outPlannedStmt(StringInfo str, const PlannedStmt *node)
282282
WRITE_NODE_FIELD(rowMarks);
283283
WRITE_NODE_FIELD(relationOids);
284284
WRITE_NODE_FIELD(invalItems);
285-
WRITE_INT_FIELD(nParamExec);
285+
WRITE_NODE_FIELD(paramExecTypes);
286286
WRITE_NODE_FIELD(utilityStmt);
287287
WRITE_LOCATION_FIELD(stmt_location);
288288
WRITE_LOCATION_FIELD(stmt_len);
@@ -2181,7 +2181,7 @@ _outPlannerGlobal(StringInfo str, const PlannerGlobal *node)
21812181
WRITE_NODE_FIELD(rootResultRelations);
21822182
WRITE_NODE_FIELD(relationOids);
21832183
WRITE_NODE_FIELD(invalItems);
2184-
WRITE_INT_FIELD(nParamExec);
2184+
WRITE_NODE_FIELD(paramExecTypes);
21852185
WRITE_UINT_FIELD(lastPHId);
21862186
WRITE_UINT_FIELD(lastRowMarkId);
21872187
WRITE_INT_FIELD(lastPlanNodeId);

src/backend/nodes/readfuncs.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1480,7 +1480,7 @@ _readPlannedStmt(void)
14801480
READ_NODE_FIELD(rowMarks);
14811481
READ_NODE_FIELD(relationOids);
14821482
READ_NODE_FIELD(invalItems);
1483-
READ_INT_FIELD(nParamExec);
1483+
READ_NODE_FIELD(paramExecTypes);
14841484
READ_NODE_FIELD(utilityStmt);
14851485
READ_LOCATION_FIELD(stmt_location);
14861486
READ_LOCATION_FIELD(stmt_len);

src/backend/optimizer/plan/planner.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,7 @@ standard_planner(Query *parse, int cursorOptions, ParamListInfo boundParams)
243243
glob->rootResultRelations = NIL;
244244
glob->relationOids = NIL;
245245
glob->invalItems = NIL;
246-
glob->nParamExec = 0;
246+
glob->paramExecTypes = NIL;
247247
glob->lastPHId = 0;
248248
glob->lastRowMarkId = 0;
249249
glob->lastPlanNodeId = 0;
@@ -415,7 +415,7 @@ standard_planner(Query *parse, int cursorOptions, ParamListInfo boundParams)
415415
* set_plan_references' tree traversal, but for now it has to be separate
416416
* because we need to visit subplans before not after main plan.
417417
*/
418-
if (glob->nParamExec > 0)
418+
if (glob->paramExecTypes != NIL)
419419
{
420420
Assert(list_length(glob->subplans) == list_length(glob->subroots));
421421
forboth(lp, glob->subplans, lr, glob->subroots)
@@ -466,7 +466,7 @@ standard_planner(Query *parse, int cursorOptions, ParamListInfo boundParams)
466466
result->rowMarks = glob->finalrowmarks;
467467
result->relationOids = glob->relationOids;
468468
result->invalItems = glob->invalItems;
469-
result->nParamExec = glob->nParamExec;
469+
result->paramExecTypes = glob->paramExecTypes;
470470
/* utilityStmt should be null, but we might as well copy it */
471471
result->utilityStmt = parse->utilityStmt;
472472
result->stmt_location = parse->stmt_location;

src/backend/optimizer/plan/subselect.c

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,9 @@ assign_param_for_var(PlannerInfo *root, Var *var)
131131

132132
pitem = makeNode(PlannerParamItem);
133133
pitem->item = (Node *) var;
134-
pitem->paramId = root->glob->nParamExec++;
134+
pitem->paramId = list_length(root->glob->paramExecTypes);
135+
root->glob->paramExecTypes = lappend_oid(root->glob->paramExecTypes,
136+
var->vartype);
135137

136138
root->plan_params = lappend(root->plan_params, pitem);
137139

@@ -234,7 +236,9 @@ assign_param_for_placeholdervar(PlannerInfo *root, PlaceHolderVar *phv)
234236

235237
pitem = makeNode(PlannerParamItem);
236238
pitem->item = (Node *) phv;
237-
pitem->paramId = root->glob->nParamExec++;
239+
pitem->paramId = list_length(root->glob->paramExecTypes);
240+
root->glob->paramExecTypes = lappend_oid(root->glob->paramExecTypes,
241+
exprType((Node *) phv->phexpr));
238242

239243
root->plan_params = lappend(root->plan_params, pitem);
240244

@@ -323,7 +327,9 @@ replace_outer_agg(PlannerInfo *root, Aggref *agg)
323327

324328
pitem = makeNode(PlannerParamItem);
325329
pitem->item = (Node *) agg;
326-
pitem->paramId = root->glob->nParamExec++;
330+
pitem->paramId = list_length(root->glob->paramExecTypes);
331+
root->glob->paramExecTypes = lappend_oid(root->glob->paramExecTypes,
332+
agg->aggtype);
327333

328334
root->plan_params = lappend(root->plan_params, pitem);
329335

@@ -348,6 +354,7 @@ replace_outer_grouping(PlannerInfo *root, GroupingFunc *grp)
348354
Param *retval;
349355
PlannerParamItem *pitem;
350356
Index levelsup;
357+
Oid ptype;
351358

352359
Assert(grp->agglevelsup > 0 && grp->agglevelsup < root->query_level);
353360

@@ -362,17 +369,20 @@ replace_outer_grouping(PlannerInfo *root, GroupingFunc *grp)
362369
grp = copyObject(grp);
363370
IncrementVarSublevelsUp((Node *) grp, -((int) grp->agglevelsup), 0);
364371
Assert(grp->agglevelsup == 0);
372+
ptype = exprType((Node *) grp);
365373

366374
pitem = makeNode(PlannerParamItem);
367375
pitem->item = (Node *) grp;
368-
pitem->paramId = root->glob->nParamExec++;
376+
pitem->paramId = list_length(root->glob->paramExecTypes);
377+
root->glob->paramExecTypes = lappend_oid(root->glob->paramExecTypes,
378+
ptype);
369379

370380
root->plan_params = lappend(root->plan_params, pitem);
371381

372382
retval = makeNode(Param);
373383
retval->paramkind = PARAM_EXEC;
374384
retval->paramid = pitem->paramId;
375-
retval->paramtype = exprType((Node *) grp);
385+
retval->paramtype = ptype;
376386
retval->paramtypmod = -1;
377387
retval->paramcollid = InvalidOid;
378388
retval->location = grp->location;
@@ -385,7 +395,8 @@ replace_outer_grouping(PlannerInfo *root, GroupingFunc *grp)
385395
*
386396
* This is used to create Params representing subplan outputs.
387397
* We don't need to build a PlannerParamItem for such a Param, but we do
388-
* need to record the PARAM_EXEC slot number as being allocated.
398+
* need to make sure we record the type in paramExecTypes (otherwise,
399+
* there won't be a slot allocated for it).
389400
*/
390401
static Param *
391402
generate_new_param(PlannerInfo *root, Oid paramtype, int32 paramtypmod,
@@ -395,7 +406,9 @@ generate_new_param(PlannerInfo *root, Oid paramtype, int32 paramtypmod,
395406

396407
retval = makeNode(Param);
397408
retval->paramkind = PARAM_EXEC;
398-
retval->paramid = root->glob->nParamExec++;
409+
retval->paramid = list_length(root->glob->paramExecTypes);
410+
root->glob->paramExecTypes = lappend_oid(root->glob->paramExecTypes,
411+
paramtype);
399412
retval->paramtype = paramtype;
400413
retval->paramtypmod = paramtypmod;
401414
retval->paramcollid = paramcollation;
@@ -415,7 +428,11 @@ generate_new_param(PlannerInfo *root, Oid paramtype, int32 paramtypmod,
415428
int
416429
SS_assign_special_param(PlannerInfo *root)
417430
{
418-
return root->glob->nParamExec++;
431+
int paramId = list_length(root->glob->paramExecTypes);
432+
433+
root->glob->paramExecTypes = lappend_oid(root->glob->paramExecTypes,
434+
InvalidOid);
435+
return paramId;
419436
}
420437

421438
/*
@@ -2098,7 +2115,7 @@ SS_identify_outer_params(PlannerInfo *root)
20982115
* If no parameters have been assigned anywhere in the tree, we certainly
20992116
* don't need to do anything here.
21002117
*/
2101-
if (root->glob->nParamExec == 0)
2118+
if (root->glob->paramExecTypes == NIL)
21022119
return;
21032120

21042121
/*

src/backend/optimizer/util/clauses.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1095,7 +1095,7 @@ is_parallel_safe(PlannerInfo *root, Node *node)
10951095
* in this expression. But otherwise we don't need to look.
10961096
*/
10971097
if (root->glob->maxParallelHazard == PROPARALLEL_SAFE &&
1098-
root->glob->nParamExec == 0)
1098+
root->glob->paramExecTypes == NIL)
10991099
return true;
11001100
/* Else use max_parallel_hazard's search logic, but stop on RESTRICTED */
11011101
context.max_hazard = PROPARALLEL_SAFE;

src/include/nodes/plannodes.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ typedef struct PlannedStmt
8989

9090
List *invalItems; /* other dependencies, as PlanInvalItems */
9191

92-
int nParamExec; /* number of PARAM_EXEC Params used */
92+
List *paramExecTypes; /* type OIDs for PARAM_EXEC Params */
9393

9494
Node *utilityStmt; /* non-null if this is utility stmt */
9595

src/include/nodes/relation.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ typedef struct PlannerGlobal
114114

115115
List *invalItems; /* other dependencies, as PlanInvalItems */
116116

117-
int nParamExec; /* number of PARAM_EXEC Params used */
117+
List *paramExecTypes; /* type OIDs for PARAM_EXEC Params */
118118

119119
Index lastPHId; /* highest PlaceHolderVar ID assigned */
120120

@@ -2219,8 +2219,8 @@ typedef struct MinMaxAggInfo
22192219
* from subplans (values that are setParam items for those subplans). These
22202220
* IDs need not be tracked via PlannerParamItems, since we do not need any
22212221
* duplicate-elimination nor later processing of the represented expressions.
2222-
* Instead, we just record the assignment of the slot number by incrementing
2223-
* root->glob->nParamExec.
2222+
* Instead, we just record the assignment of the slot number by appending to
2223+
* root->glob->paramExecTypes.
22242224
*/
22252225
typedef struct PlannerParamItem
22262226
{

0 commit comments

Comments
 (0)