PostgreSQL Source Code git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
paramassign.h File Reference
#include "nodes/pathnodes.h"
Include dependency graph for paramassign.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

Paramreplace_outer_var (PlannerInfo *root, Var *var)
 
Paramreplace_outer_placeholdervar (PlannerInfo *root, PlaceHolderVar *phv)
 
Paramreplace_outer_agg (PlannerInfo *root, Aggref *agg)
 
Paramreplace_outer_grouping (PlannerInfo *root, GroupingFunc *grp)
 
Paramreplace_outer_merge_support (PlannerInfo *root, MergeSupportFunc *msf)
 
Paramreplace_nestloop_param_var (PlannerInfo *root, Var *var)
 
Paramreplace_nestloop_param_placeholdervar (PlannerInfo *root, PlaceHolderVar *phv)
 
void process_subquery_nestloop_params (PlannerInfo *root, List *subplan_params)
 
Listidentify_current_nestloop_params (PlannerInfo *root, Relids leftrelids)
 
Paramgenerate_new_exec_param (PlannerInfo *root, Oid paramtype, int32 paramtypmod, Oid paramcollation)
 
int assign_special_exec_param (PlannerInfo *root)
 

Function Documentation

◆ assign_special_exec_param()

int assign_special_exec_param ( PlannerInfo root)

Definition at line 664 of file paramassign.c.

665{
666 int paramId = list_length(root->glob->paramExecTypes);
667
668 root->glob->paramExecTypes = lappend_oid(root->glob->paramExecTypes,
669 InvalidOid);
670 return paramId;
671}
List * lappend_oid(List *list, Oid datum)
Definition: list.c:375
static int list_length(const List *l)
Definition: pg_list.h:152
#define InvalidOid
Definition: postgres_ext.h:36
tree ctl root
Definition: radixtree.h:1857

References InvalidOid, lappend_oid(), list_length(), and root.

Referenced by create_gather_merge_plan(), create_gather_plan(), grouping_planner(), SS_process_ctes(), and subquery_planner().

◆ generate_new_exec_param()

Param * generate_new_exec_param ( PlannerInfo root,
Oid  paramtype,
int32  paramtypmod,
Oid  paramcollation 
)

Definition at line 637 of file paramassign.c.

639{
640 Param *retval;
641
642 retval = makeNode(Param);
643 retval->paramkind = PARAM_EXEC;
644 retval->paramid = list_length(root->glob->paramExecTypes);
645 root->glob->paramExecTypes = lappend_oid(root->glob->paramExecTypes,
646 paramtype);
647 retval->paramtype = paramtype;
648 retval->paramtypmod = paramtypmod;
649 retval->paramcollid = paramcollation;
650 retval->location = -1;
651
652 return retval;
653}
#define makeNode(_type_)
Definition: nodes.h:155
@ PARAM_EXEC
Definition: primnodes.h:368
ParseLoc location
Definition: primnodes.h:384
int paramid
Definition: primnodes.h:377
Oid paramtype
Definition: primnodes.h:378
ParamKind paramkind
Definition: primnodes.h:376

References lappend_oid(), list_length(), Param::location, makeNode, PARAM_EXEC, Param::paramid, Param::paramkind, Param::paramtype, and root.

Referenced by build_subplan(), convert_EXISTS_to_ANY(), generate_subquery_params(), replace_nestloop_param_placeholdervar(), replace_nestloop_param_var(), and SS_make_initplan_output_param().

◆ identify_current_nestloop_params()

List * identify_current_nestloop_params ( PlannerInfo root,
Relids  leftrelids 
)

Definition at line 582 of file paramassign.c.

583{
584 List *result;
585 ListCell *cell;
586
587 result = NIL;
588 foreach(cell, root->curOuterParams)
589 {
590 NestLoopParam *nlp = (NestLoopParam *) lfirst(cell);
591
592 /*
593 * We are looking for Vars and PHVs that can be supplied by the
594 * lefthand rels. When we find one, it's okay to modify it in-place
595 * because all the routines above make a fresh copy to put into
596 * curOuterParams.
597 */
598 if (IsA(nlp->paramval, Var) &&
599 bms_is_member(nlp->paramval->varno, leftrelids))
600 {
601 Var *var = (Var *) nlp->paramval;
602
603 root->curOuterParams = foreach_delete_current(root->curOuterParams,
604 cell);
605 var->varnullingrels = bms_intersect(var->varnullingrels,
606 leftrelids);
607 result = lappend(result, nlp);
608 }
609 else if (IsA(nlp->paramval, PlaceHolderVar) &&
612 leftrelids))
613 {
614 PlaceHolderVar *phv = (PlaceHolderVar *) nlp->paramval;
615
616 root->curOuterParams = foreach_delete_current(root->curOuterParams,
617 cell);
619 leftrelids);
620 result = lappend(result, nlp);
621 }
622 }
623 return result;
624}
Bitmapset * bms_intersect(const Bitmapset *a, const Bitmapset *b)
Definition: bitmapset.c:292
bool bms_is_subset(const Bitmapset *a, const Bitmapset *b)
Definition: bitmapset.c:412
bool bms_is_member(int x, const Bitmapset *a)
Definition: bitmapset.c:510
List * lappend(List *list, void *datum)
Definition: list.c:339
#define IsA(nodeptr, _type_)
Definition: nodes.h:158
#define lfirst(lc)
Definition: pg_list.h:172
#define NIL
Definition: pg_list.h:68
#define foreach_delete_current(lst, var_or_cell)
Definition: pg_list.h:391
PlaceHolderInfo * find_placeholder_info(PlannerInfo *root, PlaceHolderVar *phv)
Definition: placeholder.c:83
Definition: pg_list.h:54
Var * paramval
Definition: plannodes.h:820
Relids ph_eval_at
Definition: pathnodes.h:3099
Relids phnullingrels
Definition: pathnodes.h:2802
Definition: primnodes.h:248
int varno
Definition: primnodes.h:255

References bms_intersect(), bms_is_member(), bms_is_subset(), find_placeholder_info(), foreach_delete_current, IsA, lappend(), lfirst, NIL, NestLoopParam::paramval, PlaceHolderInfo::ph_eval_at, PlaceHolderVar::phnullingrels, root, and Var::varno.

Referenced by create_nestloop_plan().

◆ process_subquery_nestloop_params()

void process_subquery_nestloop_params ( PlannerInfo root,
List subplan_params 
)

Definition at line 480 of file paramassign.c.

481{
482 ListCell *lc;
483
484 foreach(lc, subplan_params)
485 {
487
488 if (IsA(pitem->item, Var))
489 {
490 Var *var = (Var *) pitem->item;
491 NestLoopParam *nlp;
492 ListCell *lc2;
493
494 /* If not from a nestloop outer rel, complain */
495 if (!bms_is_member(var->varno, root->curOuterRels))
496 elog(ERROR, "non-LATERAL parameter required by subquery");
497
498 /* Is this param already listed in root->curOuterParams? */
499 foreach(lc2, root->curOuterParams)
500 {
501 nlp = (NestLoopParam *) lfirst(lc2);
502 if (nlp->paramno == pitem->paramId)
503 {
504 Assert(equal(var, nlp->paramval));
505 /* Present, so nothing to do */
506 break;
507 }
508 }
509 if (lc2 == NULL)
510 {
511 /* No, so add it */
512 nlp = makeNode(NestLoopParam);
513 nlp->paramno = pitem->paramId;
514 nlp->paramval = copyObject(var);
515 root->curOuterParams = lappend(root->curOuterParams, nlp);
516 }
517 }
518 else if (IsA(pitem->item, PlaceHolderVar))
519 {
520 PlaceHolderVar *phv = (PlaceHolderVar *) pitem->item;
521 NestLoopParam *nlp;
522 ListCell *lc2;
523
524 /* If not from a nestloop outer rel, complain */
525 if (!bms_is_subset(find_placeholder_info(root, phv)->ph_eval_at,
526 root->curOuterRels))
527 elog(ERROR, "non-LATERAL parameter required by subquery");
528
529 /* Is this param already listed in root->curOuterParams? */
530 foreach(lc2, root->curOuterParams)
531 {
532 nlp = (NestLoopParam *) lfirst(lc2);
533 if (nlp->paramno == pitem->paramId)
534 {
535 Assert(equal(phv, nlp->paramval));
536 /* Present, so nothing to do */
537 break;
538 }
539 }
540 if (lc2 == NULL)
541 {
542 /* No, so add it */
543 nlp = makeNode(NestLoopParam);
544 nlp->paramno = pitem->paramId;
545 nlp->paramval = (Var *) copyObject(phv);
546 root->curOuterParams = lappend(root->curOuterParams, nlp);
547 }
548 }
549 else
550 elog(ERROR, "unexpected type of subquery parameter");
551 }
552}
#define Assert(condition)
Definition: c.h:812
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:225
bool equal(const void *a, const void *b)
Definition: equalfuncs.c:223
if(TABLE==NULL||TABLE_index==NULL)
Definition: isn.c:76
#define copyObject(obj)
Definition: nodes.h:224
#define lfirst_node(type, lc)
Definition: pg_list.h:176

References Assert, bms_is_member(), bms_is_subset(), copyObject, elog, equal(), ERROR, find_placeholder_info(), if(), IsA, PlannerParamItem::item, lappend(), lfirst, lfirst_node, makeNode, PlannerParamItem::paramId, root, and Var::varno.

Referenced by create_subqueryscan_plan().

◆ replace_nestloop_param_placeholdervar()

Param * replace_nestloop_param_placeholdervar ( PlannerInfo root,
PlaceHolderVar phv 
)

Definition at line 416 of file paramassign.c.

417{
418 Param *param;
419 NestLoopParam *nlp;
420 ListCell *lc;
421
422 /* Is this PHV already listed in root->curOuterParams? */
423 foreach(lc, root->curOuterParams)
424 {
425 nlp = (NestLoopParam *) lfirst(lc);
426 if (equal(phv, nlp->paramval))
427 {
428 /* Yes, so just make a Param referencing this NLP's slot */
429 param = makeNode(Param);
430 param->paramkind = PARAM_EXEC;
431 param->paramid = nlp->paramno;
432 param->paramtype = exprType((Node *) phv->phexpr);
433 param->paramtypmod = exprTypmod((Node *) phv->phexpr);
434 param->paramcollid = exprCollation((Node *) phv->phexpr);
435 param->location = -1;
436 return param;
437 }
438 }
439
440 /* No, so assign a PARAM_EXEC slot for a new NLP */
442 exprType((Node *) phv->phexpr),
443 exprTypmod((Node *) phv->phexpr),
444 exprCollation((Node *) phv->phexpr));
445
446 /* Add it to the list of required NLPs */
447 nlp = makeNode(NestLoopParam);
448 nlp->paramno = param->paramid;
449 nlp->paramval = (Var *) copyObject(phv);
450 root->curOuterParams = lappend(root->curOuterParams, nlp);
451
452 /* And return the replacement Param */
453 return param;
454}
Oid exprType(const Node *expr)
Definition: nodeFuncs.c:42
int32 exprTypmod(const Node *expr)
Definition: nodeFuncs.c:298
Oid exprCollation(const Node *expr)
Definition: nodeFuncs.c:816
Param * generate_new_exec_param(PlannerInfo *root, Oid paramtype, int32 paramtypmod, Oid paramcollation)
Definition: paramassign.c:637
Definition: nodes.h:129

References copyObject, equal(), exprCollation(), exprType(), exprTypmod(), generate_new_exec_param(), lappend(), lfirst, Param::location, makeNode, PARAM_EXEC, Param::paramid, Param::paramkind, NestLoopParam::paramno, Param::paramtype, NestLoopParam::paramval, and root.

Referenced by replace_nestloop_params_mutator().

◆ replace_nestloop_param_var()

Param * replace_nestloop_param_var ( PlannerInfo root,
Var var 
)

Definition at line 367 of file paramassign.c.

368{
369 Param *param;
370 NestLoopParam *nlp;
371 ListCell *lc;
372
373 /* Is this Var already listed in root->curOuterParams? */
374 foreach(lc, root->curOuterParams)
375 {
376 nlp = (NestLoopParam *) lfirst(lc);
377 if (equal(var, nlp->paramval))
378 {
379 /* Yes, so just make a Param referencing this NLP's slot */
380 param = makeNode(Param);
381 param->paramkind = PARAM_EXEC;
382 param->paramid = nlp->paramno;
383 param->paramtype = var->vartype;
384 param->paramtypmod = var->vartypmod;
385 param->paramcollid = var->varcollid;
386 param->location = var->location;
387 return param;
388 }
389 }
390
391 /* No, so assign a PARAM_EXEC slot for a new NLP */
393 var->vartype,
394 var->vartypmod,
395 var->varcollid);
396 param->location = var->location;
397
398 /* Add it to the list of required NLPs */
399 nlp = makeNode(NestLoopParam);
400 nlp->paramno = param->paramid;
401 nlp->paramval = copyObject(var);
402 root->curOuterParams = lappend(root->curOuterParams, nlp);
403
404 /* And return the replacement Param */
405 return param;
406}
ParseLoc location
Definition: primnodes.h:293

References copyObject, equal(), generate_new_exec_param(), lappend(), lfirst, Var::location, Param::location, makeNode, PARAM_EXEC, Param::paramid, Param::paramkind, NestLoopParam::paramno, Param::paramtype, NestLoopParam::paramval, and root.

Referenced by replace_nestloop_params_mutator().

◆ replace_outer_agg()

Param * replace_outer_agg ( PlannerInfo root,
Aggref agg 
)

Definition at line 224 of file paramassign.c.

225{
226 Param *retval;
227 PlannerParamItem *pitem;
228 Index levelsup;
229
230 Assert(agg->agglevelsup > 0 && agg->agglevelsup < root->query_level);
231
232 /* Find the query level the Aggref belongs to */
233 for (levelsup = agg->agglevelsup; levelsup > 0; levelsup--)
234 root = root->parent_root;
235
236 /*
237 * It does not seem worthwhile to try to de-duplicate references to outer
238 * aggs. Just make a new slot every time.
239 */
240 agg = copyObject(agg);
241 IncrementVarSublevelsUp((Node *) agg, -((int) agg->agglevelsup), 0);
242 Assert(agg->agglevelsup == 0);
243
244 pitem = makeNode(PlannerParamItem);
245 pitem->item = (Node *) agg;
246 pitem->paramId = list_length(root->glob->paramExecTypes);
247 root->glob->paramExecTypes = lappend_oid(root->glob->paramExecTypes,
248 agg->aggtype);
249
250 root->plan_params = lappend(root->plan_params, pitem);
251
252 retval = makeNode(Param);
253 retval->paramkind = PARAM_EXEC;
254 retval->paramid = pitem->paramId;
255 retval->paramtype = agg->aggtype;
256 retval->paramtypmod = -1;
257 retval->paramcollid = agg->aggcollid;
258 retval->location = agg->location;
259
260 return retval;
261}
unsigned int Index
Definition: c.h:568
void IncrementVarSublevelsUp(Node *node, int delta_sublevels_up, int min_sublevels_up)
Definition: rewriteManip.c:841

References Assert, copyObject, IncrementVarSublevelsUp(), PlannerParamItem::item, lappend(), lappend_oid(), list_length(), Param::location, Aggref::location, makeNode, PARAM_EXEC, PlannerParamItem::paramId, Param::paramid, Param::paramkind, Param::paramtype, and root.

Referenced by replace_correlation_vars_mutator().

◆ replace_outer_grouping()

Param * replace_outer_grouping ( PlannerInfo root,
GroupingFunc grp 
)

Definition at line 270 of file paramassign.c.

271{
272 Param *retval;
273 PlannerParamItem *pitem;
274 Index levelsup;
275 Oid ptype = exprType((Node *) grp);
276
277 Assert(grp->agglevelsup > 0 && grp->agglevelsup < root->query_level);
278
279 /* Find the query level the GroupingFunc belongs to */
280 for (levelsup = grp->agglevelsup; levelsup > 0; levelsup--)
281 root = root->parent_root;
282
283 /*
284 * It does not seem worthwhile to try to de-duplicate references to outer
285 * aggs. Just make a new slot every time.
286 */
287 grp = copyObject(grp);
288 IncrementVarSublevelsUp((Node *) grp, -((int) grp->agglevelsup), 0);
289 Assert(grp->agglevelsup == 0);
290
291 pitem = makeNode(PlannerParamItem);
292 pitem->item = (Node *) grp;
293 pitem->paramId = list_length(root->glob->paramExecTypes);
294 root->glob->paramExecTypes = lappend_oid(root->glob->paramExecTypes,
295 ptype);
296
297 root->plan_params = lappend(root->plan_params, pitem);
298
299 retval = makeNode(Param);
300 retval->paramkind = PARAM_EXEC;
301 retval->paramid = pitem->paramId;
302 retval->paramtype = ptype;
303 retval->paramtypmod = -1;
304 retval->paramcollid = InvalidOid;
305 retval->location = grp->location;
306
307 return retval;
308}
unsigned int Oid
Definition: postgres_ext.h:31
Index agglevelsup
Definition: primnodes.h:551

References GroupingFunc::agglevelsup, Assert, copyObject, exprType(), IncrementVarSublevelsUp(), InvalidOid, PlannerParamItem::item, lappend(), lappend_oid(), list_length(), Param::location, GroupingFunc::location, makeNode, PARAM_EXEC, PlannerParamItem::paramId, Param::paramid, Param::paramkind, Param::paramtype, and root.

Referenced by replace_correlation_vars_mutator().

◆ replace_outer_merge_support()

Param * replace_outer_merge_support ( PlannerInfo root,
MergeSupportFunc msf 
)

Definition at line 317 of file paramassign.c.

318{
319 Param *retval;
320 PlannerParamItem *pitem;
321 Oid ptype = exprType((Node *) msf);
322
323 Assert(root->parse->commandType != CMD_MERGE);
324
325 /*
326 * The parser should have ensured that the MergeSupportFunc is in the
327 * RETURNING list of an upper-level MERGE query, so find that query.
328 */
329 do
330 {
331 root = root->parent_root;
332 if (root == NULL)
333 elog(ERROR, "MergeSupportFunc found outside MERGE");
334 } while (root->parse->commandType != CMD_MERGE);
335
336 /*
337 * It does not seem worthwhile to try to de-duplicate references to outer
338 * MergeSupportFunc expressions. Just make a new slot every time.
339 */
340 msf = copyObject(msf);
341
342 pitem = makeNode(PlannerParamItem);
343 pitem->item = (Node *) msf;
344 pitem->paramId = list_length(root->glob->paramExecTypes);
345 root->glob->paramExecTypes = lappend_oid(root->glob->paramExecTypes,
346 ptype);
347
348 root->plan_params = lappend(root->plan_params, pitem);
349
350 retval = makeNode(Param);
351 retval->paramkind = PARAM_EXEC;
352 retval->paramid = pitem->paramId;
353 retval->paramtype = ptype;
354 retval->paramtypmod = -1;
355 retval->paramcollid = InvalidOid;
356 retval->location = msf->location;
357
358 return retval;
359}
@ CMD_MERGE
Definition: nodes.h:269
ParseLoc location
Definition: primnodes.h:636

References Assert, CMD_MERGE, copyObject, elog, ERROR, exprType(), InvalidOid, PlannerParamItem::item, lappend(), lappend_oid(), list_length(), Param::location, MergeSupportFunc::location, makeNode, PARAM_EXEC, PlannerParamItem::paramId, Param::paramid, Param::paramkind, Param::paramtype, and root.

Referenced by replace_correlation_vars_mutator().

◆ replace_outer_placeholdervar()

Param * replace_outer_placeholdervar ( PlannerInfo root,
PlaceHolderVar phv 
)

Definition at line 197 of file paramassign.c.

198{
199 Param *retval;
200 int i;
201
202 Assert(phv->phlevelsup > 0 && phv->phlevelsup < root->query_level);
203
204 /* Find the PHV in the appropriate plan_params, or add it if not present */
206
207 retval = makeNode(Param);
208 retval->paramkind = PARAM_EXEC;
209 retval->paramid = i;
210 retval->paramtype = exprType((Node *) phv->phexpr);
211 retval->paramtypmod = exprTypmod((Node *) phv->phexpr);
212 retval->paramcollid = exprCollation((Node *) phv->phexpr);
213 retval->location = -1;
214
215 return retval;
216}
int i
Definition: isn.c:72
static int assign_param_for_placeholdervar(PlannerInfo *root, PlaceHolderVar *phv)
Definition: paramassign.c:149
Index phlevelsup
Definition: pathnodes.h:2808

References Assert, assign_param_for_placeholdervar(), exprCollation(), exprType(), exprTypmod(), i, Param::location, makeNode, PARAM_EXEC, Param::paramid, Param::paramkind, Param::paramtype, PlaceHolderVar::phlevelsup, and root.

Referenced by replace_correlation_vars_mutator().

◆ replace_outer_var()

Param * replace_outer_var ( PlannerInfo root,
Var var 
)

Definition at line 120 of file paramassign.c.

121{
122 Param *retval;
123 int i;
124
125 Assert(var->varlevelsup > 0 && var->varlevelsup < root->query_level);
126
127 /* Find the Var in the appropriate plan_params, or add it if not present */
129
130 retval = makeNode(Param);
131 retval->paramkind = PARAM_EXEC;
132 retval->paramid = i;
133 retval->paramtype = var->vartype;
134 retval->paramtypmod = var->vartypmod;
135 retval->paramcollid = var->varcollid;
136 retval->location = var->location;
137
138 return retval;
139}
static int assign_param_for_var(PlannerInfo *root, Var *var)
Definition: paramassign.c:66
Index varlevelsup
Definition: primnodes.h:280

References Assert, assign_param_for_var(), i, Var::location, Param::location, makeNode, PARAM_EXEC, Param::paramid, Param::paramkind, Param::paramtype, root, and Var::varlevelsup.

Referenced by replace_correlation_vars_mutator().