PostgreSQL Source Code  git master
paramassign.c
Go to the documentation of this file.
1 /*-------------------------------------------------------------------------
2  *
3  * paramassign.c
4  * Functions for assigning PARAM_EXEC slots during planning.
5  *
6  * This module is responsible for managing three planner data structures:
7  *
8  * root->glob->paramExecTypes: records actual assignments of PARAM_EXEC slots.
9  * The i'th list element holds the data type OID of the i'th parameter slot.
10  * (Elements can be InvalidOid if they represent slots that are needed for
11  * chgParam signaling, but will never hold a value at runtime.) This list is
12  * global to the whole plan since the executor has only one PARAM_EXEC array.
13  * Assignments are permanent for the plan: we never remove entries once added.
14  *
15  * root->plan_params: a list of PlannerParamItem nodes, recording Vars and
16  * PlaceHolderVars that the root's query level needs to supply to lower-level
17  * subqueries, along with the PARAM_EXEC number to use for each such value.
18  * Elements are added to this list while planning a subquery, and the list
19  * is reset to empty after completion of each subquery.
20  *
21  * root->curOuterParams: a list of NestLoopParam nodes, recording Vars and
22  * PlaceHolderVars that some outer level of nestloop needs to pass down to
23  * a lower-level plan node in its righthand side. Elements are added to this
24  * list as createplan.c creates lower Plan nodes that need such Params, and
25  * are removed when it creates a NestLoop Plan node that will supply those
26  * values.
27  *
28  * The latter two data structures are used to prevent creating multiple
29  * PARAM_EXEC slots (each requiring work to fill) when the same upper
30  * SubPlan or NestLoop supplies a value that is referenced in more than
31  * one place in its child plan nodes. However, when the same Var has to
32  * be supplied to different subplan trees by different SubPlan or NestLoop
33  * parent nodes, we don't recognize any commonality; a fresh plan_params or
34  * curOuterParams entry will be made (since the old one has been removed
35  * when we finished processing the earlier SubPlan or NestLoop) and a fresh
36  * PARAM_EXEC number will be assigned. At one time we tried to avoid
37  * allocating duplicate PARAM_EXEC numbers in such cases, but it's harder
38  * than it seems to avoid bugs due to overlapping Param lifetimes, so we
39  * don't risk that anymore. Minimizing the number of PARAM_EXEC slots
40  * doesn't really save much executor work anyway.
41  *
42  *
43  * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group
44  * Portions Copyright (c) 1994, Regents of the University of California
45  *
46  * IDENTIFICATION
47  * src/backend/optimizer/util/paramassign.c
48  *
49  *-------------------------------------------------------------------------
50  */
51 #include "postgres.h"
52 
53 #include "nodes/nodeFuncs.h"
54 #include "nodes/plannodes.h"
55 #include "optimizer/paramassign.h"
56 #include "optimizer/placeholder.h"
57 #include "rewrite/rewriteManip.h"
58 
59 
60 /*
61  * Select a PARAM_EXEC number to identify the given Var as a parameter for
62  * the current subquery. (It might already have one.)
63  * Record the need for the Var in the proper upper-level root->plan_params.
64  */
65 static int
67 {
68  ListCell *ppl;
69  PlannerParamItem *pitem;
70  Index levelsup;
71 
72  /* Find the query level the Var belongs to */
73  for (levelsup = var->varlevelsup; levelsup > 0; levelsup--)
74  root = root->parent_root;
75 
76  /* If there's already a matching PlannerParamItem there, just use it */
77  foreach(ppl, root->plan_params)
78  {
79  pitem = (PlannerParamItem *) lfirst(ppl);
80  if (IsA(pitem->item, Var))
81  {
82  Var *pvar = (Var *) pitem->item;
83 
84  /*
85  * This comparison must match _equalVar(), except for ignoring
86  * varlevelsup. Note that _equalVar() ignores varnosyn,
87  * varattnosyn, and location, so this does too.
88  */
89  if (pvar->varno == var->varno &&
90  pvar->varattno == var->varattno &&
91  pvar->vartype == var->vartype &&
92  pvar->vartypmod == var->vartypmod &&
93  pvar->varcollid == var->varcollid)
94  return pitem->paramId;
95  }
96  }
97 
98  /* Nope, so make a new one */
99  var = copyObject(var);
100  var->varlevelsup = 0;
101 
102  pitem = makeNode(PlannerParamItem);
103  pitem->item = (Node *) var;
104  pitem->paramId = list_length(root->glob->paramExecTypes);
106  var->vartype);
107 
108  root->plan_params = lappend(root->plan_params, pitem);
109 
110  return pitem->paramId;
111 }
112 
113 /*
114  * Generate a Param node to replace the given Var,
115  * which is expected to have varlevelsup > 0 (ie, it is not local).
116  * Record the need for the Var in the proper upper-level root->plan_params.
117  */
118 Param *
120 {
121  Param *retval;
122  int i;
123 
124  Assert(var->varlevelsup > 0 && var->varlevelsup < root->query_level);
125 
126  /* Find the Var in the appropriate plan_params, or add it if not present */
127  i = assign_param_for_var(root, var);
128 
129  retval = makeNode(Param);
130  retval->paramkind = PARAM_EXEC;
131  retval->paramid = i;
132  retval->paramtype = var->vartype;
133  retval->paramtypmod = var->vartypmod;
134  retval->paramcollid = var->varcollid;
135  retval->location = var->location;
136 
137  return retval;
138 }
139 
140 /*
141  * Select a PARAM_EXEC number to identify the given PlaceHolderVar as a
142  * parameter for the current subquery. (It might already have one.)
143  * Record the need for the PHV in the proper upper-level root->plan_params.
144  *
145  * This is just like assign_param_for_var, except for PlaceHolderVars.
146  */
147 static int
149 {
150  ListCell *ppl;
151  PlannerParamItem *pitem;
152  Index levelsup;
153 
154  /* Find the query level the PHV belongs to */
155  for (levelsup = phv->phlevelsup; levelsup > 0; levelsup--)
156  root = root->parent_root;
157 
158  /* If there's already a matching PlannerParamItem there, just use it */
159  foreach(ppl, root->plan_params)
160  {
161  pitem = (PlannerParamItem *) lfirst(ppl);
162  if (IsA(pitem->item, PlaceHolderVar))
163  {
164  PlaceHolderVar *pphv = (PlaceHolderVar *) pitem->item;
165 
166  /* We assume comparing the PHIDs is sufficient */
167  if (pphv->phid == phv->phid)
168  return pitem->paramId;
169  }
170  }
171 
172  /* Nope, so make a new one */
173  phv = copyObject(phv);
174  IncrementVarSublevelsUp((Node *) phv, -((int) phv->phlevelsup), 0);
175  Assert(phv->phlevelsup == 0);
176 
177  pitem = makeNode(PlannerParamItem);
178  pitem->item = (Node *) phv;
179  pitem->paramId = list_length(root->glob->paramExecTypes);
181  exprType((Node *) phv->phexpr));
182 
183  root->plan_params = lappend(root->plan_params, pitem);
184 
185  return pitem->paramId;
186 }
187 
188 /*
189  * Generate a Param node to replace the given PlaceHolderVar,
190  * which is expected to have phlevelsup > 0 (ie, it is not local).
191  * Record the need for the PHV in the proper upper-level root->plan_params.
192  *
193  * This is just like replace_outer_var, except for PlaceHolderVars.
194  */
195 Param *
197 {
198  Param *retval;
199  int i;
200 
201  Assert(phv->phlevelsup > 0 && phv->phlevelsup < root->query_level);
202 
203  /* Find the PHV in the appropriate plan_params, or add it if not present */
204  i = assign_param_for_placeholdervar(root, phv);
205 
206  retval = makeNode(Param);
207  retval->paramkind = PARAM_EXEC;
208  retval->paramid = i;
209  retval->paramtype = exprType((Node *) phv->phexpr);
210  retval->paramtypmod = exprTypmod((Node *) phv->phexpr);
211  retval->paramcollid = exprCollation((Node *) phv->phexpr);
212  retval->location = -1;
213 
214  return retval;
215 }
216 
217 /*
218  * Generate a Param node to replace the given Aggref
219  * which is expected to have agglevelsup > 0 (ie, it is not local).
220  * Record the need for the Aggref in the proper upper-level root->plan_params.
221  */
222 Param *
224 {
225  Param *retval;
226  PlannerParamItem *pitem;
227  Index levelsup;
228 
229  Assert(agg->agglevelsup > 0 && agg->agglevelsup < root->query_level);
230 
231  /* Find the query level the Aggref belongs to */
232  for (levelsup = agg->agglevelsup; levelsup > 0; levelsup--)
233  root = root->parent_root;
234 
235  /*
236  * It does not seem worthwhile to try to de-duplicate references to outer
237  * aggs. Just make a new slot every time.
238  */
239  agg = copyObject(agg);
240  IncrementVarSublevelsUp((Node *) agg, -((int) agg->agglevelsup), 0);
241  Assert(agg->agglevelsup == 0);
242 
243  pitem = makeNode(PlannerParamItem);
244  pitem->item = (Node *) agg;
245  pitem->paramId = list_length(root->glob->paramExecTypes);
247  agg->aggtype);
248 
249  root->plan_params = lappend(root->plan_params, pitem);
250 
251  retval = makeNode(Param);
252  retval->paramkind = PARAM_EXEC;
253  retval->paramid = pitem->paramId;
254  retval->paramtype = agg->aggtype;
255  retval->paramtypmod = -1;
256  retval->paramcollid = agg->aggcollid;
257  retval->location = agg->location;
258 
259  return retval;
260 }
261 
262 /*
263  * Generate a Param node to replace the given GroupingFunc expression which is
264  * expected to have agglevelsup > 0 (ie, it is not local).
265  * Record the need for the GroupingFunc in the proper upper-level
266  * root->plan_params.
267  */
268 Param *
270 {
271  Param *retval;
272  PlannerParamItem *pitem;
273  Index levelsup;
274  Oid ptype = exprType((Node *) grp);
275 
276  Assert(grp->agglevelsup > 0 && grp->agglevelsup < root->query_level);
277 
278  /* Find the query level the GroupingFunc belongs to */
279  for (levelsup = grp->agglevelsup; levelsup > 0; levelsup--)
280  root = root->parent_root;
281 
282  /*
283  * It does not seem worthwhile to try to de-duplicate references to outer
284  * aggs. Just make a new slot every time.
285  */
286  grp = copyObject(grp);
287  IncrementVarSublevelsUp((Node *) grp, -((int) grp->agglevelsup), 0);
288  Assert(grp->agglevelsup == 0);
289 
290  pitem = makeNode(PlannerParamItem);
291  pitem->item = (Node *) grp;
292  pitem->paramId = list_length(root->glob->paramExecTypes);
294  ptype);
295 
296  root->plan_params = lappend(root->plan_params, pitem);
297 
298  retval = makeNode(Param);
299  retval->paramkind = PARAM_EXEC;
300  retval->paramid = pitem->paramId;
301  retval->paramtype = ptype;
302  retval->paramtypmod = -1;
303  retval->paramcollid = InvalidOid;
304  retval->location = grp->location;
305 
306  return retval;
307 }
308 
309 /*
310  * Generate a Param node to replace the given Var,
311  * which is expected to come from some upper NestLoop plan node.
312  * Record the need for the Var in root->curOuterParams.
313  */
314 Param *
316 {
317  Param *param;
318  NestLoopParam *nlp;
319  ListCell *lc;
320 
321  /* Is this Var already listed in root->curOuterParams? */
322  foreach(lc, root->curOuterParams)
323  {
324  nlp = (NestLoopParam *) lfirst(lc);
325  if (equal(var, nlp->paramval))
326  {
327  /* Yes, so just make a Param referencing this NLP's slot */
328  param = makeNode(Param);
329  param->paramkind = PARAM_EXEC;
330  param->paramid = nlp->paramno;
331  param->paramtype = var->vartype;
332  param->paramtypmod = var->vartypmod;
333  param->paramcollid = var->varcollid;
334  param->location = var->location;
335  return param;
336  }
337  }
338 
339  /* No, so assign a PARAM_EXEC slot for a new NLP */
340  param = generate_new_exec_param(root,
341  var->vartype,
342  var->vartypmod,
343  var->varcollid);
344  param->location = var->location;
345 
346  /* Add it to the list of required NLPs */
347  nlp = makeNode(NestLoopParam);
348  nlp->paramno = param->paramid;
349  nlp->paramval = copyObject(var);
350  root->curOuterParams = lappend(root->curOuterParams, nlp);
351 
352  /* And return the replacement Param */
353  return param;
354 }
355 
356 /*
357  * Generate a Param node to replace the given PlaceHolderVar,
358  * which is expected to come from some upper NestLoop plan node.
359  * Record the need for the PHV in root->curOuterParams.
360  *
361  * This is just like replace_nestloop_param_var, except for PlaceHolderVars.
362  */
363 Param *
365 {
366  Param *param;
367  NestLoopParam *nlp;
368  ListCell *lc;
369 
370  /* Is this PHV already listed in root->curOuterParams? */
371  foreach(lc, root->curOuterParams)
372  {
373  nlp = (NestLoopParam *) lfirst(lc);
374  if (equal(phv, nlp->paramval))
375  {
376  /* Yes, so just make a Param referencing this NLP's slot */
377  param = makeNode(Param);
378  param->paramkind = PARAM_EXEC;
379  param->paramid = nlp->paramno;
380  param->paramtype = exprType((Node *) phv->phexpr);
381  param->paramtypmod = exprTypmod((Node *) phv->phexpr);
382  param->paramcollid = exprCollation((Node *) phv->phexpr);
383  param->location = -1;
384  return param;
385  }
386  }
387 
388  /* No, so assign a PARAM_EXEC slot for a new NLP */
389  param = generate_new_exec_param(root,
390  exprType((Node *) phv->phexpr),
391  exprTypmod((Node *) phv->phexpr),
392  exprCollation((Node *) phv->phexpr));
393 
394  /* Add it to the list of required NLPs */
395  nlp = makeNode(NestLoopParam);
396  nlp->paramno = param->paramid;
397  nlp->paramval = (Var *) copyObject(phv);
398  root->curOuterParams = lappend(root->curOuterParams, nlp);
399 
400  /* And return the replacement Param */
401  return param;
402 }
403 
404 /*
405  * process_subquery_nestloop_params
406  * Handle params of a parameterized subquery that need to be fed
407  * from an outer nestloop.
408  *
409  * Currently, that would be *all* params that a subquery in FROM has demanded
410  * from the current query level, since they must be LATERAL references.
411  *
412  * subplan_params is a list of PlannerParamItems that we intend to pass to
413  * a subquery-in-FROM. (This was constructed in root->plan_params while
414  * planning the subquery, but isn't there anymore when this is called.)
415  *
416  * The subplan's references to the outer variables are already represented
417  * as PARAM_EXEC Params, since that conversion was done by the routines above
418  * while planning the subquery. So we need not modify the subplan or the
419  * PlannerParamItems here. What we do need to do is add entries to
420  * root->curOuterParams to signal the parent nestloop plan node that it must
421  * provide these values. This differs from replace_nestloop_param_var in
422  * that the PARAM_EXEC slots to use have already been determined.
423  *
424  * Note that we also use root->curOuterRels as an implicit parameter for
425  * sanity checks.
426  */
427 void
429 {
430  ListCell *lc;
431 
432  foreach(lc, subplan_params)
433  {
435 
436  if (IsA(pitem->item, Var))
437  {
438  Var *var = (Var *) pitem->item;
439  NestLoopParam *nlp;
440  ListCell *lc2;
441 
442  /* If not from a nestloop outer rel, complain */
443  if (!bms_is_member(var->varno, root->curOuterRels))
444  elog(ERROR, "non-LATERAL parameter required by subquery");
445 
446  /* Is this param already listed in root->curOuterParams? */
447  foreach(lc2, root->curOuterParams)
448  {
449  nlp = (NestLoopParam *) lfirst(lc2);
450  if (nlp->paramno == pitem->paramId)
451  {
452  Assert(equal(var, nlp->paramval));
453  /* Present, so nothing to do */
454  break;
455  }
456  }
457  if (lc2 == NULL)
458  {
459  /* No, so add it */
460  nlp = makeNode(NestLoopParam);
461  nlp->paramno = pitem->paramId;
462  nlp->paramval = copyObject(var);
463  root->curOuterParams = lappend(root->curOuterParams, nlp);
464  }
465  }
466  else if (IsA(pitem->item, PlaceHolderVar))
467  {
468  PlaceHolderVar *phv = (PlaceHolderVar *) pitem->item;
469  NestLoopParam *nlp;
470  ListCell *lc2;
471 
472  /* If not from a nestloop outer rel, complain */
473  if (!bms_is_subset(find_placeholder_info(root, phv)->ph_eval_at,
474  root->curOuterRels))
475  elog(ERROR, "non-LATERAL parameter required by subquery");
476 
477  /* Is this param already listed in root->curOuterParams? */
478  foreach(lc2, root->curOuterParams)
479  {
480  nlp = (NestLoopParam *) lfirst(lc2);
481  if (nlp->paramno == pitem->paramId)
482  {
483  Assert(equal(phv, nlp->paramval));
484  /* Present, so nothing to do */
485  break;
486  }
487  }
488  if (lc2 == NULL)
489  {
490  /* No, so add it */
491  nlp = makeNode(NestLoopParam);
492  nlp->paramno = pitem->paramId;
493  nlp->paramval = (Var *) copyObject(phv);
494  root->curOuterParams = lappend(root->curOuterParams, nlp);
495  }
496  }
497  else
498  elog(ERROR, "unexpected type of subquery parameter");
499  }
500 }
501 
502 /*
503  * Identify any NestLoopParams that should be supplied by a NestLoop plan
504  * node with the specified lefthand rels. Remove them from the active
505  * root->curOuterParams list and return them as the result list.
506  *
507  * XXX Here we also hack up the returned Vars and PHVs so that they do not
508  * contain nullingrel sets exceeding what is available from the outer side.
509  * This is needed if we have applied outer join identity 3,
510  * (A leftjoin B on (Pab)) leftjoin C on (Pb*c)
511  * = A leftjoin (B leftjoin C on (Pbc)) on (Pab)
512  * and C contains lateral references to B. It's still safe to apply the
513  * identity, but the parser will have created those references in the form
514  * "b*" (i.e., with varnullingrels listing the A/B join), while what we will
515  * have available from the nestloop's outer side is just "b". We deal with
516  * that here by stripping the nullingrels down to what is available from the
517  * outer side according to leftrelids.
518  *
519  * That fixes matters for the case of forward application of identity 3.
520  * If the identity was applied in the reverse direction, we will have
521  * parameter Vars containing too few nullingrel bits rather than too many.
522  * Currently, that causes no problems because setrefs.c applies only a
523  * subset check to nullingrels in NestLoopParams, but we'd have to work
524  * harder if we ever want to tighten that check. This is all pretty annoying
525  * because it greatly weakens setrefs.c's cross-check, but the alternative
526  * seems to be to generate multiple versions of each laterally-parameterized
527  * subquery, which'd be unduly expensive.
528  */
529 List *
531 {
532  List *result;
533  ListCell *cell;
534 
535  result = NIL;
536  foreach(cell, root->curOuterParams)
537  {
538  NestLoopParam *nlp = (NestLoopParam *) lfirst(cell);
539 
540  /*
541  * We are looking for Vars and PHVs that can be supplied by the
542  * lefthand rels. When we find one, it's okay to modify it in-place
543  * because all the routines above make a fresh copy to put into
544  * curOuterParams.
545  */
546  if (IsA(nlp->paramval, Var) &&
547  bms_is_member(nlp->paramval->varno, leftrelids))
548  {
549  Var *var = (Var *) nlp->paramval;
550 
552  cell);
553  var->varnullingrels = bms_intersect(var->varnullingrels,
554  leftrelids);
555  result = lappend(result, nlp);
556  }
557  else if (IsA(nlp->paramval, PlaceHolderVar) &&
560  leftrelids))
561  {
562  PlaceHolderVar *phv = (PlaceHolderVar *) nlp->paramval;
563 
565  cell);
567  leftrelids);
568  result = lappend(result, nlp);
569  }
570  }
571  return result;
572 }
573 
574 /*
575  * Generate a new Param node that will not conflict with any other.
576  *
577  * This is used to create Params representing subplan outputs or
578  * NestLoop parameters.
579  *
580  * We don't need to build a PlannerParamItem for such a Param, but we do
581  * need to make sure we record the type in paramExecTypes (otherwise,
582  * there won't be a slot allocated for it).
583  */
584 Param *
585 generate_new_exec_param(PlannerInfo *root, Oid paramtype, int32 paramtypmod,
586  Oid paramcollation)
587 {
588  Param *retval;
589 
590  retval = makeNode(Param);
591  retval->paramkind = PARAM_EXEC;
592  retval->paramid = list_length(root->glob->paramExecTypes);
594  paramtype);
595  retval->paramtype = paramtype;
596  retval->paramtypmod = paramtypmod;
597  retval->paramcollid = paramcollation;
598  retval->location = -1;
599 
600  return retval;
601 }
602 
603 /*
604  * Assign a (nonnegative) PARAM_EXEC ID for a special parameter (one that
605  * is not actually used to carry a value at runtime). Such parameters are
606  * used for special runtime signaling purposes, such as connecting a
607  * recursive union node to its worktable scan node or forcing plan
608  * re-evaluation within the EvalPlanQual mechanism. No actual Param node
609  * exists with this ID, however.
610  */
611 int
613 {
614  int paramId = list_length(root->glob->paramExecTypes);
615 
617  InvalidOid);
618  return paramId;
619 }
bool bms_is_subset(const Bitmapset *a, const Bitmapset *b)
Definition: bitmapset.c:363
bool bms_is_member(int x, const Bitmapset *a)
Definition: bitmapset.c:460
Bitmapset * bms_intersect(const Bitmapset *a, const Bitmapset *b)
Definition: bitmapset.c:248
signed int int32
Definition: c.h:483
unsigned int Index
Definition: c.h:603
#define ERROR
Definition: elog.h:39
bool equal(const void *a, const void *b)
Definition: equalfuncs.c:223
int i
Definition: isn.c:73
if(TABLE==NULL||TABLE_index==NULL)
Definition: isn.c:77
Assert(fmt[strlen(fmt) - 1] !='\n')
List * lappend(List *list, void *datum)
Definition: list.c:338
List * lappend_oid(List *list, Oid datum)
Definition: list.c:374
Oid exprType(const Node *expr)
Definition: nodeFuncs.c:43
int32 exprTypmod(const Node *expr)
Definition: nodeFuncs.c:282
Oid exprCollation(const Node *expr)
Definition: nodeFuncs.c:786
#define IsA(nodeptr, _type_)
Definition: nodes.h:179
#define copyObject(obj)
Definition: nodes.h:244
#define makeNode(_type_)
Definition: nodes.h:176
static int assign_param_for_var(PlannerInfo *root, Var *var)
Definition: paramassign.c:66
static int assign_param_for_placeholdervar(PlannerInfo *root, PlaceHolderVar *phv)
Definition: paramassign.c:148
Param * generate_new_exec_param(PlannerInfo *root, Oid paramtype, int32 paramtypmod, Oid paramcollation)
Definition: paramassign.c:585
Param * replace_outer_var(PlannerInfo *root, Var *var)
Definition: paramassign.c:119
void process_subquery_nestloop_params(PlannerInfo *root, List *subplan_params)
Definition: paramassign.c:428
Param * replace_outer_grouping(PlannerInfo *root, GroupingFunc *grp)
Definition: paramassign.c:269
Param * replace_nestloop_param_var(PlannerInfo *root, Var *var)
Definition: paramassign.c:315
List * identify_current_nestloop_params(PlannerInfo *root, Relids leftrelids)
Definition: paramassign.c:530
Param * replace_outer_placeholdervar(PlannerInfo *root, PlaceHolderVar *phv)
Definition: paramassign.c:196
Param * replace_outer_agg(PlannerInfo *root, Aggref *agg)
Definition: paramassign.c:223
Param * replace_nestloop_param_placeholdervar(PlannerInfo *root, PlaceHolderVar *phv)
Definition: paramassign.c:364
int assign_special_exec_param(PlannerInfo *root)
Definition: paramassign.c:612
#define lfirst(lc)
Definition: pg_list.h:172
#define lfirst_node(type, lc)
Definition: pg_list.h:176
static int list_length(const List *l)
Definition: pg_list.h:152
#define NIL
Definition: pg_list.h:68
#define foreach_delete_current(lst, cell)
Definition: pg_list.h:390
PlaceHolderInfo * find_placeholder_info(PlannerInfo *root, PlaceHolderVar *phv)
Definition: placeholder.c:83
#define InvalidOid
Definition: postgres_ext.h:36
unsigned int Oid
Definition: postgres_ext.h:31
@ PARAM_EXEC
Definition: primnodes.h:346
void IncrementVarSublevelsUp(Node *node, int delta_sublevels_up, int min_sublevels_up)
Definition: rewriteManip.c:841
int location
Definition: primnodes.h:485
Index agglevelsup
Definition: primnodes.h:529
Definition: pg_list.h:54
Var * paramval
Definition: plannodes.h:817
Definition: nodes.h:129
int paramid
Definition: primnodes.h:355
Oid paramtype
Definition: primnodes.h:356
ParamKind paramkind
Definition: primnodes.h:354
int location
Definition: primnodes.h:362
Relids ph_eval_at
Definition: pathnodes.h:3047
Relids phnullingrels
Definition: pathnodes.h:2753
Index phlevelsup
Definition: pathnodes.h:2759
List * paramExecTypes
Definition: pathnodes.h:135
Relids curOuterRels
Definition: pathnodes.h:529
Index query_level
Definition: pathnodes.h:205
PlannerGlobal * glob
Definition: pathnodes.h:202
List * plan_params
Definition: pathnodes.h:217
List * curOuterParams
Definition: pathnodes.h:531
Definition: primnodes.h:226
AttrNumber varattno
Definition: primnodes.h:238
int varno
Definition: primnodes.h:233
Index varlevelsup
Definition: primnodes.h:258
int location
Definition: primnodes.h:271