*/
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;
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)
{
* 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)
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;
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);
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);
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);
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);
glob->rootResultRelations = NIL;
glob->relationOids = NIL;
glob->invalItems = NIL;
- glob->nParamExec = 0;
+ glob->paramExecTypes = NIL;
glob->lastPHId = 0;
glob->lastRowMarkId = 0;
glob->lastPlanNodeId = 0;
* 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)
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;
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);
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);
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);
Param *retval;
PlannerParamItem *pitem;
Index levelsup;
+ Oid ptype;
Assert(grp->agglevelsup > 0 && grp->agglevelsup < root->query_level);
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;
*
* 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,
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;
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;
}
/*
* 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;
/*
* 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;
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 */
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 */
* 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
{