PostgreSQL Source Code  git master
prepjointree.c
Go to the documentation of this file.
1 /*-------------------------------------------------------------------------
2  *
3  * prepjointree.c
4  * Planner preprocessing for subqueries and join tree manipulation.
5  *
6  * NOTE: the intended sequence for invoking these operations is
7  * replace_empty_jointree
8  * pull_up_sublinks
9  * preprocess_function_rtes
10  * pull_up_subqueries
11  * flatten_simple_union_all
12  * do expression preprocessing (including flattening JOIN alias vars)
13  * reduce_outer_joins
14  * remove_useless_result_rtes
15  *
16  *
17  * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
18  * Portions Copyright (c) 1994, Regents of the University of California
19  *
20  *
21  * IDENTIFICATION
22  * src/backend/optimizer/prep/prepjointree.c
23  *
24  *-------------------------------------------------------------------------
25  */
26 #include "postgres.h"
27 
28 #include "catalog/pg_type.h"
29 #include "funcapi.h"
30 #include "nodes/makefuncs.h"
31 #include "nodes/nodeFuncs.h"
32 #include "optimizer/clauses.h"
33 #include "optimizer/optimizer.h"
34 #include "optimizer/placeholder.h"
35 #include "optimizer/prep.h"
36 #include "optimizer/subselect.h"
37 #include "optimizer/tlist.h"
38 #include "parser/parse_relation.h"
39 #include "parser/parsetree.h"
40 #include "rewrite/rewriteManip.h"
41 
42 
44 {
46  List *targetlist; /* tlist of subquery being pulled up */
47  RangeTblEntry *target_rte; /* RTE of subquery */
48  Relids relids; /* relids within subquery, as numbered after
49  * pullup (set only if target_rte->lateral) */
50  bool *outer_hasSubLinks; /* -> outer query's hasSubLinks */
51  int varno; /* varno of subquery */
52  bool need_phvs; /* do we need PlaceHolderVars? */
53  bool wrap_non_vars; /* do we need 'em on *all* non-Vars? */
54  Node **rv_cache; /* cache for results with PHVs */
56 
58 {
59  Relids relids; /* base relids within this subtree */
60  bool contains_outer; /* does subtree contain outer join(s)? */
61  List *sub_states; /* List of states for subtree components */
63 
65  Relids *relids);
67  Node **jtlink1, Relids available_rels1,
68  Node **jtlink2, Relids available_rels2);
69 static Node *pull_up_subqueries_recurse(PlannerInfo *root, Node *jtnode,
70  JoinExpr *lowest_outer_join,
71  JoinExpr *lowest_nulling_outer_join,
72  AppendRelInfo *containing_appendrel);
73 static Node *pull_up_simple_subquery(PlannerInfo *root, Node *jtnode,
74  RangeTblEntry *rte,
75  JoinExpr *lowest_outer_join,
76  JoinExpr *lowest_nulling_outer_join,
77  AppendRelInfo *containing_appendrel);
78 static Node *pull_up_simple_union_all(PlannerInfo *root, Node *jtnode,
79  RangeTblEntry *rte);
80 static void pull_up_union_leaf_queries(Node *setOp, PlannerInfo *root,
81  int parentRTindex, Query *setOpQuery,
82  int childRToffset);
83 static void make_setop_translation_list(Query *query, int newvarno,
84  AppendRelInfo *appinfo);
85 static bool is_simple_subquery(PlannerInfo *root, Query *subquery,
86  RangeTblEntry *rte,
87  JoinExpr *lowest_outer_join);
88 static Node *pull_up_simple_values(PlannerInfo *root, Node *jtnode,
89  RangeTblEntry *rte);
90 static bool is_simple_values(PlannerInfo *root, RangeTblEntry *rte);
91 static Node *pull_up_constant_function(PlannerInfo *root, Node *jtnode,
92  RangeTblEntry *rte,
93  JoinExpr *lowest_nulling_outer_join,
94  AppendRelInfo *containing_appendrel);
95 static bool is_simple_union_all(Query *subquery);
96 static bool is_simple_union_all_recurse(Node *setOp, Query *setOpQuery,
97  List *colTypes);
98 static bool is_safe_append_member(Query *subquery);
100  Node *jtnode, bool restricted,
101  Relids safe_upper_varnos);
102 static void perform_pullup_replace_vars(PlannerInfo *root,
103  pullup_replace_vars_context *rvcontext,
104  JoinExpr *lowest_nulling_outer_join,
105  AppendRelInfo *containing_appendrel);
106 static void replace_vars_in_jointree(Node *jtnode,
108  JoinExpr *lowest_nulling_outer_join);
109 static Node *pullup_replace_vars(Node *expr,
110  pullup_replace_vars_context *context);
114  pullup_replace_vars_context *context);
116 static void reduce_outer_joins_pass2(Node *jtnode,
118  PlannerInfo *root,
119  Relids nonnullable_rels,
120  List *nonnullable_vars,
121  List *forced_null_vars);
122 static Node *remove_useless_results_recurse(PlannerInfo *root, Node *jtnode);
123 static int get_result_relid(PlannerInfo *root, Node *jtnode);
124 static void remove_result_refs(PlannerInfo *root, int varno, Node *newjtloc);
125 static bool find_dependent_phvs(PlannerInfo *root, int varno);
127  Node *node, int varno);
128 static void substitute_phv_relids(Node *node,
129  int varno, Relids subrelids);
130 static void fix_append_rel_relids(List *append_rel_list, int varno,
131  Relids subrelids);
132 static Node *find_jointree_node_for_rel(Node *jtnode, int relid);
133 
134 
135 /*
136  * transform_MERGE_to_join
137  * Replace a MERGE's jointree to also include the target relation.
138  */
139 void
141 {
142  RangeTblEntry *joinrte;
143  JoinExpr *joinexpr;
144  JoinType jointype;
145  int joinrti;
146  List *vars;
147 
148  if (parse->commandType != CMD_MERGE)
149  return;
150 
151  /* XXX probably bogus */
152  vars = NIL;
153 
154  /*
155  * When any WHEN NOT MATCHED THEN INSERT clauses exist, we need to use an
156  * outer join so that we process all unmatched tuples from the source
157  * relation. If none exist, we can use an inner join.
158  */
159  if (parse->mergeUseOuterJoin)
160  jointype = JOIN_RIGHT;
161  else
162  jointype = JOIN_INNER;
163 
164  /* Manufacture a join RTE to use. */
165  joinrte = makeNode(RangeTblEntry);
166  joinrte->rtekind = RTE_JOIN;
167  joinrte->jointype = jointype;
168  joinrte->joinmergedcols = 0;
169  joinrte->joinaliasvars = vars;
170  joinrte->joinleftcols = NIL; /* MERGE does not allow JOIN USING */
171  joinrte->joinrightcols = NIL; /* ditto */
172  joinrte->join_using_alias = NULL;
173 
174  joinrte->alias = NULL;
175  joinrte->eref = makeAlias("*MERGE*", NIL);
176  joinrte->lateral = false;
177  joinrte->inh = false;
178  joinrte->inFromCl = true;
179  joinrte->requiredPerms = 0;
180  joinrte->checkAsUser = InvalidOid;
181  joinrte->selectedCols = NULL;
182  joinrte->insertedCols = NULL;
183  joinrte->updatedCols = NULL;
184  joinrte->extraUpdatedCols = NULL;
185  joinrte->securityQuals = NIL;
186 
187  /*
188  * Add completed RTE to pstate's range table list, so that we know its
189  * index.
190  */
191  parse->rtable = lappend(parse->rtable, joinrte);
192  joinrti = list_length(parse->rtable);
193 
194  /*
195  * Create a JOIN between the target and the source relation.
196  */
197  joinexpr = makeNode(JoinExpr);
198  joinexpr->jointype = jointype;
199  joinexpr->isNatural = false;
200  joinexpr->larg = (Node *) makeNode(RangeTblRef);
201  ((RangeTblRef *) joinexpr->larg)->rtindex = parse->resultRelation;
202  joinexpr->rarg = linitial(parse->jointree->fromlist); /* original join */
203  joinexpr->usingClause = NIL;
204  joinexpr->join_using_alias = NULL;
205  /* The quals are removed from the jointree and into this specific join */
206  joinexpr->quals = parse->jointree->quals;
207  joinexpr->alias = NULL;
208  joinexpr->rtindex = joinrti;
209 
210  /* Make the new join be the sole entry in the query's jointree */
211  parse->jointree->fromlist = list_make1(joinexpr);
212  parse->jointree->quals = NULL;
213 }
214 
215 /*
216  * replace_empty_jointree
217  * If the Query's jointree is empty, replace it with a dummy RTE_RESULT
218  * relation.
219  *
220  * By doing this, we can avoid a bunch of corner cases that formerly existed
221  * for SELECTs with omitted FROM clauses. An example is that a subquery
222  * with empty jointree previously could not be pulled up, because that would
223  * have resulted in an empty relid set, making the subquery not uniquely
224  * identifiable for join or PlaceHolderVar processing.
225  *
226  * Unlike most other functions in this file, this function doesn't recurse;
227  * we rely on other processing to invoke it on sub-queries at suitable times.
228  */
229 void
231 {
232  RangeTblEntry *rte;
233  Index rti;
234  RangeTblRef *rtr;
235 
236  /* Nothing to do if jointree is already nonempty */
237  if (parse->jointree->fromlist != NIL)
238  return;
239 
240  /* We mustn't change it in the top level of a setop tree, either */
241  if (parse->setOperations)
242  return;
243 
244  /* Create suitable RTE */
245  rte = makeNode(RangeTblEntry);
246  rte->rtekind = RTE_RESULT;
247  rte->eref = makeAlias("*RESULT*", NIL);
248 
249  /* Add it to rangetable */
250  parse->rtable = lappend(parse->rtable, rte);
251  rti = list_length(parse->rtable);
252 
253  /* And jam a reference into the jointree */
254  rtr = makeNode(RangeTblRef);
255  rtr->rtindex = rti;
256  parse->jointree->fromlist = list_make1(rtr);
257 }
258 
259 /*
260  * pull_up_sublinks
261  * Attempt to pull up ANY and EXISTS SubLinks to be treated as
262  * semijoins or anti-semijoins.
263  *
264  * A clause "foo op ANY (sub-SELECT)" can be processed by pulling the
265  * sub-SELECT up to become a rangetable entry and treating the implied
266  * comparisons as quals of a semijoin. However, this optimization *only*
267  * works at the top level of WHERE or a JOIN/ON clause, because we cannot
268  * distinguish whether the ANY ought to return FALSE or NULL in cases
269  * involving NULL inputs. Also, in an outer join's ON clause we can only
270  * do this if the sublink is degenerate (ie, references only the nullable
271  * side of the join). In that case it is legal to push the semijoin
272  * down into the nullable side of the join. If the sublink references any
273  * nonnullable-side variables then it would have to be evaluated as part
274  * of the outer join, which makes things way too complicated.
275  *
276  * Under similar conditions, EXISTS and NOT EXISTS clauses can be handled
277  * by pulling up the sub-SELECT and creating a semijoin or anti-semijoin.
278  *
279  * This routine searches for such clauses and does the necessary parsetree
280  * transformations if any are found.
281  *
282  * This routine has to run before preprocess_expression(), so the quals
283  * clauses are not yet reduced to implicit-AND format, and are not guaranteed
284  * to be AND/OR-flat either. That means we need to recursively search through
285  * explicit AND clauses. We stop as soon as we hit a non-AND item.
286  */
287 void
289 {
290  Node *jtnode;
291  Relids relids;
292 
293  /* Begin recursion through the jointree */
294  jtnode = pull_up_sublinks_jointree_recurse(root,
295  (Node *) root->parse->jointree,
296  &relids);
297 
298  /*
299  * root->parse->jointree must always be a FromExpr, so insert a dummy one
300  * if we got a bare RangeTblRef or JoinExpr out of the recursion.
301  */
302  if (IsA(jtnode, FromExpr))
303  root->parse->jointree = (FromExpr *) jtnode;
304  else
305  root->parse->jointree = makeFromExpr(list_make1(jtnode), NULL);
306 }
307 
308 /*
309  * Recurse through jointree nodes for pull_up_sublinks()
310  *
311  * In addition to returning the possibly-modified jointree node, we return
312  * a relids set of the contained rels into *relids.
313  */
314 static Node *
316  Relids *relids)
317 {
318  if (jtnode == NULL)
319  {
320  *relids = NULL;
321  }
322  else if (IsA(jtnode, RangeTblRef))
323  {
324  int varno = ((RangeTblRef *) jtnode)->rtindex;
325 
326  *relids = bms_make_singleton(varno);
327  /* jtnode is returned unmodified */
328  }
329  else if (IsA(jtnode, FromExpr))
330  {
331  FromExpr *f = (FromExpr *) jtnode;
332  List *newfromlist = NIL;
333  Relids frelids = NULL;
334  FromExpr *newf;
335  Node *jtlink;
336  ListCell *l;
337 
338  /* First, recurse to process children and collect their relids */
339  foreach(l, f->fromlist)
340  {
341  Node *newchild;
342  Relids childrelids;
343 
344  newchild = pull_up_sublinks_jointree_recurse(root,
345  lfirst(l),
346  &childrelids);
347  newfromlist = lappend(newfromlist, newchild);
348  frelids = bms_join(frelids, childrelids);
349  }
350  /* Build the replacement FromExpr; no quals yet */
351  newf = makeFromExpr(newfromlist, NULL);
352  /* Set up a link representing the rebuilt jointree */
353  jtlink = (Node *) newf;
354  /* Now process qual --- all children are available for use */
355  newf->quals = pull_up_sublinks_qual_recurse(root, f->quals,
356  &jtlink, frelids,
357  NULL, NULL);
358 
359  /*
360  * Note that the result will be either newf, or a stack of JoinExprs
361  * with newf at the base. We rely on subsequent optimization steps to
362  * flatten this and rearrange the joins as needed.
363  *
364  * Although we could include the pulled-up subqueries in the returned
365  * relids, there's no need since upper quals couldn't refer to their
366  * outputs anyway.
367  */
368  *relids = frelids;
369  jtnode = jtlink;
370  }
371  else if (IsA(jtnode, JoinExpr))
372  {
373  JoinExpr *j;
374  Relids leftrelids;
375  Relids rightrelids;
376  Node *jtlink;
377 
378  /*
379  * Make a modifiable copy of join node, but don't bother copying its
380  * subnodes (yet).
381  */
382  j = (JoinExpr *) palloc(sizeof(JoinExpr));
383  memcpy(j, jtnode, sizeof(JoinExpr));
384  jtlink = (Node *) j;
385 
386  /* Recurse to process children and collect their relids */
387  j->larg = pull_up_sublinks_jointree_recurse(root, j->larg,
388  &leftrelids);
389  j->rarg = pull_up_sublinks_jointree_recurse(root, j->rarg,
390  &rightrelids);
391 
392  /*
393  * Now process qual, showing appropriate child relids as available,
394  * and attach any pulled-up jointree items at the right place. In the
395  * inner-join case we put new JoinExprs above the existing one (much
396  * as for a FromExpr-style join). In outer-join cases the new
397  * JoinExprs must go into the nullable side of the outer join. The
398  * point of the available_rels machinations is to ensure that we only
399  * pull up quals for which that's okay.
400  *
401  * We don't expect to see any pre-existing JOIN_SEMI or JOIN_ANTI
402  * nodes here.
403  */
404  switch (j->jointype)
405  {
406  case JOIN_INNER:
407  j->quals = pull_up_sublinks_qual_recurse(root, j->quals,
408  &jtlink,
409  bms_union(leftrelids,
410  rightrelids),
411  NULL, NULL);
412  break;
413  case JOIN_LEFT:
414  j->quals = pull_up_sublinks_qual_recurse(root, j->quals,
415  &j->rarg,
416  rightrelids,
417  NULL, NULL);
418  break;
419  case JOIN_FULL:
420  /* can't do anything with full-join quals */
421  break;
422  case JOIN_RIGHT:
423  j->quals = pull_up_sublinks_qual_recurse(root, j->quals,
424  &j->larg,
425  leftrelids,
426  NULL, NULL);
427  break;
428  default:
429  elog(ERROR, "unrecognized join type: %d",
430  (int) j->jointype);
431  break;
432  }
433 
434  /*
435  * Although we could include the pulled-up subqueries in the returned
436  * relids, there's no need since upper quals couldn't refer to their
437  * outputs anyway. But we *do* need to include the join's own rtindex
438  * because we haven't yet collapsed join alias variables, so upper
439  * levels would mistakenly think they couldn't use references to this
440  * join.
441  */
442  *relids = bms_join(leftrelids, rightrelids);
443  if (j->rtindex)
444  *relids = bms_add_member(*relids, j->rtindex);
445  jtnode = jtlink;
446  }
447  else
448  elog(ERROR, "unrecognized node type: %d",
449  (int) nodeTag(jtnode));
450  return jtnode;
451 }
452 
453 /*
454  * Recurse through top-level qual nodes for pull_up_sublinks()
455  *
456  * jtlink1 points to the link in the jointree where any new JoinExprs should
457  * be inserted if they reference available_rels1 (i.e., available_rels1
458  * denotes the relations present underneath jtlink1). Optionally, jtlink2 can
459  * point to a second link where new JoinExprs should be inserted if they
460  * reference available_rels2 (pass NULL for both those arguments if not used).
461  * Note that SubLinks referencing both sets of variables cannot be optimized.
462  * If we find multiple pull-up-able SubLinks, they'll get stacked onto jtlink1
463  * and/or jtlink2 in the order we encounter them. We rely on subsequent
464  * optimization to rearrange the stack if appropriate.
465  *
466  * Returns the replacement qual node, or NULL if the qual should be removed.
467  */
468 static Node *
470  Node **jtlink1, Relids available_rels1,
471  Node **jtlink2, Relids available_rels2)
472 {
473  if (node == NULL)
474  return NULL;
475  if (IsA(node, SubLink))
476  {
477  SubLink *sublink = (SubLink *) node;
478  JoinExpr *j;
479  Relids child_rels;
480 
481  /* Is it a convertible ANY or EXISTS clause? */
482  if (sublink->subLinkType == ANY_SUBLINK)
483  {
484  if ((j = convert_ANY_sublink_to_join(root, sublink,
485  available_rels1)) != NULL)
486  {
487  /* Yes; insert the new join node into the join tree */
488  j->larg = *jtlink1;
489  *jtlink1 = (Node *) j;
490  /* Recursively process pulled-up jointree nodes */
492  j->rarg,
493  &child_rels);
494 
495  /*
496  * Now recursively process the pulled-up quals. Any inserted
497  * joins can get stacked onto either j->larg or j->rarg,
498  * depending on which rels they reference.
499  */
500  j->quals = pull_up_sublinks_qual_recurse(root,
501  j->quals,
502  &j->larg,
503  available_rels1,
504  &j->rarg,
505  child_rels);
506  /* Return NULL representing constant TRUE */
507  return NULL;
508  }
509  if (available_rels2 != NULL &&
510  (j = convert_ANY_sublink_to_join(root, sublink,
511  available_rels2)) != NULL)
512  {
513  /* Yes; insert the new join node into the join tree */
514  j->larg = *jtlink2;
515  *jtlink2 = (Node *) j;
516  /* Recursively process pulled-up jointree nodes */
518  j->rarg,
519  &child_rels);
520 
521  /*
522  * Now recursively process the pulled-up quals. Any inserted
523  * joins can get stacked onto either j->larg or j->rarg,
524  * depending on which rels they reference.
525  */
526  j->quals = pull_up_sublinks_qual_recurse(root,
527  j->quals,
528  &j->larg,
529  available_rels2,
530  &j->rarg,
531  child_rels);
532  /* Return NULL representing constant TRUE */
533  return NULL;
534  }
535  }
536  else if (sublink->subLinkType == EXISTS_SUBLINK)
537  {
538  if ((j = convert_EXISTS_sublink_to_join(root, sublink, false,
539  available_rels1)) != NULL)
540  {
541  /* Yes; insert the new join node into the join tree */
542  j->larg = *jtlink1;
543  *jtlink1 = (Node *) j;
544  /* Recursively process pulled-up jointree nodes */
546  j->rarg,
547  &child_rels);
548 
549  /*
550  * Now recursively process the pulled-up quals. Any inserted
551  * joins can get stacked onto either j->larg or j->rarg,
552  * depending on which rels they reference.
553  */
554  j->quals = pull_up_sublinks_qual_recurse(root,
555  j->quals,
556  &j->larg,
557  available_rels1,
558  &j->rarg,
559  child_rels);
560  /* Return NULL representing constant TRUE */
561  return NULL;
562  }
563  if (available_rels2 != NULL &&
564  (j = convert_EXISTS_sublink_to_join(root, sublink, false,
565  available_rels2)) != NULL)
566  {
567  /* Yes; insert the new join node into the join tree */
568  j->larg = *jtlink2;
569  *jtlink2 = (Node *) j;
570  /* Recursively process pulled-up jointree nodes */
572  j->rarg,
573  &child_rels);
574 
575  /*
576  * Now recursively process the pulled-up quals. Any inserted
577  * joins can get stacked onto either j->larg or j->rarg,
578  * depending on which rels they reference.
579  */
580  j->quals = pull_up_sublinks_qual_recurse(root,
581  j->quals,
582  &j->larg,
583  available_rels2,
584  &j->rarg,
585  child_rels);
586  /* Return NULL representing constant TRUE */
587  return NULL;
588  }
589  }
590  /* Else return it unmodified */
591  return node;
592  }
593  if (is_notclause(node))
594  {
595  /* If the immediate argument of NOT is EXISTS, try to convert */
596  SubLink *sublink = (SubLink *) get_notclausearg((Expr *) node);
597  JoinExpr *j;
598  Relids child_rels;
599 
600  if (sublink && IsA(sublink, SubLink))
601  {
602  if (sublink->subLinkType == EXISTS_SUBLINK)
603  {
604  if ((j = convert_EXISTS_sublink_to_join(root, sublink, true,
605  available_rels1)) != NULL)
606  {
607  /* Yes; insert the new join node into the join tree */
608  j->larg = *jtlink1;
609  *jtlink1 = (Node *) j;
610  /* Recursively process pulled-up jointree nodes */
612  j->rarg,
613  &child_rels);
614 
615  /*
616  * Now recursively process the pulled-up quals. Because
617  * we are underneath a NOT, we can't pull up sublinks that
618  * reference the left-hand stuff, but it's still okay to
619  * pull up sublinks referencing j->rarg.
620  */
621  j->quals = pull_up_sublinks_qual_recurse(root,
622  j->quals,
623  &j->rarg,
624  child_rels,
625  NULL, NULL);
626  /* Return NULL representing constant TRUE */
627  return NULL;
628  }
629  if (available_rels2 != NULL &&
630  (j = convert_EXISTS_sublink_to_join(root, sublink, true,
631  available_rels2)) != NULL)
632  {
633  /* Yes; insert the new join node into the join tree */
634  j->larg = *jtlink2;
635  *jtlink2 = (Node *) j;
636  /* Recursively process pulled-up jointree nodes */
638  j->rarg,
639  &child_rels);
640 
641  /*
642  * Now recursively process the pulled-up quals. Because
643  * we are underneath a NOT, we can't pull up sublinks that
644  * reference the left-hand stuff, but it's still okay to
645  * pull up sublinks referencing j->rarg.
646  */
647  j->quals = pull_up_sublinks_qual_recurse(root,
648  j->quals,
649  &j->rarg,
650  child_rels,
651  NULL, NULL);
652  /* Return NULL representing constant TRUE */
653  return NULL;
654  }
655  }
656  }
657  /* Else return it unmodified */
658  return node;
659  }
660  if (is_andclause(node))
661  {
662  /* Recurse into AND clause */
663  List *newclauses = NIL;
664  ListCell *l;
665 
666  foreach(l, ((BoolExpr *) node)->args)
667  {
668  Node *oldclause = (Node *) lfirst(l);
669  Node *newclause;
670 
671  newclause = pull_up_sublinks_qual_recurse(root,
672  oldclause,
673  jtlink1,
674  available_rels1,
675  jtlink2,
676  available_rels2);
677  if (newclause)
678  newclauses = lappend(newclauses, newclause);
679  }
680  /* We might have got back fewer clauses than we started with */
681  if (newclauses == NIL)
682  return NULL;
683  else if (list_length(newclauses) == 1)
684  return (Node *) linitial(newclauses);
685  else
686  return (Node *) make_andclause(newclauses);
687  }
688  /* Stop if not an AND */
689  return node;
690 }
691 
692 /*
693  * preprocess_function_rtes
694  * Constant-simplify any FUNCTION RTEs in the FROM clause, and then
695  * attempt to "inline" any that are set-returning functions.
696  *
697  * If an RTE_FUNCTION rtable entry invokes a set-returning function that
698  * contains just a simple SELECT, we can convert the rtable entry to an
699  * RTE_SUBQUERY entry exposing the SELECT directly. This is especially
700  * useful if the subquery can then be "pulled up" for further optimization,
701  * but we do it even if not, to reduce executor overhead.
702  *
703  * This has to be done before we have started to do any optimization of
704  * subqueries, else any such steps wouldn't get applied to subqueries
705  * obtained via inlining. However, we do it after pull_up_sublinks
706  * so that we can inline any functions used in SubLink subselects.
707  *
708  * The reason for applying const-simplification at this stage is that
709  * (a) we'd need to do it anyway to inline a SRF, and (b) by doing it now,
710  * we can be sure that pull_up_constant_function() will see constants
711  * if there are constants to be seen. This approach also guarantees
712  * that every FUNCTION RTE has been const-simplified, allowing planner.c's
713  * preprocess_expression() to skip doing it again.
714  *
715  * Like most of the planner, this feels free to scribble on its input data
716  * structure.
717  */
718 void
720 {
721  ListCell *rt;
722 
723  foreach(rt, root->parse->rtable)
724  {
725  RangeTblEntry *rte = (RangeTblEntry *) lfirst(rt);
726 
727  if (rte->rtekind == RTE_FUNCTION)
728  {
729  Query *funcquery;
730 
731  /* Apply const-simplification */
732  rte->functions = (List *)
733  eval_const_expressions(root, (Node *) rte->functions);
734 
735  /* Check safety of expansion, and expand if possible */
736  funcquery = inline_set_returning_function(root, rte);
737  if (funcquery)
738  {
739  /* Successful expansion, convert the RTE to a subquery */
740  rte->rtekind = RTE_SUBQUERY;
741  rte->subquery = funcquery;
742  rte->security_barrier = false;
743  /* Clear fields that should not be set in a subquery RTE */
744  rte->functions = NIL;
745  rte->funcordinality = false;
746  }
747  }
748  }
749 }
750 
751 /*
752  * pull_up_subqueries
753  * Look for subqueries in the rangetable that can be pulled up into
754  * the parent query. If the subquery has no special features like
755  * grouping/aggregation then we can merge it into the parent's jointree.
756  * Also, subqueries that are simple UNION ALL structures can be
757  * converted into "append relations".
758  */
759 void
761 {
762  /* Top level of jointree must always be a FromExpr */
763  Assert(IsA(root->parse->jointree, FromExpr));
764  /* Recursion starts with no containing join nor appendrel */
765  root->parse->jointree = (FromExpr *)
767  NULL, NULL, NULL);
768  /* We should still have a FromExpr */
769  Assert(IsA(root->parse->jointree, FromExpr));
770 }
771 
772 /*
773  * pull_up_subqueries_recurse
774  * Recursive guts of pull_up_subqueries.
775  *
776  * This recursively processes the jointree and returns a modified jointree.
777  *
778  * If this jointree node is within either side of an outer join, then
779  * lowest_outer_join references the lowest such JoinExpr node; otherwise
780  * it is NULL. We use this to constrain the effects of LATERAL subqueries.
781  *
782  * If this jointree node is within the nullable side of an outer join, then
783  * lowest_nulling_outer_join references the lowest such JoinExpr node;
784  * otherwise it is NULL. This forces use of the PlaceHolderVar mechanism for
785  * references to non-nullable targetlist items, but only for references above
786  * that join.
787  *
788  * If we are looking at a member subquery of an append relation,
789  * containing_appendrel describes that relation; else it is NULL.
790  * This forces use of the PlaceHolderVar mechanism for all non-Var targetlist
791  * items, and puts some additional restrictions on what can be pulled up.
792  *
793  * A tricky aspect of this code is that if we pull up a subquery we have
794  * to replace Vars that reference the subquery's outputs throughout the
795  * parent query, including quals attached to jointree nodes above the one
796  * we are currently processing! We handle this by being careful to maintain
797  * validity of the jointree structure while recursing, in the following sense:
798  * whenever we recurse, all qual expressions in the tree must be reachable
799  * from the top level, in case the recursive call needs to modify them.
800  *
801  * Notice also that we can't turn pullup_replace_vars loose on the whole
802  * jointree, because it'd return a mutated copy of the tree; we have to
803  * invoke it just on the quals, instead. This behavior is what makes it
804  * reasonable to pass lowest_outer_join and lowest_nulling_outer_join as
805  * pointers rather than some more-indirect way of identifying the lowest
806  * OJs. Likewise, we don't replace append_rel_list members but only their
807  * substructure, so the containing_appendrel reference is safe to use.
808  */
809 static Node *
811  JoinExpr *lowest_outer_join,
812  JoinExpr *lowest_nulling_outer_join,
813  AppendRelInfo *containing_appendrel)
814 {
815  Assert(jtnode != NULL);
816  if (IsA(jtnode, RangeTblRef))
817  {
818  int varno = ((RangeTblRef *) jtnode)->rtindex;
819  RangeTblEntry *rte = rt_fetch(varno, root->parse->rtable);
820 
821  /*
822  * Is this a subquery RTE, and if so, is the subquery simple enough to
823  * pull up?
824  *
825  * If we are looking at an append-relation member, we can't pull it up
826  * unless is_safe_append_member says so.
827  */
828  if (rte->rtekind == RTE_SUBQUERY &&
829  is_simple_subquery(root, rte->subquery, rte, lowest_outer_join) &&
830  (containing_appendrel == NULL ||
832  return pull_up_simple_subquery(root, jtnode, rte,
833  lowest_outer_join,
834  lowest_nulling_outer_join,
835  containing_appendrel);
836 
837  /*
838  * Alternatively, is it a simple UNION ALL subquery? If so, flatten
839  * into an "append relation".
840  *
841  * It's safe to do this regardless of whether this query is itself an
842  * appendrel member. (If you're thinking we should try to flatten the
843  * two levels of appendrel together, you're right; but we handle that
844  * in set_append_rel_pathlist, not here.)
845  */
846  if (rte->rtekind == RTE_SUBQUERY &&
848  return pull_up_simple_union_all(root, jtnode, rte);
849 
850  /*
851  * Or perhaps it's a simple VALUES RTE?
852  *
853  * We don't allow VALUES pullup below an outer join nor into an
854  * appendrel (such cases are impossible anyway at the moment).
855  */
856  if (rte->rtekind == RTE_VALUES &&
857  lowest_outer_join == NULL &&
858  containing_appendrel == NULL &&
859  is_simple_values(root, rte))
860  return pull_up_simple_values(root, jtnode, rte);
861 
862  /*
863  * Or perhaps it's a FUNCTION RTE that we could inline?
864  */
865  if (rte->rtekind == RTE_FUNCTION)
866  return pull_up_constant_function(root, jtnode, rte,
867  lowest_nulling_outer_join,
868  containing_appendrel);
869 
870  /* Otherwise, do nothing at this node. */
871  }
872  else if (IsA(jtnode, FromExpr))
873  {
874  FromExpr *f = (FromExpr *) jtnode;
875  ListCell *l;
876 
877  Assert(containing_appendrel == NULL);
878  /* Recursively transform all the child nodes */
879  foreach(l, f->fromlist)
880  {
882  lowest_outer_join,
883  lowest_nulling_outer_join,
884  NULL);
885  }
886  }
887  else if (IsA(jtnode, JoinExpr))
888  {
889  JoinExpr *j = (JoinExpr *) jtnode;
890 
891  Assert(containing_appendrel == NULL);
892  /* Recurse, being careful to tell myself when inside outer join */
893  switch (j->jointype)
894  {
895  case JOIN_INNER:
896  j->larg = pull_up_subqueries_recurse(root, j->larg,
897  lowest_outer_join,
898  lowest_nulling_outer_join,
899  NULL);
900  j->rarg = pull_up_subqueries_recurse(root, j->rarg,
901  lowest_outer_join,
902  lowest_nulling_outer_join,
903  NULL);
904  break;
905  case JOIN_LEFT:
906  case JOIN_SEMI:
907  case JOIN_ANTI:
908  j->larg = pull_up_subqueries_recurse(root, j->larg,
909  j,
910  lowest_nulling_outer_join,
911  NULL);
912  j->rarg = pull_up_subqueries_recurse(root, j->rarg,
913  j,
914  j,
915  NULL);
916  break;
917  case JOIN_FULL:
918  j->larg = pull_up_subqueries_recurse(root, j->larg,
919  j,
920  j,
921  NULL);
922  j->rarg = pull_up_subqueries_recurse(root, j->rarg,
923  j,
924  j,
925  NULL);
926  break;
927  case JOIN_RIGHT:
928  j->larg = pull_up_subqueries_recurse(root, j->larg,
929  j,
930  j,
931  NULL);
932  j->rarg = pull_up_subqueries_recurse(root, j->rarg,
933  j,
934  lowest_nulling_outer_join,
935  NULL);
936  break;
937  default:
938  elog(ERROR, "unrecognized join type: %d",
939  (int) j->jointype);
940  break;
941  }
942  }
943  else
944  elog(ERROR, "unrecognized node type: %d",
945  (int) nodeTag(jtnode));
946  return jtnode;
947 }
948 
949 /*
950  * pull_up_simple_subquery
951  * Attempt to pull up a single simple subquery.
952  *
953  * jtnode is a RangeTblRef that has been tentatively identified as a simple
954  * subquery by pull_up_subqueries. We return the replacement jointree node,
955  * or jtnode itself if we determine that the subquery can't be pulled up
956  * after all.
957  *
958  * rte is the RangeTblEntry referenced by jtnode. Remaining parameters are
959  * as for pull_up_subqueries_recurse.
960  */
961 static Node *
963  JoinExpr *lowest_outer_join,
964  JoinExpr *lowest_nulling_outer_join,
965  AppendRelInfo *containing_appendrel)
966 {
967  Query *parse = root->parse;
968  int varno = ((RangeTblRef *) jtnode)->rtindex;
969  Query *subquery;
970  PlannerInfo *subroot;
971  int rtoffset;
972  pullup_replace_vars_context rvcontext;
973  ListCell *lc;
974 
975  /*
976  * Make a modifiable copy of the subquery to hack on, so that the RTE will
977  * be left unchanged in case we decide below that we can't pull it up
978  * after all.
979  */
980  subquery = copyObject(rte->subquery);
981 
982  /*
983  * Create a PlannerInfo data structure for this subquery.
984  *
985  * NOTE: the next few steps should match the first processing in
986  * subquery_planner(). Can we refactor to avoid code duplication, or
987  * would that just make things uglier?
988  */
989  subroot = makeNode(PlannerInfo);
990  subroot->parse = subquery;
991  subroot->glob = root->glob;
992  subroot->query_level = root->query_level;
993  subroot->parent_root = root->parent_root;
994  subroot->plan_params = NIL;
995  subroot->outer_params = NULL;
997  subroot->init_plans = NIL;
998  subroot->cte_plan_ids = NIL;
999  subroot->multiexpr_params = NIL;
1000  subroot->eq_classes = NIL;
1001  subroot->ec_merging_done = false;
1002  subroot->all_result_relids = NULL;
1003  subroot->leaf_result_relids = NULL;
1004  subroot->append_rel_list = NIL;
1005  subroot->row_identity_vars = NIL;
1006  subroot->rowMarks = NIL;
1007  memset(subroot->upper_rels, 0, sizeof(subroot->upper_rels));
1008  memset(subroot->upper_targets, 0, sizeof(subroot->upper_targets));
1009  subroot->processed_tlist = NIL;
1010  subroot->update_colnos = NIL;
1011  subroot->grouping_map = NULL;
1012  subroot->minmax_aggs = NIL;
1013  subroot->qual_security_level = 0;
1014  subroot->hasRecursion = false;
1015  subroot->wt_param_id = -1;
1016  subroot->non_recursive_path = NULL;
1017 
1018  /* No CTEs to worry about */
1019  Assert(subquery->cteList == NIL);
1020 
1021  /*
1022  * If the FROM clause is empty, replace it with a dummy RTE_RESULT RTE, so
1023  * that we don't need so many special cases to deal with that situation.
1024  */
1025  replace_empty_jointree(subquery);
1026 
1027  /*
1028  * Pull up any SubLinks within the subquery's quals, so that we don't
1029  * leave unoptimized SubLinks behind.
1030  */
1031  if (subquery->hasSubLinks)
1032  pull_up_sublinks(subroot);
1033 
1034  /*
1035  * Similarly, preprocess its function RTEs to inline any set-returning
1036  * functions in its rangetable.
1037  */
1038  preprocess_function_rtes(subroot);
1039 
1040  /*
1041  * Recursively pull up the subquery's subqueries, so that
1042  * pull_up_subqueries' processing is complete for its jointree and
1043  * rangetable.
1044  *
1045  * Note: it's okay that the subquery's recursion starts with NULL for
1046  * containing-join info, even if we are within an outer join in the upper
1047  * query; the lower query starts with a clean slate for outer-join
1048  * semantics. Likewise, we needn't pass down appendrel state.
1049  */
1050  pull_up_subqueries(subroot);
1051 
1052  /*
1053  * Now we must recheck whether the subquery is still simple enough to pull
1054  * up. If not, abandon processing it.
1055  *
1056  * We don't really need to recheck all the conditions involved, but it's
1057  * easier just to keep this "if" looking the same as the one in
1058  * pull_up_subqueries_recurse.
1059  */
1060  if (is_simple_subquery(root, subquery, rte, lowest_outer_join) &&
1061  (containing_appendrel == NULL || is_safe_append_member(subquery)))
1062  {
1063  /* good to go */
1064  }
1065  else
1066  {
1067  /*
1068  * Give up, return unmodified RangeTblRef.
1069  *
1070  * Note: The work we just did will be redone when the subquery gets
1071  * planned on its own. Perhaps we could avoid that by storing the
1072  * modified subquery back into the rangetable, but I'm not gonna risk
1073  * it now.
1074  */
1075  return jtnode;
1076  }
1077 
1078  /*
1079  * We must flatten any join alias Vars in the subquery's targetlist,
1080  * because pulling up the subquery's subqueries might have changed their
1081  * expansions into arbitrary expressions, which could affect
1082  * pullup_replace_vars' decisions about whether PlaceHolderVar wrappers
1083  * are needed for tlist entries. (Likely it'd be better to do
1084  * flatten_join_alias_vars on the whole query tree at some earlier stage,
1085  * maybe even in the rewriter; but for now let's just fix this case here.)
1086  */
1087  subquery->targetList = (List *)
1088  flatten_join_alias_vars(subroot->parse, (Node *) subquery->targetList);
1089 
1090  /*
1091  * Adjust level-0 varnos in subquery so that we can append its rangetable
1092  * to upper query's. We have to fix the subquery's append_rel_list as
1093  * well.
1094  */
1095  rtoffset = list_length(parse->rtable);
1096  OffsetVarNodes((Node *) subquery, rtoffset, 0);
1097  OffsetVarNodes((Node *) subroot->append_rel_list, rtoffset, 0);
1098 
1099  /*
1100  * Upper-level vars in subquery are now one level closer to their parent
1101  * than before.
1102  */
1103  IncrementVarSublevelsUp((Node *) subquery, -1, 1);
1104  IncrementVarSublevelsUp((Node *) subroot->append_rel_list, -1, 1);
1105 
1106  /*
1107  * The subquery's targetlist items are now in the appropriate form to
1108  * insert into the top query, except that we may need to wrap them in
1109  * PlaceHolderVars. Set up required context data for pullup_replace_vars.
1110  */
1111  rvcontext.root = root;
1112  rvcontext.targetlist = subquery->targetList;
1113  rvcontext.target_rte = rte;
1114  if (rte->lateral)
1115  rvcontext.relids = get_relids_in_jointree((Node *) subquery->jointree,
1116  true);
1117  else /* won't need relids */
1118  rvcontext.relids = NULL;
1119  rvcontext.outer_hasSubLinks = &parse->hasSubLinks;
1120  rvcontext.varno = varno;
1121  /* these flags will be set below, if needed */
1122  rvcontext.need_phvs = false;
1123  rvcontext.wrap_non_vars = false;
1124  /* initialize cache array with indexes 0 .. length(tlist) */
1125  rvcontext.rv_cache = palloc0((list_length(subquery->targetList) + 1) *
1126  sizeof(Node *));
1127 
1128  /*
1129  * If we are under an outer join then non-nullable items and lateral
1130  * references may have to be turned into PlaceHolderVars.
1131  */
1132  if (lowest_nulling_outer_join != NULL)
1133  rvcontext.need_phvs = true;
1134 
1135  /*
1136  * If we are dealing with an appendrel member then anything that's not a
1137  * simple Var has to be turned into a PlaceHolderVar. We force this to
1138  * ensure that what we pull up doesn't get merged into a surrounding
1139  * expression during later processing and then fail to match the
1140  * expression actually available from the appendrel.
1141  */
1142  if (containing_appendrel != NULL)
1143  {
1144  rvcontext.need_phvs = true;
1145  rvcontext.wrap_non_vars = true;
1146  }
1147 
1148  /*
1149  * If the parent query uses grouping sets, we need a PlaceHolderVar for
1150  * anything that's not a simple Var. Again, this ensures that expressions
1151  * retain their separate identity so that they will match grouping set
1152  * columns when appropriate. (It'd be sufficient to wrap values used in
1153  * grouping set columns, and do so only in non-aggregated portions of the
1154  * tlist and havingQual, but that would require a lot of infrastructure
1155  * that pullup_replace_vars hasn't currently got.)
1156  */
1157  if (parse->groupingSets)
1158  {
1159  rvcontext.need_phvs = true;
1160  rvcontext.wrap_non_vars = true;
1161  }
1162 
1163  /*
1164  * Replace all of the top query's references to the subquery's outputs
1165  * with copies of the adjusted subtlist items, being careful not to
1166  * replace any of the jointree structure.
1167  */
1168  perform_pullup_replace_vars(root, &rvcontext,
1169  lowest_nulling_outer_join,
1170  containing_appendrel);
1171 
1172  /*
1173  * If the subquery had a LATERAL marker, propagate that to any of its
1174  * child RTEs that could possibly now contain lateral cross-references.
1175  * The children might or might not contain any actual lateral
1176  * cross-references, but we have to mark the pulled-up child RTEs so that
1177  * later planner stages will check for such.
1178  */
1179  if (rte->lateral)
1180  {
1181  foreach(lc, subquery->rtable)
1182  {
1183  RangeTblEntry *child_rte = (RangeTblEntry *) lfirst(lc);
1184 
1185  switch (child_rte->rtekind)
1186  {
1187  case RTE_RELATION:
1188  if (child_rte->tablesample)
1189  child_rte->lateral = true;
1190  break;
1191  case RTE_SUBQUERY:
1192  case RTE_FUNCTION:
1193  case RTE_VALUES:
1194  case RTE_TABLEFUNC:
1195  child_rte->lateral = true;
1196  break;
1197  case RTE_JOIN:
1198  case RTE_CTE:
1199  case RTE_NAMEDTUPLESTORE:
1200  case RTE_RESULT:
1201  /* these can't contain any lateral references */
1202  break;
1203  }
1204  }
1205  }
1206 
1207  /*
1208  * Now append the adjusted rtable entries to upper query. (We hold off
1209  * until after fixing the upper rtable entries; no point in running that
1210  * code on the subquery ones too.)
1211  */
1212  parse->rtable = list_concat(parse->rtable, subquery->rtable);
1213 
1214  /*
1215  * Pull up any FOR UPDATE/SHARE markers, too. (OffsetVarNodes already
1216  * adjusted the marker rtindexes, so just concat the lists.)
1217  */
1218  parse->rowMarks = list_concat(parse->rowMarks, subquery->rowMarks);
1219 
1220  /*
1221  * We also have to fix the relid sets of any PlaceHolderVar nodes in the
1222  * parent query. (This could perhaps be done by pullup_replace_vars(),
1223  * but it seems cleaner to use two passes.) Note in particular that any
1224  * PlaceHolderVar nodes just created by pullup_replace_vars() will be
1225  * adjusted, so having created them with the subquery's varno is correct.
1226  *
1227  * Likewise, relids appearing in AppendRelInfo nodes have to be fixed. We
1228  * already checked that this won't require introducing multiple subrelids
1229  * into the single-slot AppendRelInfo structs.
1230  */
1231  if (parse->hasSubLinks || root->glob->lastPHId != 0 ||
1232  root->append_rel_list)
1233  {
1234  Relids subrelids;
1235 
1236  subrelids = get_relids_in_jointree((Node *) subquery->jointree, false);
1237  substitute_phv_relids((Node *) parse, varno, subrelids);
1238  fix_append_rel_relids(root->append_rel_list, varno, subrelids);
1239  }
1240 
1241  /*
1242  * And now add subquery's AppendRelInfos to our list.
1243  */
1245  subroot->append_rel_list);
1246 
1247  /*
1248  * We don't have to do the equivalent bookkeeping for outer-join info,
1249  * because that hasn't been set up yet. placeholder_list likewise.
1250  */
1251  Assert(root->join_info_list == NIL);
1252  Assert(subroot->join_info_list == NIL);
1253  Assert(root->placeholder_list == NIL);
1254  Assert(subroot->placeholder_list == NIL);
1255 
1256  /*
1257  * We no longer need the RTE's copy of the subquery's query tree. Getting
1258  * rid of it saves nothing in particular so far as this level of query is
1259  * concerned; but if this query level is in turn pulled up into a parent,
1260  * we'd waste cycles copying the now-unused query tree.
1261  */
1262  rte->subquery = NULL;
1263 
1264  /*
1265  * Miscellaneous housekeeping.
1266  *
1267  * Although replace_rte_variables() faithfully updated parse->hasSubLinks
1268  * if it copied any SubLinks out of the subquery's targetlist, we still
1269  * could have SubLinks added to the query in the expressions of FUNCTION
1270  * and VALUES RTEs copied up from the subquery. So it's necessary to copy
1271  * subquery->hasSubLinks anyway. Perhaps this can be improved someday.
1272  */
1273  parse->hasSubLinks |= subquery->hasSubLinks;
1274 
1275  /* If subquery had any RLS conditions, now main query does too */
1276  parse->hasRowSecurity |= subquery->hasRowSecurity;
1277 
1278  /*
1279  * subquery won't be pulled up if it hasAggs, hasWindowFuncs, or
1280  * hasTargetSRFs, so no work needed on those flags
1281  */
1282 
1283  /*
1284  * Return the adjusted subquery jointree to replace the RangeTblRef entry
1285  * in parent's jointree; or, if the FromExpr is degenerate, just return
1286  * its single member.
1287  */
1288  Assert(IsA(subquery->jointree, FromExpr));
1289  Assert(subquery->jointree->fromlist != NIL);
1290  if (subquery->jointree->quals == NULL &&
1291  list_length(subquery->jointree->fromlist) == 1)
1292  return (Node *) linitial(subquery->jointree->fromlist);
1293 
1294  return (Node *) subquery->jointree;
1295 }
1296 
1297 /*
1298  * pull_up_simple_union_all
1299  * Pull up a single simple UNION ALL subquery.
1300  *
1301  * jtnode is a RangeTblRef that has been identified as a simple UNION ALL
1302  * subquery by pull_up_subqueries. We pull up the leaf subqueries and
1303  * build an "append relation" for the union set. The result value is just
1304  * jtnode, since we don't actually need to change the query jointree.
1305  */
1306 static Node *
1308 {
1309  int varno = ((RangeTblRef *) jtnode)->rtindex;
1310  Query *subquery = rte->subquery;
1311  int rtoffset = list_length(root->parse->rtable);
1312  List *rtable;
1313 
1314  /*
1315  * Make a modifiable copy of the subquery's rtable, so we can adjust
1316  * upper-level Vars in it. There are no such Vars in the setOperations
1317  * tree proper, so fixing the rtable should be sufficient.
1318  */
1319  rtable = copyObject(subquery->rtable);
1320 
1321  /*
1322  * Upper-level vars in subquery are now one level closer to their parent
1323  * than before. We don't have to worry about offsetting varnos, though,
1324  * because the UNION leaf queries can't cross-reference each other.
1325  */
1326  IncrementVarSublevelsUp_rtable(rtable, -1, 1);
1327 
1328  /*
1329  * If the UNION ALL subquery had a LATERAL marker, propagate that to all
1330  * its children. The individual children might or might not contain any
1331  * actual lateral cross-references, but we have to mark the pulled-up
1332  * child RTEs so that later planner stages will check for such.
1333  */
1334  if (rte->lateral)
1335  {
1336  ListCell *rt;
1337 
1338  foreach(rt, rtable)
1339  {
1340  RangeTblEntry *child_rte = (RangeTblEntry *) lfirst(rt);
1341 
1342  Assert(child_rte->rtekind == RTE_SUBQUERY);
1343  child_rte->lateral = true;
1344  }
1345  }
1346 
1347  /*
1348  * Append child RTEs to parent rtable.
1349  */
1350  root->parse->rtable = list_concat(root->parse->rtable, rtable);
1351 
1352  /*
1353  * Recursively scan the subquery's setOperations tree and add
1354  * AppendRelInfo nodes for leaf subqueries to the parent's
1355  * append_rel_list. Also apply pull_up_subqueries to the leaf subqueries.
1356  */
1357  Assert(subquery->setOperations);
1358  pull_up_union_leaf_queries(subquery->setOperations, root, varno, subquery,
1359  rtoffset);
1360 
1361  /*
1362  * Mark the parent as an append relation.
1363  */
1364  rte->inh = true;
1365 
1366  return jtnode;
1367 }
1368 
1369 /*
1370  * pull_up_union_leaf_queries -- recursive guts of pull_up_simple_union_all
1371  *
1372  * Build an AppendRelInfo for each leaf query in the setop tree, and then
1373  * apply pull_up_subqueries to the leaf query.
1374  *
1375  * Note that setOpQuery is the Query containing the setOp node, whose tlist
1376  * contains references to all the setop output columns. When called from
1377  * pull_up_simple_union_all, this is *not* the same as root->parse, which is
1378  * the parent Query we are pulling up into.
1379  *
1380  * parentRTindex is the appendrel parent's index in root->parse->rtable.
1381  *
1382  * The child RTEs have already been copied to the parent. childRToffset
1383  * tells us where in the parent's range table they were copied. When called
1384  * from flatten_simple_union_all, childRToffset is 0 since the child RTEs
1385  * were already in root->parse->rtable and no RT index adjustment is needed.
1386  */
1387 static void
1388 pull_up_union_leaf_queries(Node *setOp, PlannerInfo *root, int parentRTindex,
1389  Query *setOpQuery, int childRToffset)
1390 {
1391  if (IsA(setOp, RangeTblRef))
1392  {
1393  RangeTblRef *rtr = (RangeTblRef *) setOp;
1394  int childRTindex;
1395  AppendRelInfo *appinfo;
1396 
1397  /*
1398  * Calculate the index in the parent's range table
1399  */
1400  childRTindex = childRToffset + rtr->rtindex;
1401 
1402  /*
1403  * Build a suitable AppendRelInfo, and attach to parent's list.
1404  */
1405  appinfo = makeNode(AppendRelInfo);
1406  appinfo->parent_relid = parentRTindex;
1407  appinfo->child_relid = childRTindex;
1408  appinfo->parent_reltype = InvalidOid;
1409  appinfo->child_reltype = InvalidOid;
1410  make_setop_translation_list(setOpQuery, childRTindex, appinfo);
1411  appinfo->parent_reloid = InvalidOid;
1412  root->append_rel_list = lappend(root->append_rel_list, appinfo);
1413 
1414  /*
1415  * Recursively apply pull_up_subqueries to the new child RTE. (We
1416  * must build the AppendRelInfo first, because this will modify it.)
1417  * Note that we can pass NULL for containing-join info even if we're
1418  * actually under an outer join, because the child's expressions
1419  * aren't going to propagate up to the join. Also, we ignore the
1420  * possibility that pull_up_subqueries_recurse() returns a different
1421  * jointree node than what we pass it; if it does, the important thing
1422  * is that it replaced the child relid in the AppendRelInfo node.
1423  */
1424  rtr = makeNode(RangeTblRef);
1425  rtr->rtindex = childRTindex;
1426  (void) pull_up_subqueries_recurse(root, (Node *) rtr,
1427  NULL, NULL, appinfo);
1428  }
1429  else if (IsA(setOp, SetOperationStmt))
1430  {
1431  SetOperationStmt *op = (SetOperationStmt *) setOp;
1432 
1433  /* Recurse to reach leaf queries */
1434  pull_up_union_leaf_queries(op->larg, root, parentRTindex, setOpQuery,
1435  childRToffset);
1436  pull_up_union_leaf_queries(op->rarg, root, parentRTindex, setOpQuery,
1437  childRToffset);
1438  }
1439  else
1440  {
1441  elog(ERROR, "unrecognized node type: %d",
1442  (int) nodeTag(setOp));
1443  }
1444 }
1445 
1446 /*
1447  * make_setop_translation_list
1448  * Build the list of translations from parent Vars to child Vars for
1449  * a UNION ALL member. (At this point it's just a simple list of
1450  * referencing Vars, but if we succeed in pulling up the member
1451  * subquery, the Vars will get replaced by pulled-up expressions.)
1452  * Also create the rather trivial reverse-translation array.
1453  */
1454 static void
1455 make_setop_translation_list(Query *query, int newvarno,
1456  AppendRelInfo *appinfo)
1457 {
1458  List *vars = NIL;
1459  AttrNumber *pcolnos;
1460  ListCell *l;
1461 
1462  /* Initialize reverse-translation array with all entries zero */
1463  /* (entries for resjunk columns will stay that way) */
1464  appinfo->num_child_cols = list_length(query->targetList);
1465  appinfo->parent_colnos = pcolnos =
1466  (AttrNumber *) palloc0(appinfo->num_child_cols * sizeof(AttrNumber));
1467 
1468  foreach(l, query->targetList)
1469  {
1470  TargetEntry *tle = (TargetEntry *) lfirst(l);
1471 
1472  if (tle->resjunk)
1473  continue;
1474 
1475  vars = lappend(vars, makeVarFromTargetEntry(newvarno, tle));
1476  pcolnos[tle->resno - 1] = tle->resno;
1477  }
1478 
1479  appinfo->translated_vars = vars;
1480 }
1481 
1482 /*
1483  * is_simple_subquery
1484  * Check a subquery in the range table to see if it's simple enough
1485  * to pull up into the parent query.
1486  *
1487  * rte is the RTE_SUBQUERY RangeTblEntry that contained the subquery.
1488  * (Note subquery is not necessarily equal to rte->subquery; it could be a
1489  * processed copy of that.)
1490  * lowest_outer_join is the lowest outer join above the subquery, or NULL.
1491  */
1492 static bool
1494  JoinExpr *lowest_outer_join)
1495 {
1496  /*
1497  * Let's just make sure it's a valid subselect ...
1498  */
1499  if (!IsA(subquery, Query) ||
1500  subquery->commandType != CMD_SELECT)
1501  elog(ERROR, "subquery is bogus");
1502 
1503  /*
1504  * Can't currently pull up a query with setops (unless it's simple UNION
1505  * ALL, which is handled by a different code path). Maybe after querytree
1506  * redesign...
1507  */
1508  if (subquery->setOperations)
1509  return false;
1510 
1511  /*
1512  * Can't pull up a subquery involving grouping, aggregation, SRFs,
1513  * sorting, limiting, or WITH. (XXX WITH could possibly be allowed later)
1514  *
1515  * We also don't pull up a subquery that has explicit FOR UPDATE/SHARE
1516  * clauses, because pullup would cause the locking to occur semantically
1517  * higher than it should. Implicit FOR UPDATE/SHARE is okay because in
1518  * that case the locking was originally declared in the upper query
1519  * anyway.
1520  */
1521  if (subquery->hasAggs ||
1522  subquery->hasWindowFuncs ||
1523  subquery->hasTargetSRFs ||
1524  subquery->groupClause ||
1525  subquery->groupingSets ||
1526  subquery->havingQual ||
1527  subquery->sortClause ||
1528  subquery->distinctClause ||
1529  subquery->limitOffset ||
1530  subquery->limitCount ||
1531  subquery->hasForUpdate ||
1532  subquery->cteList)
1533  return false;
1534 
1535  /*
1536  * Don't pull up if the RTE represents a security-barrier view; we
1537  * couldn't prevent information leakage once the RTE's Vars are scattered
1538  * about in the upper query.
1539  */
1540  if (rte->security_barrier)
1541  return false;
1542 
1543  /*
1544  * If the subquery is LATERAL, check for pullup restrictions from that.
1545  */
1546  if (rte->lateral)
1547  {
1548  bool restricted;
1549  Relids safe_upper_varnos;
1550 
1551  /*
1552  * The subquery's WHERE and JOIN/ON quals mustn't contain any lateral
1553  * references to rels outside a higher outer join (including the case
1554  * where the outer join is within the subquery itself). In such a
1555  * case, pulling up would result in a situation where we need to
1556  * postpone quals from below an outer join to above it, which is
1557  * probably completely wrong and in any case is a complication that
1558  * doesn't seem worth addressing at the moment.
1559  */
1560  if (lowest_outer_join != NULL)
1561  {
1562  restricted = true;
1563  safe_upper_varnos = get_relids_in_jointree((Node *) lowest_outer_join,
1564  true);
1565  }
1566  else
1567  {
1568  restricted = false;
1569  safe_upper_varnos = NULL; /* doesn't matter */
1570  }
1571 
1573  (Node *) subquery->jointree,
1574  restricted, safe_upper_varnos))
1575  return false;
1576 
1577  /*
1578  * If there's an outer join above the LATERAL subquery, also disallow
1579  * pullup if the subquery's targetlist has any references to rels
1580  * outside the outer join, since these might get pulled into quals
1581  * above the subquery (but in or below the outer join) and then lead
1582  * to qual-postponement issues similar to the case checked for above.
1583  * (We wouldn't need to prevent pullup if no such references appear in
1584  * outer-query quals, but we don't have enough info here to check
1585  * that. Also, maybe this restriction could be removed if we forced
1586  * such refs to be wrapped in PlaceHolderVars, even when they're below
1587  * the nearest outer join? But it's a pretty hokey usage, so not
1588  * clear this is worth sweating over.)
1589  */
1590  if (lowest_outer_join != NULL)
1591  {
1592  Relids lvarnos = pull_varnos_of_level(root,
1593  (Node *) subquery->targetList,
1594  1);
1595 
1596  if (!bms_is_subset(lvarnos, safe_upper_varnos))
1597  return false;
1598  }
1599  }
1600 
1601  /*
1602  * Don't pull up a subquery that has any volatile functions in its
1603  * targetlist. Otherwise we might introduce multiple evaluations of these
1604  * functions, if they get copied to multiple places in the upper query,
1605  * leading to surprising results. (Note: the PlaceHolderVar mechanism
1606  * doesn't quite guarantee single evaluation; else we could pull up anyway
1607  * and just wrap such items in PlaceHolderVars ...)
1608  */
1609  if (contain_volatile_functions((Node *) subquery->targetList))
1610  return false;
1611 
1612  return true;
1613 }
1614 
1615 /*
1616  * pull_up_simple_values
1617  * Pull up a single simple VALUES RTE.
1618  *
1619  * jtnode is a RangeTblRef that has been identified as a simple VALUES RTE
1620  * by pull_up_subqueries. We always return a RangeTblRef representing a
1621  * RESULT RTE to replace it (all failure cases should have been detected by
1622  * is_simple_values()). Actually, what we return is just jtnode, because
1623  * we replace the VALUES RTE in the rangetable with the RESULT RTE.
1624  *
1625  * rte is the RangeTblEntry referenced by jtnode. Because of the limited
1626  * possible usage of VALUES RTEs, we do not need the remaining parameters
1627  * of pull_up_subqueries_recurse.
1628  */
1629 static Node *
1631 {
1632  Query *parse = root->parse;
1633  int varno = ((RangeTblRef *) jtnode)->rtindex;
1634  List *values_list;
1635  List *tlist;
1636  AttrNumber attrno;
1637  pullup_replace_vars_context rvcontext;
1638  ListCell *lc;
1639 
1640  Assert(rte->rtekind == RTE_VALUES);
1641  Assert(list_length(rte->values_lists) == 1);
1642 
1643  /*
1644  * Need a modifiable copy of the VALUES list to hack on, just in case it's
1645  * multiply referenced.
1646  */
1647  values_list = copyObject(linitial(rte->values_lists));
1648 
1649  /*
1650  * The VALUES RTE can't contain any Vars of level zero, let alone any that
1651  * are join aliases, so no need to flatten join alias Vars.
1652  */
1653  Assert(!contain_vars_of_level((Node *) values_list, 0));
1654 
1655  /*
1656  * Set up required context data for pullup_replace_vars. In particular,
1657  * we have to make the VALUES list look like a subquery targetlist.
1658  */
1659  tlist = NIL;
1660  attrno = 1;
1661  foreach(lc, values_list)
1662  {
1663  tlist = lappend(tlist,
1664  makeTargetEntry((Expr *) lfirst(lc),
1665  attrno,
1666  NULL,
1667  false));
1668  attrno++;
1669  }
1670  rvcontext.root = root;
1671  rvcontext.targetlist = tlist;
1672  rvcontext.target_rte = rte;
1673  rvcontext.relids = NULL;
1674  rvcontext.outer_hasSubLinks = &parse->hasSubLinks;
1675  rvcontext.varno = varno;
1676  rvcontext.need_phvs = false;
1677  rvcontext.wrap_non_vars = false;
1678  /* initialize cache array with indexes 0 .. length(tlist) */
1679  rvcontext.rv_cache = palloc0((list_length(tlist) + 1) *
1680  sizeof(Node *));
1681 
1682  /*
1683  * Replace all of the top query's references to the RTE's outputs with
1684  * copies of the adjusted VALUES expressions, being careful not to replace
1685  * any of the jointree structure. We can assume there's no outer joins or
1686  * appendrels in the dummy Query that surrounds a VALUES RTE.
1687  */
1688  perform_pullup_replace_vars(root, &rvcontext, NULL, NULL);
1689 
1690  /*
1691  * There should be no appendrels to fix, nor any outer joins and hence no
1692  * PlaceHolderVars.
1693  */
1694  Assert(root->append_rel_list == NIL);
1695  Assert(root->join_info_list == NIL);
1696  Assert(root->placeholder_list == NIL);
1697 
1698  /*
1699  * Replace the VALUES RTE with a RESULT RTE. The VALUES RTE is the only
1700  * rtable entry in the current query level, so this is easy.
1701  */
1702  Assert(list_length(parse->rtable) == 1);
1703 
1704  /* Create suitable RTE */
1705  rte = makeNode(RangeTblEntry);
1706  rte->rtekind = RTE_RESULT;
1707  rte->eref = makeAlias("*RESULT*", NIL);
1708 
1709  /* Replace rangetable */
1710  parse->rtable = list_make1(rte);
1711 
1712  /* We could manufacture a new RangeTblRef, but the one we have is fine */
1713  Assert(varno == 1);
1714 
1715  return jtnode;
1716 }
1717 
1718 /*
1719  * is_simple_values
1720  * Check a VALUES RTE in the range table to see if it's simple enough
1721  * to pull up into the parent query.
1722  *
1723  * rte is the RTE_VALUES RangeTblEntry to check.
1724  */
1725 static bool
1727 {
1728  Assert(rte->rtekind == RTE_VALUES);
1729 
1730  /*
1731  * There must be exactly one VALUES list, else it's not semantically
1732  * correct to replace the VALUES RTE with a RESULT RTE, nor would we have
1733  * a unique set of expressions to substitute into the parent query.
1734  */
1735  if (list_length(rte->values_lists) != 1)
1736  return false;
1737 
1738  /*
1739  * Because VALUES can't appear under an outer join (or at least, we won't
1740  * try to pull it up if it does), we need not worry about LATERAL, nor
1741  * about validity of PHVs for the VALUES' outputs.
1742  */
1743 
1744  /*
1745  * Don't pull up a VALUES that contains any set-returning or volatile
1746  * functions. The considerations here are basically identical to the
1747  * restrictions on a pull-able subquery's targetlist.
1748  */
1749  if (expression_returns_set((Node *) rte->values_lists) ||
1751  return false;
1752 
1753  /*
1754  * Do not pull up a VALUES that's not the only RTE in its parent query.
1755  * This is actually the only case that the parser will generate at the
1756  * moment, and assuming this is true greatly simplifies
1757  * pull_up_simple_values().
1758  */
1759  if (list_length(root->parse->rtable) != 1 ||
1760  rte != (RangeTblEntry *) linitial(root->parse->rtable))
1761  return false;
1762 
1763  return true;
1764 }
1765 
1766 /*
1767  * pull_up_constant_function
1768  * Pull up an RTE_FUNCTION expression that was simplified to a constant.
1769  *
1770  * jtnode is a RangeTblRef that has been identified as a FUNCTION RTE by
1771  * pull_up_subqueries. If its expression is just a Const, hoist that value
1772  * up into the parent query, and replace the RTE_FUNCTION with RTE_RESULT.
1773  *
1774  * In principle we could pull up any immutable expression, but we don't.
1775  * That might result in multiple evaluations of the expression, which could
1776  * be costly if it's not just a Const. Also, the main value of this is
1777  * to let the constant participate in further const-folding, and of course
1778  * that won't happen for a non-Const.
1779  *
1780  * The pulled-up value might need to be wrapped in a PlaceHolderVar if the
1781  * RTE is below an outer join or is part of an appendrel; the extra
1782  * parameters show whether that's needed.
1783  */
1784 static Node *
1786  RangeTblEntry *rte,
1787  JoinExpr *lowest_nulling_outer_join,
1788  AppendRelInfo *containing_appendrel)
1789 {
1790  Query *parse = root->parse;
1791  RangeTblFunction *rtf;
1792  TypeFuncClass functypclass;
1793  Oid funcrettype;
1794  TupleDesc tupdesc;
1795  pullup_replace_vars_context rvcontext;
1796 
1797  /* Fail if the RTE has ORDINALITY - we don't implement that here. */
1798  if (rte->funcordinality)
1799  return jtnode;
1800 
1801  /* Fail if RTE isn't a single, simple Const expr */
1802  if (list_length(rte->functions) != 1)
1803  return jtnode;
1805  if (!IsA(rtf->funcexpr, Const))
1806  return jtnode;
1807 
1808  /*
1809  * If the function's result is not a scalar, we punt. In principle we
1810  * could break the composite constant value apart into per-column
1811  * constants, but for now it seems not worth the work.
1812  */
1813  if (rtf->funccolcount != 1)
1814  return jtnode; /* definitely composite */
1815 
1816  functypclass = get_expr_result_type(rtf->funcexpr,
1817  &funcrettype,
1818  &tupdesc);
1819  if (functypclass != TYPEFUNC_SCALAR)
1820  return jtnode; /* must be a one-column composite type */
1821 
1822  /* Create context for applying pullup_replace_vars */
1823  rvcontext.root = root;
1824  rvcontext.targetlist = list_make1(makeTargetEntry((Expr *) rtf->funcexpr,
1825  1, /* resno */
1826  NULL, /* resname */
1827  false)); /* resjunk */
1828  rvcontext.target_rte = rte;
1829 
1830  /*
1831  * Since this function was reduced to a Const, it doesn't contain any
1832  * lateral references, even if it's marked as LATERAL. This means we
1833  * don't need to fill relids.
1834  */
1835  rvcontext.relids = NULL;
1836 
1837  rvcontext.outer_hasSubLinks = &parse->hasSubLinks;
1838  rvcontext.varno = ((RangeTblRef *) jtnode)->rtindex;
1839  /* these flags will be set below, if needed */
1840  rvcontext.need_phvs = false;
1841  rvcontext.wrap_non_vars = false;
1842  /* initialize cache array with indexes 0 .. length(tlist) */
1843  rvcontext.rv_cache = palloc0((list_length(rvcontext.targetlist) + 1) *
1844  sizeof(Node *));
1845 
1846  /*
1847  * If we are under an outer join then non-nullable items and lateral
1848  * references may have to be turned into PlaceHolderVars.
1849  */
1850  if (lowest_nulling_outer_join != NULL)
1851  rvcontext.need_phvs = true;
1852 
1853  /*
1854  * If we are dealing with an appendrel member then anything that's not a
1855  * simple Var has to be turned into a PlaceHolderVar. (See comments in
1856  * pull_up_simple_subquery().)
1857  */
1858  if (containing_appendrel != NULL)
1859  {
1860  rvcontext.need_phvs = true;
1861  rvcontext.wrap_non_vars = true;
1862  }
1863 
1864  /*
1865  * If the parent query uses grouping sets, we need a PlaceHolderVar for
1866  * anything that's not a simple Var.
1867  */
1868  if (parse->groupingSets)
1869  {
1870  rvcontext.need_phvs = true;
1871  rvcontext.wrap_non_vars = true;
1872  }
1873 
1874  /*
1875  * Replace all of the top query's references to the RTE's output with
1876  * copies of the funcexpr, being careful not to replace any of the
1877  * jointree structure.
1878  */
1879  perform_pullup_replace_vars(root, &rvcontext,
1880  lowest_nulling_outer_join,
1881  containing_appendrel);
1882 
1883  /*
1884  * We don't need to bother with changing PlaceHolderVars in the parent
1885  * query. Their references to the RT index are still good for now, and
1886  * will get removed later if we're able to drop the RTE_RESULT.
1887  */
1888 
1889  /*
1890  * Convert the RTE to be RTE_RESULT type, signifying that we don't need to
1891  * scan it anymore, and zero out RTE_FUNCTION-specific fields. Also make
1892  * sure the RTE is not marked LATERAL, since elsewhere we don't expect
1893  * RTE_RESULTs to be LATERAL.
1894  */
1895  rte->rtekind = RTE_RESULT;
1896  rte->functions = NIL;
1897  rte->lateral = false;
1898 
1899  /*
1900  * We can reuse the RangeTblRef node.
1901  */
1902  return jtnode;
1903 }
1904 
1905 /*
1906  * is_simple_union_all
1907  * Check a subquery to see if it's a simple UNION ALL.
1908  *
1909  * We require all the setops to be UNION ALL (no mixing) and there can't be
1910  * any datatype coercions involved, ie, all the leaf queries must emit the
1911  * same datatypes.
1912  */
1913 static bool
1915 {
1916  SetOperationStmt *topop;
1917 
1918  /* Let's just make sure it's a valid subselect ... */
1919  if (!IsA(subquery, Query) ||
1920  subquery->commandType != CMD_SELECT)
1921  elog(ERROR, "subquery is bogus");
1922 
1923  /* Is it a set-operation query at all? */
1924  topop = castNode(SetOperationStmt, subquery->setOperations);
1925  if (!topop)
1926  return false;
1927 
1928  /* Can't handle ORDER BY, LIMIT/OFFSET, locking, or WITH */
1929  if (subquery->sortClause ||
1930  subquery->limitOffset ||
1931  subquery->limitCount ||
1932  subquery->rowMarks ||
1933  subquery->cteList)
1934  return false;
1935 
1936  /* Recursively check the tree of set operations */
1937  return is_simple_union_all_recurse((Node *) topop, subquery,
1938  topop->colTypes);
1939 }
1940 
1941 static bool
1942 is_simple_union_all_recurse(Node *setOp, Query *setOpQuery, List *colTypes)
1943 {
1944  if (IsA(setOp, RangeTblRef))
1945  {
1946  RangeTblRef *rtr = (RangeTblRef *) setOp;
1947  RangeTblEntry *rte = rt_fetch(rtr->rtindex, setOpQuery->rtable);
1948  Query *subquery = rte->subquery;
1949 
1950  Assert(subquery != NULL);
1951 
1952  /* Leaf nodes are OK if they match the toplevel column types */
1953  /* We don't have to compare typmods or collations here */
1954  return tlist_same_datatypes(subquery->targetList, colTypes, true);
1955  }
1956  else if (IsA(setOp, SetOperationStmt))
1957  {
1958  SetOperationStmt *op = (SetOperationStmt *) setOp;
1959 
1960  /* Must be UNION ALL */
1961  if (op->op != SETOP_UNION || !op->all)
1962  return false;
1963 
1964  /* Recurse to check inputs */
1965  return is_simple_union_all_recurse(op->larg, setOpQuery, colTypes) &&
1966  is_simple_union_all_recurse(op->rarg, setOpQuery, colTypes);
1967  }
1968  else
1969  {
1970  elog(ERROR, "unrecognized node type: %d",
1971  (int) nodeTag(setOp));
1972  return false; /* keep compiler quiet */
1973  }
1974 }
1975 
1976 /*
1977  * is_safe_append_member
1978  * Check a subquery that is a leaf of a UNION ALL appendrel to see if it's
1979  * safe to pull up.
1980  */
1981 static bool
1983 {
1984  FromExpr *jtnode;
1985 
1986  /*
1987  * It's only safe to pull up the child if its jointree contains exactly
1988  * one RTE, else the AppendRelInfo data structure breaks. The one base RTE
1989  * could be buried in several levels of FromExpr, however. Also, if the
1990  * child's jointree is completely empty, we can pull up because
1991  * pull_up_simple_subquery will insert a single RTE_RESULT RTE instead.
1992  *
1993  * Also, the child can't have any WHERE quals because there's no place to
1994  * put them in an appendrel. (This is a bit annoying...) If we didn't
1995  * need to check this, we'd just test whether get_relids_in_jointree()
1996  * yields a singleton set, to be more consistent with the coding of
1997  * fix_append_rel_relids().
1998  */
1999  jtnode = subquery->jointree;
2000  Assert(IsA(jtnode, FromExpr));
2001  /* Check the completely-empty case */
2002  if (jtnode->fromlist == NIL && jtnode->quals == NULL)
2003  return true;
2004  /* Check the more general case */
2005  while (IsA(jtnode, FromExpr))
2006  {
2007  if (jtnode->quals != NULL)
2008  return false;
2009  if (list_length(jtnode->fromlist) != 1)
2010  return false;
2011  jtnode = linitial(jtnode->fromlist);
2012  }
2013  if (!IsA(jtnode, RangeTblRef))
2014  return false;
2015 
2016  return true;
2017 }
2018 
2019 /*
2020  * jointree_contains_lateral_outer_refs
2021  * Check for disallowed lateral references in a jointree's quals
2022  *
2023  * If restricted is false, all level-1 Vars are allowed (but we still must
2024  * search the jointree, since it might contain outer joins below which there
2025  * will be restrictions). If restricted is true, return true when any qual
2026  * in the jointree contains level-1 Vars coming from outside the rels listed
2027  * in safe_upper_varnos.
2028  */
2029 static bool
2031  bool restricted,
2032  Relids safe_upper_varnos)
2033 {
2034  if (jtnode == NULL)
2035  return false;
2036  if (IsA(jtnode, RangeTblRef))
2037  return false;
2038  else if (IsA(jtnode, FromExpr))
2039  {
2040  FromExpr *f = (FromExpr *) jtnode;
2041  ListCell *l;
2042 
2043  /* First, recurse to check child joins */
2044  foreach(l, f->fromlist)
2045  {
2047  lfirst(l),
2048  restricted,
2049  safe_upper_varnos))
2050  return true;
2051  }
2052 
2053  /* Then check the top-level quals */
2054  if (restricted &&
2056  safe_upper_varnos))
2057  return true;
2058  }
2059  else if (IsA(jtnode, JoinExpr))
2060  {
2061  JoinExpr *j = (JoinExpr *) jtnode;
2062 
2063  /*
2064  * If this is an outer join, we mustn't allow any upper lateral
2065  * references in or below it.
2066  */
2067  if (j->jointype != JOIN_INNER)
2068  {
2069  restricted = true;
2070  safe_upper_varnos = NULL;
2071  }
2072 
2073  /* Check the child joins */
2075  j->larg,
2076  restricted,
2077  safe_upper_varnos))
2078  return true;
2080  j->rarg,
2081  restricted,
2082  safe_upper_varnos))
2083  return true;
2084 
2085  /* Check the JOIN's qual clauses */
2086  if (restricted &&
2087  !bms_is_subset(pull_varnos_of_level(root, j->quals, 1),
2088  safe_upper_varnos))
2089  return true;
2090  }
2091  else
2092  elog(ERROR, "unrecognized node type: %d",
2093  (int) nodeTag(jtnode));
2094  return false;
2095 }
2096 
2097 /*
2098  * Perform pullup_replace_vars everyplace it's needed in the query tree.
2099  *
2100  * Caller has already filled *rvcontext with data describing what to
2101  * substitute for Vars referencing the target subquery. In addition
2102  * we need the identity of the lowest outer join that can null the
2103  * target subquery, and its containing appendrel if any.
2104  */
2105 static void
2107  pullup_replace_vars_context *rvcontext,
2108  JoinExpr *lowest_nulling_outer_join,
2109  AppendRelInfo *containing_appendrel)
2110 {
2111  Query *parse = root->parse;
2112  ListCell *lc;
2113 
2114  /*
2115  * Replace all of the top query's references to the subquery's outputs
2116  * with copies of the adjusted subtlist items, being careful not to
2117  * replace any of the jointree structure. (This'd be a lot cleaner if we
2118  * could use query_tree_mutator.) We have to use PHVs in the targetList,
2119  * returningList, and havingQual, since those are certainly above any
2120  * outer join. replace_vars_in_jointree tracks its location in the
2121  * jointree and uses PHVs or not appropriately.
2122  */
2123  parse->targetList = (List *)
2124  pullup_replace_vars((Node *) parse->targetList, rvcontext);
2125  parse->returningList = (List *)
2126  pullup_replace_vars((Node *) parse->returningList, rvcontext);
2127  if (parse->onConflict)
2128  {
2129  parse->onConflict->onConflictSet = (List *)
2130  pullup_replace_vars((Node *) parse->onConflict->onConflictSet,
2131  rvcontext);
2132  parse->onConflict->onConflictWhere =
2133  pullup_replace_vars(parse->onConflict->onConflictWhere,
2134  rvcontext);
2135 
2136  /*
2137  * We assume ON CONFLICT's arbiterElems, arbiterWhere, exclRelTlist
2138  * can't contain any references to a subquery.
2139  */
2140  }
2141  if (parse->mergeActionList)
2142  {
2143  foreach(lc, parse->mergeActionList)
2144  {
2145  MergeAction *action = lfirst(lc);
2146 
2147  action->qual = pullup_replace_vars(action->qual, rvcontext);
2148  action->targetList = (List *)
2149  pullup_replace_vars((Node *) action->targetList, rvcontext);
2150  }
2151  }
2152  replace_vars_in_jointree((Node *) parse->jointree, rvcontext,
2153  lowest_nulling_outer_join);
2154  Assert(parse->setOperations == NULL);
2155  parse->havingQual = pullup_replace_vars(parse->havingQual, rvcontext);
2156 
2157  /*
2158  * Replace references in the translated_vars lists of appendrels. When
2159  * pulling up an appendrel member, we do not need PHVs in the list of the
2160  * parent appendrel --- there isn't any outer join between. Elsewhere,
2161  * use PHVs for safety. (This analysis could be made tighter but it seems
2162  * unlikely to be worth much trouble.)
2163  */
2164  foreach(lc, root->append_rel_list)
2165  {
2166  AppendRelInfo *appinfo = (AppendRelInfo *) lfirst(lc);
2167  bool save_need_phvs = rvcontext->need_phvs;
2168 
2169  if (appinfo == containing_appendrel)
2170  rvcontext->need_phvs = false;
2171  appinfo->translated_vars = (List *)
2172  pullup_replace_vars((Node *) appinfo->translated_vars, rvcontext);
2173  rvcontext->need_phvs = save_need_phvs;
2174  }
2175 
2176  /*
2177  * Replace references in the joinaliasvars lists of join RTEs.
2178  *
2179  * You might think that we could avoid using PHVs for alias vars of joins
2180  * below lowest_nulling_outer_join, but that doesn't work because the
2181  * alias vars could be referenced above that join; we need the PHVs to be
2182  * present in such references after the alias vars get flattened. (It
2183  * might be worth trying to be smarter here, someday.)
2184  */
2185  foreach(lc, parse->rtable)
2186  {
2187  RangeTblEntry *otherrte = (RangeTblEntry *) lfirst(lc);
2188 
2189  if (otherrte->rtekind == RTE_JOIN)
2190  otherrte->joinaliasvars = (List *)
2191  pullup_replace_vars((Node *) otherrte->joinaliasvars,
2192  rvcontext);
2193  }
2194 }
2195 
2196 /*
2197  * Helper routine for perform_pullup_replace_vars: do pullup_replace_vars on
2198  * every expression in the jointree, without changing the jointree structure
2199  * itself. Ugly, but there's no other way...
2200  *
2201  * If we are at or below lowest_nulling_outer_join, we can suppress use of
2202  * PlaceHolderVars wrapped around the replacement expressions.
2203  */
2204 static void
2206  pullup_replace_vars_context *context,
2207  JoinExpr *lowest_nulling_outer_join)
2208 {
2209  if (jtnode == NULL)
2210  return;
2211  if (IsA(jtnode, RangeTblRef))
2212  {
2213  /*
2214  * If the RangeTblRef refers to a LATERAL subquery (that isn't the
2215  * same subquery we're pulling up), it might contain references to the
2216  * target subquery, which we must replace. We drive this from the
2217  * jointree scan, rather than a scan of the rtable, for a couple of
2218  * reasons: we can avoid processing no-longer-referenced RTEs, and we
2219  * can use the appropriate setting of need_phvs depending on whether
2220  * the RTE is above possibly-nulling outer joins or not.
2221  */
2222  int varno = ((RangeTblRef *) jtnode)->rtindex;
2223 
2224  if (varno != context->varno) /* ignore target subquery itself */
2225  {
2226  RangeTblEntry *rte = rt_fetch(varno, context->root->parse->rtable);
2227 
2228  Assert(rte != context->target_rte);
2229  if (rte->lateral)
2230  {
2231  switch (rte->rtekind)
2232  {
2233  case RTE_RELATION:
2234  /* shouldn't be marked LATERAL unless tablesample */
2235  Assert(rte->tablesample);
2236  rte->tablesample = (TableSampleClause *)
2238  context);
2239  break;
2240  case RTE_SUBQUERY:
2241  rte->subquery =
2243  context);
2244  break;
2245  case RTE_FUNCTION:
2246  rte->functions = (List *)
2248  context);
2249  break;
2250  case RTE_TABLEFUNC:
2251  rte->tablefunc = (TableFunc *)
2253  context);
2254  break;
2255  case RTE_VALUES:
2256  rte->values_lists = (List *)
2258  context);
2259  break;
2260  case RTE_JOIN:
2261  case RTE_CTE:
2262  case RTE_NAMEDTUPLESTORE:
2263  case RTE_RESULT:
2264  /* these shouldn't be marked LATERAL */
2265  Assert(false);
2266  break;
2267  }
2268  }
2269  }
2270  }
2271  else if (IsA(jtnode, FromExpr))
2272  {
2273  FromExpr *f = (FromExpr *) jtnode;
2274  ListCell *l;
2275 
2276  foreach(l, f->fromlist)
2277  replace_vars_in_jointree(lfirst(l), context,
2278  lowest_nulling_outer_join);
2279  f->quals = pullup_replace_vars(f->quals, context);
2280  }
2281  else if (IsA(jtnode, JoinExpr))
2282  {
2283  JoinExpr *j = (JoinExpr *) jtnode;
2284  bool save_need_phvs = context->need_phvs;
2285 
2286  if (j == lowest_nulling_outer_join)
2287  {
2288  /* no more PHVs in or below this join */
2289  context->need_phvs = false;
2290  lowest_nulling_outer_join = NULL;
2291  }
2292  replace_vars_in_jointree(j->larg, context, lowest_nulling_outer_join);
2293  replace_vars_in_jointree(j->rarg, context, lowest_nulling_outer_join);
2294 
2295  /*
2296  * Use PHVs within the join quals of a full join, even when it's the
2297  * lowest nulling outer join. Otherwise, we cannot identify which
2298  * side of the join a pulled-up var-free expression came from, which
2299  * can lead to failure to make a plan at all because none of the quals
2300  * appear to be mergeable or hashable conditions. For this purpose we
2301  * don't care about the state of wrap_non_vars, so leave it alone.
2302  */
2303  if (j->jointype == JOIN_FULL)
2304  context->need_phvs = true;
2305 
2306  j->quals = pullup_replace_vars(j->quals, context);
2307 
2308  /*
2309  * We don't bother to update the colvars list, since it won't be used
2310  * again ...
2311  */
2312  context->need_phvs = save_need_phvs;
2313  }
2314  else
2315  elog(ERROR, "unrecognized node type: %d",
2316  (int) nodeTag(jtnode));
2317 }
2318 
2319 /*
2320  * Apply pullup variable replacement throughout an expression tree
2321  *
2322  * Returns a modified copy of the tree, so this can't be used where we
2323  * need to do in-place replacement.
2324  */
2325 static Node *
2327 {
2328  return replace_rte_variables(expr,
2329  context->varno, 0,
2331  (void *) context,
2332  context->outer_hasSubLinks);
2333 }
2334 
2335 static Node *
2338 {
2340  int varattno = var->varattno;
2341  Node *newnode;
2342 
2343  /*
2344  * If PlaceHolderVars are needed, we cache the modified expressions in
2345  * rcon->rv_cache[]. This is not in hopes of any material speed gain
2346  * within this function, but to avoid generating identical PHVs with
2347  * different IDs. That would result in duplicate evaluations at runtime,
2348  * and possibly prevent optimizations that rely on recognizing different
2349  * references to the same subquery output as being equal(). So it's worth
2350  * a bit of extra effort to avoid it.
2351  */
2352  if (rcon->need_phvs &&
2353  varattno >= InvalidAttrNumber &&
2354  varattno <= list_length(rcon->targetlist) &&
2355  rcon->rv_cache[varattno] != NULL)
2356  {
2357  /* Just copy the entry and fall through to adjust its varlevelsup */
2358  newnode = copyObject(rcon->rv_cache[varattno]);
2359  }
2360  else if (varattno == InvalidAttrNumber)
2361  {
2362  /* Must expand whole-tuple reference into RowExpr */
2363  RowExpr *rowexpr;
2364  List *colnames;
2365  List *fields;
2366  bool save_need_phvs = rcon->need_phvs;
2367  int save_sublevelsup = context->sublevels_up;
2368 
2369  /*
2370  * If generating an expansion for a var of a named rowtype (ie, this
2371  * is a plain relation RTE), then we must include dummy items for
2372  * dropped columns. If the var is RECORD (ie, this is a JOIN), then
2373  * omit dropped columns. In the latter case, attach column names to
2374  * the RowExpr for use of the executor and ruleutils.c.
2375  *
2376  * In order to be able to cache the results, we always generate the
2377  * expansion with varlevelsup = 0, and then adjust if needed.
2378  */
2379  expandRTE(rcon->target_rte,
2380  var->varno, 0 /* not varlevelsup */ , var->location,
2381  (var->vartype != RECORDOID),
2382  &colnames, &fields);
2383  /* Adjust the generated per-field Vars, but don't insert PHVs */
2384  rcon->need_phvs = false;
2385  context->sublevels_up = 0; /* to match the expandRTE output */
2386  fields = (List *) replace_rte_variables_mutator((Node *) fields,
2387  context);
2388  rcon->need_phvs = save_need_phvs;
2389  context->sublevels_up = save_sublevelsup;
2390 
2391  rowexpr = makeNode(RowExpr);
2392  rowexpr->args = fields;
2393  rowexpr->row_typeid = var->vartype;
2394  rowexpr->row_format = COERCE_IMPLICIT_CAST;
2395  rowexpr->colnames = (var->vartype == RECORDOID) ? colnames : NIL;
2396  rowexpr->location = var->location;
2397  newnode = (Node *) rowexpr;
2398 
2399  /*
2400  * Insert PlaceHolderVar if needed. Notice that we are wrapping one
2401  * PlaceHolderVar around the whole RowExpr, rather than putting one
2402  * around each element of the row. This is because we need the
2403  * expression to yield NULL, not ROW(NULL,NULL,...) when it is forced
2404  * to null by an outer join.
2405  */
2406  if (rcon->need_phvs)
2407  {
2408  /* RowExpr is certainly not strict, so always need PHV */
2409  newnode = (Node *)
2411  (Expr *) newnode,
2412  bms_make_singleton(rcon->varno));
2413  /* cache it with the PHV, and with varlevelsup still zero */
2414  rcon->rv_cache[InvalidAttrNumber] = copyObject(newnode);
2415  }
2416  }
2417  else
2418  {
2419  /* Normal case referencing one targetlist element */
2420  TargetEntry *tle = get_tle_by_resno(rcon->targetlist, varattno);
2421 
2422  if (tle == NULL) /* shouldn't happen */
2423  elog(ERROR, "could not find attribute %d in subquery targetlist",
2424  varattno);
2425 
2426  /* Make a copy of the tlist item to return */
2427  newnode = (Node *) copyObject(tle->expr);
2428 
2429  /* Insert PlaceHolderVar if needed */
2430  if (rcon->need_phvs)
2431  {
2432  bool wrap;
2433 
2434  if (newnode && IsA(newnode, Var) &&
2435  ((Var *) newnode)->varlevelsup == 0)
2436  {
2437  /*
2438  * Simple Vars always escape being wrapped, unless they are
2439  * lateral references to something outside the subquery being
2440  * pulled up. (Even then, we could omit the PlaceHolderVar if
2441  * the referenced rel is under the same lowest outer join, but
2442  * it doesn't seem worth the trouble to check that.)
2443  */
2444  if (rcon->target_rte->lateral &&
2445  !bms_is_member(((Var *) newnode)->varno, rcon->relids))
2446  wrap = true;
2447  else
2448  wrap = false;
2449  }
2450  else if (newnode && IsA(newnode, PlaceHolderVar) &&
2451  ((PlaceHolderVar *) newnode)->phlevelsup == 0)
2452  {
2453  /* No need to wrap a PlaceHolderVar with another one, either */
2454  wrap = false;
2455  }
2456  else if (rcon->wrap_non_vars)
2457  {
2458  /* Wrap all non-Vars in a PlaceHolderVar */
2459  wrap = true;
2460  }
2461  else
2462  {
2463  /*
2464  * If it contains a Var of the subquery being pulled up, and
2465  * does not contain any non-strict constructs, then it's
2466  * certainly nullable so we don't need to insert a
2467  * PlaceHolderVar.
2468  *
2469  * This analysis could be tighter: in particular, a non-strict
2470  * construct hidden within a lower-level PlaceHolderVar is not
2471  * reason to add another PHV. But for now it doesn't seem
2472  * worth the code to be more exact.
2473  *
2474  * Note: in future maybe we should insert a PlaceHolderVar
2475  * anyway, if the tlist item is expensive to evaluate?
2476  *
2477  * For a LATERAL subquery, we have to check the actual var
2478  * membership of the node, but if it's non-lateral then any
2479  * level-zero var must belong to the subquery.
2480  */
2481  if ((rcon->target_rte->lateral ?
2482  bms_overlap(pull_varnos(rcon->root, (Node *) newnode),
2483  rcon->relids) :
2484  contain_vars_of_level((Node *) newnode, 0)) &&
2485  !contain_nonstrict_functions((Node *) newnode))
2486  {
2487  /* No wrap needed */
2488  wrap = false;
2489  }
2490  else
2491  {
2492  /* Else wrap it in a PlaceHolderVar */
2493  wrap = true;
2494  }
2495  }
2496 
2497  if (wrap)
2498  newnode = (Node *)
2500  (Expr *) newnode,
2501  bms_make_singleton(rcon->varno));
2502 
2503  /*
2504  * Cache it if possible (ie, if the attno is in range, which it
2505  * probably always should be). We can cache the value even if we
2506  * decided we didn't need a PHV, since this result will be
2507  * suitable for any request that has need_phvs.
2508  */
2509  if (varattno > InvalidAttrNumber &&
2510  varattno <= list_length(rcon->targetlist))
2511  rcon->rv_cache[varattno] = copyObject(newnode);
2512  }
2513  }
2514 
2515  /* Must adjust varlevelsup if tlist item is from higher query */
2516  if (var->varlevelsup > 0)
2517  IncrementVarSublevelsUp(newnode, var->varlevelsup, 0);
2518 
2519  return newnode;
2520 }
2521 
2522 /*
2523  * Apply pullup variable replacement to a subquery
2524  *
2525  * This needs to be different from pullup_replace_vars() because
2526  * replace_rte_variables will think that it shouldn't increment sublevels_up
2527  * before entering the Query; so we need to call it with sublevels_up == 1.
2528  */
2529 static Query *
2531  pullup_replace_vars_context *context)
2532 {
2533  Assert(IsA(query, Query));
2534  return (Query *) replace_rte_variables((Node *) query,
2535  context->varno, 1,
2537  (void *) context,
2538  NULL);
2539 }
2540 
2541 
2542 /*
2543  * flatten_simple_union_all
2544  * Try to optimize top-level UNION ALL structure into an appendrel
2545  *
2546  * If a query's setOperations tree consists entirely of simple UNION ALL
2547  * operations, flatten it into an append relation, which we can process more
2548  * intelligently than the general setops case. Otherwise, do nothing.
2549  *
2550  * In most cases, this can succeed only for a top-level query, because for a
2551  * subquery in FROM, the parent query's invocation of pull_up_subqueries would
2552  * already have flattened the UNION via pull_up_simple_union_all. But there
2553  * are a few cases we can support here but not in that code path, for example
2554  * when the subquery also contains ORDER BY.
2555  */
2556 void
2558 {
2559  Query *parse = root->parse;
2560  SetOperationStmt *topop;
2561  Node *leftmostjtnode;
2562  int leftmostRTI;
2563  RangeTblEntry *leftmostRTE;
2564  int childRTI;
2565  RangeTblEntry *childRTE;
2566  RangeTblRef *rtr;
2567 
2568  /* Shouldn't be called unless query has setops */
2569  topop = castNode(SetOperationStmt, parse->setOperations);
2570  Assert(topop);
2571 
2572  /* Can't optimize away a recursive UNION */
2573  if (root->hasRecursion)
2574  return;
2575 
2576  /*
2577  * Recursively check the tree of set operations. If not all UNION ALL
2578  * with identical column types, punt.
2579  */
2580  if (!is_simple_union_all_recurse((Node *) topop, parse, topop->colTypes))
2581  return;
2582 
2583  /*
2584  * Locate the leftmost leaf query in the setops tree. The upper query's
2585  * Vars all refer to this RTE (see transformSetOperationStmt).
2586  */
2587  leftmostjtnode = topop->larg;
2588  while (leftmostjtnode && IsA(leftmostjtnode, SetOperationStmt))
2589  leftmostjtnode = ((SetOperationStmt *) leftmostjtnode)->larg;
2590  Assert(leftmostjtnode && IsA(leftmostjtnode, RangeTblRef));
2591  leftmostRTI = ((RangeTblRef *) leftmostjtnode)->rtindex;
2592  leftmostRTE = rt_fetch(leftmostRTI, parse->rtable);
2593  Assert(leftmostRTE->rtekind == RTE_SUBQUERY);
2594 
2595  /*
2596  * Make a copy of the leftmost RTE and add it to the rtable. This copy
2597  * will represent the leftmost leaf query in its capacity as a member of
2598  * the appendrel. The original will represent the appendrel as a whole.
2599  * (We must do things this way because the upper query's Vars have to be
2600  * seen as referring to the whole appendrel.)
2601  */
2602  childRTE = copyObject(leftmostRTE);
2603  parse->rtable = lappend(parse->rtable, childRTE);
2604  childRTI = list_length(parse->rtable);
2605 
2606  /* Modify the setops tree to reference the child copy */
2607  ((RangeTblRef *) leftmostjtnode)->rtindex = childRTI;
2608 
2609  /* Modify the formerly-leftmost RTE to mark it as an appendrel parent */
2610  leftmostRTE->inh = true;
2611 
2612  /*
2613  * Form a RangeTblRef for the appendrel, and insert it into FROM. The top
2614  * Query of a setops tree should have had an empty FromClause initially.
2615  */
2616  rtr = makeNode(RangeTblRef);
2617  rtr->rtindex = leftmostRTI;
2618  Assert(parse->jointree->fromlist == NIL);
2619  parse->jointree->fromlist = list_make1(rtr);
2620 
2621  /*
2622  * Now pretend the query has no setops. We must do this before trying to
2623  * do subquery pullup, because of Assert in pull_up_simple_subquery.
2624  */
2625  parse->setOperations = NULL;
2626 
2627  /*
2628  * Build AppendRelInfo information, and apply pull_up_subqueries to the
2629  * leaf queries of the UNION ALL. (We must do that now because they
2630  * weren't previously referenced by the jointree, and so were missed by
2631  * the main invocation of pull_up_subqueries.)
2632  */
2633  pull_up_union_leaf_queries((Node *) topop, root, leftmostRTI, parse, 0);
2634 }
2635 
2636 
2637 /*
2638  * reduce_outer_joins
2639  * Attempt to reduce outer joins to plain inner joins.
2640  *
2641  * The idea here is that given a query like
2642  * SELECT ... FROM a LEFT JOIN b ON (...) WHERE b.y = 42;
2643  * we can reduce the LEFT JOIN to a plain JOIN if the "=" operator in WHERE
2644  * is strict. The strict operator will always return NULL, causing the outer
2645  * WHERE to fail, on any row where the LEFT JOIN filled in NULLs for b's
2646  * columns. Therefore, there's no need for the join to produce null-extended
2647  * rows in the first place --- which makes it a plain join not an outer join.
2648  * (This scenario may not be very likely in a query written out by hand, but
2649  * it's reasonably likely when pushing quals down into complex views.)
2650  *
2651  * More generally, an outer join can be reduced in strength if there is a
2652  * strict qual above it in the qual tree that constrains a Var from the
2653  * nullable side of the join to be non-null. (For FULL joins this applies
2654  * to each side separately.)
2655  *
2656  * Another transformation we apply here is to recognize cases like
2657  * SELECT ... FROM a LEFT JOIN b ON (a.x = b.y) WHERE b.y IS NULL;
2658  * If the join clause is strict for b.y, then only null-extended rows could
2659  * pass the upper WHERE, and we can conclude that what the query is really
2660  * specifying is an anti-semijoin. We change the join type from JOIN_LEFT
2661  * to JOIN_ANTI. The IS NULL clause then becomes redundant, and must be
2662  * removed to prevent bogus selectivity calculations, but we leave it to
2663  * distribute_qual_to_rels to get rid of such clauses.
2664  *
2665  * Also, we get rid of JOIN_RIGHT cases by flipping them around to become
2666  * JOIN_LEFT. This saves some code here and in some later planner routines,
2667  * but the main reason to do it is to not need to invent a JOIN_REVERSE_ANTI
2668  * join type.
2669  *
2670  * To ease recognition of strict qual clauses, we require this routine to be
2671  * run after expression preprocessing (i.e., qual canonicalization and JOIN
2672  * alias-var expansion).
2673  */
2674 void
2676 {
2678 
2679  /*
2680  * To avoid doing strictness checks on more quals than necessary, we want
2681  * to stop descending the jointree as soon as there are no outer joins
2682  * below our current point. This consideration forces a two-pass process.
2683  * The first pass gathers information about which base rels appear below
2684  * each side of each join clause, and about whether there are outer
2685  * join(s) below each side of each join clause. The second pass examines
2686  * qual clauses and changes join types as it descends the tree.
2687  */
2689 
2690  /* planner.c shouldn't have called me if no outer joins */
2691  if (state == NULL || !state->contains_outer)
2692  elog(ERROR, "so where are the outer joins?");
2693 
2695  state, root, NULL, NIL, NIL);
2696 }
2697 
2698 /*
2699  * reduce_outer_joins_pass1 - phase 1 data collection
2700  *
2701  * Returns a state node describing the given jointree node.
2702  */
2703 static reduce_outer_joins_state *
2705 {
2706  reduce_outer_joins_state *result;
2707 
2708  result = (reduce_outer_joins_state *)
2710  result->relids = NULL;
2711  result->contains_outer = false;
2712  result->sub_states = NIL;
2713 
2714  if (jtnode == NULL)
2715  return result;
2716  if (IsA(jtnode, RangeTblRef))
2717  {
2718  int varno = ((RangeTblRef *) jtnode)->rtindex;
2719 
2720  result->relids = bms_make_singleton(varno);
2721  }
2722  else if (IsA(jtnode, FromExpr))
2723  {
2724  FromExpr *f = (FromExpr *) jtnode;
2725  ListCell *l;
2726 
2727  foreach(l, f->fromlist)
2728  {
2729  reduce_outer_joins_state *sub_state;
2730 
2731  sub_state = reduce_outer_joins_pass1(lfirst(l));
2732  result->relids = bms_add_members(result->relids,
2733  sub_state->relids);
2734  result->contains_outer |= sub_state->contains_outer;
2735  result->sub_states = lappend(result->sub_states, sub_state);
2736  }
2737  }
2738  else if (IsA(jtnode, JoinExpr))
2739  {
2740  JoinExpr *j = (JoinExpr *) jtnode;
2741  reduce_outer_joins_state *sub_state;
2742 
2743  /* join's own RT index is not wanted in result->relids */
2744  if (IS_OUTER_JOIN(j->jointype))
2745  result->contains_outer = true;
2746 
2747  sub_state = reduce_outer_joins_pass1(j->larg);
2748  result->relids = bms_add_members(result->relids,
2749  sub_state->relids);
2750  result->contains_outer |= sub_state->contains_outer;
2751  result->sub_states = lappend(result->sub_states, sub_state);
2752 
2753  sub_state = reduce_outer_joins_pass1(j->rarg);
2754  result->relids = bms_add_members(result->relids,
2755  sub_state->relids);
2756  result->contains_outer |= sub_state->contains_outer;
2757  result->sub_states = lappend(result->sub_states, sub_state);
2758  }
2759  else
2760  elog(ERROR, "unrecognized node type: %d",
2761  (int) nodeTag(jtnode));
2762  return result;
2763 }
2764 
2765 /*
2766  * reduce_outer_joins_pass2 - phase 2 processing
2767  *
2768  * jtnode: current jointree node
2769  * state: state data collected by phase 1 for this node
2770  * root: toplevel planner state
2771  * nonnullable_rels: set of base relids forced non-null by upper quals
2772  * nonnullable_vars: list of Vars forced non-null by upper quals
2773  * forced_null_vars: list of Vars forced null by upper quals
2774  */
2775 static void
2778  PlannerInfo *root,
2779  Relids nonnullable_rels,
2780  List *nonnullable_vars,
2781  List *forced_null_vars)
2782 {
2783  /*
2784  * pass 2 should never descend as far as an empty subnode or base rel,
2785  * because it's only called on subtrees marked as contains_outer.
2786  */
2787  if (jtnode == NULL)
2788  elog(ERROR, "reached empty jointree");
2789  if (IsA(jtnode, RangeTblRef))
2790  elog(ERROR, "reached base rel");
2791  else if (IsA(jtnode, FromExpr))
2792  {
2793  FromExpr *f = (FromExpr *) jtnode;
2794  ListCell *l;
2795  ListCell *s;
2796  Relids pass_nonnullable_rels;
2797  List *pass_nonnullable_vars;
2798  List *pass_forced_null_vars;
2799 
2800  /* Scan quals to see if we can add any constraints */
2801  pass_nonnullable_rels = find_nonnullable_rels(f->quals);
2802  pass_nonnullable_rels = bms_add_members(pass_nonnullable_rels,
2803  nonnullable_rels);
2804  pass_nonnullable_vars = find_nonnullable_vars(f->quals);
2805  pass_nonnullable_vars = list_concat(pass_nonnullable_vars,
2806  nonnullable_vars);
2807  pass_forced_null_vars = find_forced_null_vars(f->quals);
2808  pass_forced_null_vars = list_concat(pass_forced_null_vars,
2809  forced_null_vars);
2810  /* And recurse --- but only into interesting subtrees */
2811  Assert(list_length(f->fromlist) == list_length(state->sub_states));
2812  forboth(l, f->fromlist, s, state->sub_states)
2813  {
2814  reduce_outer_joins_state *sub_state = lfirst(s);
2815 
2816  if (sub_state->contains_outer)
2817  reduce_outer_joins_pass2(lfirst(l), sub_state, root,
2818  pass_nonnullable_rels,
2819  pass_nonnullable_vars,
2820  pass_forced_null_vars);
2821  }
2822  bms_free(pass_nonnullable_rels);
2823  /* can't so easily clean up var lists, unfortunately */
2824  }
2825  else if (IsA(jtnode, JoinExpr))
2826  {
2827  JoinExpr *j = (JoinExpr *) jtnode;
2828  int rtindex = j->rtindex;
2829  JoinType jointype = j->jointype;
2830  reduce_outer_joins_state *left_state = linitial(state->sub_states);
2831  reduce_outer_joins_state *right_state = lsecond(state->sub_states);
2832  List *local_nonnullable_vars = NIL;
2833  bool computed_local_nonnullable_vars = false;
2834 
2835  /* Can we simplify this join? */
2836  switch (jointype)
2837  {
2838  case JOIN_INNER:
2839  break;
2840  case JOIN_LEFT:
2841  if (bms_overlap(nonnullable_rels, right_state->relids))
2842  jointype = JOIN_INNER;
2843  break;
2844  case JOIN_RIGHT:
2845  if (bms_overlap(nonnullable_rels, left_state->relids))
2846  jointype = JOIN_INNER;
2847  break;
2848  case JOIN_FULL:
2849  if (bms_overlap(nonnullable_rels, left_state->relids))
2850  {
2851  if (bms_overlap(nonnullable_rels, right_state->relids))
2852  jointype = JOIN_INNER;
2853  else
2854  jointype = JOIN_LEFT;
2855  }
2856  else
2857  {
2858  if (bms_overlap(nonnullable_rels, right_state->relids))
2859  jointype = JOIN_RIGHT;
2860  }
2861  break;
2862  case JOIN_SEMI:
2863  case JOIN_ANTI:
2864 
2865  /*
2866  * These could only have been introduced by pull_up_sublinks,
2867  * so there's no way that upper quals could refer to their
2868  * righthand sides, and no point in checking.
2869  */
2870  break;
2871  default:
2872  elog(ERROR, "unrecognized join type: %d",
2873  (int) jointype);
2874  break;
2875  }
2876 
2877  /*
2878  * Convert JOIN_RIGHT to JOIN_LEFT. Note that in the case where we
2879  * reduced JOIN_FULL to JOIN_RIGHT, this will mean the JoinExpr no
2880  * longer matches the internal ordering of any CoalesceExpr's built to
2881  * represent merged join variables. We don't care about that at
2882  * present, but be wary of it ...
2883  */
2884  if (jointype == JOIN_RIGHT)
2885  {
2886  Node *tmparg;
2887 
2888  tmparg = j->larg;
2889  j->larg = j->rarg;
2890  j->rarg = tmparg;
2891  jointype = JOIN_LEFT;
2892  right_state = linitial(state->sub_states);
2893  left_state = lsecond(state->sub_states);
2894  }
2895 
2896  /*
2897  * See if we can reduce JOIN_LEFT to JOIN_ANTI. This is the case if
2898  * the join's own quals are strict for any var that was forced null by
2899  * higher qual levels. NOTE: there are other ways that we could
2900  * detect an anti-join, in particular if we were to check whether Vars
2901  * coming from the RHS must be non-null because of table constraints.
2902  * That seems complicated and expensive though (in particular, one
2903  * would have to be wary of lower outer joins). For the moment this
2904  * seems sufficient.
2905  */
2906  if (jointype == JOIN_LEFT)
2907  {
2908  List *overlap;
2909 
2910  local_nonnullable_vars = find_nonnullable_vars(j->quals);
2911  computed_local_nonnullable_vars = true;
2912 
2913  /*
2914  * It's not sufficient to check whether local_nonnullable_vars and
2915  * forced_null_vars overlap: we need to know if the overlap
2916  * includes any RHS variables.
2917  */
2918  overlap = list_intersection(local_nonnullable_vars,
2919  forced_null_vars);
2920  if (overlap != NIL &&
2921  bms_overlap(pull_varnos(root, (Node *) overlap),
2922  right_state->relids))
2923  jointype = JOIN_ANTI;
2924  }
2925 
2926  /* Apply the jointype change, if any, to both jointree node and RTE */
2927  if (rtindex && jointype != j->jointype)
2928  {
2929  RangeTblEntry *rte = rt_fetch(rtindex, root->parse->rtable);
2930 
2931  Assert(rte->rtekind == RTE_JOIN);
2932  Assert(rte->jointype == j->jointype);
2933  rte->jointype = jointype;
2934  }
2935  j->jointype = jointype;
2936 
2937  /* Only recurse if there's more to do below here */
2938  if (left_state->contains_outer || right_state->contains_outer)
2939  {
2940  Relids local_nonnullable_rels;
2941  List *local_forced_null_vars;
2942  Relids pass_nonnullable_rels;
2943  List *pass_nonnullable_vars;
2944  List *pass_forced_null_vars;
2945 
2946  /*
2947  * If this join is (now) inner, we can add any constraints its
2948  * quals provide to those we got from above. But if it is outer,
2949  * we can pass down the local constraints only into the nullable
2950  * side, because an outer join never eliminates any rows from its
2951  * non-nullable side. Also, there is no point in passing upper
2952  * constraints into the nullable side, since if there were any
2953  * we'd have been able to reduce the join. (In the case of upper
2954  * forced-null constraints, we *must not* pass them into the
2955  * nullable side --- they either applied here, or not.) The upshot
2956  * is that we pass either the local or the upper constraints,
2957  * never both, to the children of an outer join.
2958  *
2959  * Note that a SEMI join works like an inner join here: it's okay
2960  * to pass down both local and upper constraints. (There can't be
2961  * any upper constraints affecting its inner side, but it's not
2962  * worth having a separate code path to avoid passing them.)
2963  *
2964  * At a FULL join we just punt and pass nothing down --- is it
2965  * possible to be smarter?
2966  */
2967  if (jointype != JOIN_FULL)
2968  {
2969  local_nonnullable_rels = find_nonnullable_rels(j->quals);
2970  if (!computed_local_nonnullable_vars)
2971  local_nonnullable_vars = find_nonnullable_vars(j->quals);
2972  local_forced_null_vars = find_forced_null_vars(j->quals);
2973  if (jointype == JOIN_INNER || jointype == JOIN_SEMI)
2974  {
2975  /* OK to merge upper and local constraints */
2976  local_nonnullable_rels = bms_add_members(local_nonnullable_rels,
2977  nonnullable_rels);
2978  local_nonnullable_vars = list_concat(local_nonnullable_vars,
2979  nonnullable_vars);
2980  local_forced_null_vars = list_concat(local_forced_null_vars,
2981  forced_null_vars);
2982  }
2983  }
2984  else
2985  {
2986  /* no use in calculating these */
2987  local_nonnullable_rels = NULL;
2988  local_forced_null_vars = NIL;
2989  }
2990 
2991  if (left_state->contains_outer)
2992  {
2993  if (jointype == JOIN_INNER || jointype == JOIN_SEMI)
2994  {
2995  /* pass union of local and upper constraints */
2996  pass_nonnullable_rels = local_nonnullable_rels;
2997  pass_nonnullable_vars = local_nonnullable_vars;
2998  pass_forced_null_vars = local_forced_null_vars;
2999  }
3000  else if (jointype != JOIN_FULL) /* ie, LEFT or ANTI */
3001  {
3002  /* can't pass local constraints to non-nullable side */
3003  pass_nonnullable_rels = nonnullable_rels;
3004  pass_nonnullable_vars = nonnullable_vars;
3005  pass_forced_null_vars = forced_null_vars;
3006  }
3007  else
3008  {
3009  /* no constraints pass through JOIN_FULL */
3010  pass_nonnullable_rels = NULL;
3011  pass_nonnullable_vars = NIL;
3012  pass_forced_null_vars = NIL;
3013  }
3014  reduce_outer_joins_pass2(j->larg, left_state, root,
3015  pass_nonnullable_rels,
3016  pass_nonnullable_vars,
3017  pass_forced_null_vars);
3018  }
3019 
3020  if (right_state->contains_outer)
3021  {
3022  if (jointype != JOIN_FULL) /* ie, INNER/LEFT/SEMI/ANTI */
3023  {
3024  /* pass appropriate constraints, per comment above */
3025  pass_nonnullable_rels = local_nonnullable_rels;
3026  pass_nonnullable_vars = local_nonnullable_vars;
3027  pass_forced_null_vars = local_forced_null_vars;
3028  }
3029  else
3030  {
3031  /* no constraints pass through JOIN_FULL */
3032  pass_nonnullable_rels = NULL;
3033  pass_nonnullable_vars = NIL;
3034  pass_forced_null_vars = NIL;
3035  }
3036  reduce_outer_joins_pass2(j->rarg, right_state, root,
3037  pass_nonnullable_rels,
3038  pass_nonnullable_vars,
3039  pass_forced_null_vars);
3040  }
3041  bms_free(local_nonnullable_rels);
3042  }
3043  }
3044  else
3045  elog(ERROR, "unrecognized node type: %d",
3046  (int) nodeTag(jtnode));
3047 }
3048 
3049 
3050 /*
3051  * remove_useless_result_rtes
3052  * Attempt to remove RTE_RESULT RTEs from the join tree.
3053  *
3054  * We can remove RTE_RESULT entries from the join tree using the knowledge
3055  * that RTE_RESULT returns exactly one row and has no output columns. Hence,
3056  * if one is inner-joined to anything else, we can delete it. Optimizations
3057  * are also possible for some outer-join cases, as detailed below.
3058  *
3059  * Some of these optimizations depend on recognizing empty (constant-true)
3060  * quals for FromExprs and JoinExprs. That makes it useful to apply this
3061  * optimization pass after expression preprocessing, since that will have
3062  * eliminated constant-true quals, allowing more cases to be recognized as
3063  * optimizable. What's more, the usual reason for an RTE_RESULT to be present
3064  * is that we pulled up a subquery or VALUES clause, thus very possibly
3065  * replacing Vars with constants, making it more likely that a qual can be
3066  * reduced to constant true. Also, because some optimizations depend on
3067  * the outer-join type, it's best to have done reduce_outer_joins() first.
3068  *
3069  * A PlaceHolderVar referencing an RTE_RESULT RTE poses an obstacle to this
3070  * process: we must remove the RTE_RESULT's relid from the PHV's phrels, but
3071  * we must not reduce the phrels set to empty. If that would happen, and
3072  * the RTE_RESULT is an immediate child of an outer join, we have to give up
3073  * and not remove the RTE_RESULT: there is noplace else to evaluate the
3074  * PlaceHolderVar. (That is, in such cases the RTE_RESULT *does* have output
3075  * columns.) But if the RTE_RESULT is an immediate child of an inner join,
3076  * we can usually change the PlaceHolderVar's phrels so as to evaluate it at
3077  * the inner join instead. This is OK because we really only care that PHVs
3078  * are evaluated above or below the correct outer joins. We can't, however,
3079  * postpone the evaluation of a PHV to above where it is used; so there are
3080  * some checks below on whether output PHVs are laterally referenced in the
3081  * other join input rel(s).
3082  *
3083  * We used to try to do this work as part of pull_up_subqueries() where the
3084  * potentially-optimizable cases get introduced; but it's way simpler, and
3085  * more effective, to do it separately.
3086  */
3087 void
3089 {
3090  ListCell *cell;
3091 
3092  /* Top level of jointree must always be a FromExpr */
3093  Assert(IsA(root->parse->jointree, FromExpr));
3094  /* Recurse ... */
3095  root->parse->jointree = (FromExpr *)
3097  /* We should still have a FromExpr */
3098  Assert(IsA(root->parse->jointree, FromExpr));
3099 
3100  /*
3101  * Remove any PlanRowMark referencing an RTE_RESULT RTE. We obviously
3102  * must do that for any RTE_RESULT that we just removed. But one for a
3103  * RTE that we did not remove can be dropped anyway: since the RTE has
3104  * only one possible output row, there is no need for EPQ to mark and
3105  * restore that row.
3106  *
3107  * It's necessary, not optional, to remove the PlanRowMark for a surviving
3108  * RTE_RESULT RTE; otherwise we'll generate a whole-row Var for the
3109  * RTE_RESULT, which the executor has no support for.
3110  */
3111  foreach(cell, root->rowMarks)
3112  {
3113  PlanRowMark *rc = (PlanRowMark *) lfirst(cell);
3114 
3115  if (rt_fetch(rc->rti, root->parse->rtable)->rtekind == RTE_RESULT)
3116  root->rowMarks = foreach_delete_current(root->rowMarks, cell);
3117  }
3118 }
3119 
3120 /*
3121  * remove_useless_results_recurse
3122  * Recursive guts of remove_useless_result_rtes.
3123  *
3124  * This recursively processes the jointree and returns a modified jointree.
3125  */
3126 static Node *
3128 {
3129  Assert(jtnode != NULL);
3130  if (IsA(jtnode, RangeTblRef))
3131  {
3132  /* Can't immediately do anything with a RangeTblRef */
3133  }
3134  else if (IsA(jtnode, FromExpr))
3135  {
3136  FromExpr *f = (FromExpr *) jtnode;
3137  Relids result_relids = NULL;
3138  ListCell *cell;
3139 
3140  /*
3141  * We can drop RTE_RESULT rels from the fromlist so long as at least
3142  * one child remains, since joining to a one-row table changes
3143  * nothing. (But we can't drop a RTE_RESULT that computes PHV(s) that
3144  * are needed by some sibling. The cleanup transformation below would
3145  * reassign the PHVs to be computed at the join, which is too late for
3146  * the sibling's use.) The easiest way to mechanize this rule is to
3147  * modify the list in-place.
3148  */
3149  foreach(cell, f->fromlist)
3150  {
3151  Node *child = (Node *) lfirst(cell);
3152  int varno;
3153 
3154  /* Recursively transform child ... */
3155  child = remove_useless_results_recurse(root, child);
3156  /* ... and stick it back into the tree */
3157  lfirst(cell) = child;
3158 
3159  /*
3160  * If it's an RTE_RESULT with at least one sibling, and no sibling
3161  * references dependent PHVs, we can drop it. We don't yet know
3162  * what the inner join's final relid set will be, so postpone
3163  * cleanup of PHVs etc till after this loop.
3164  */
3165  if (list_length(f->fromlist) > 1 &&
3166  (varno = get_result_relid(root, child)) != 0 &&
3167  !find_dependent_phvs_in_jointree(root, (Node *) f, varno))
3168  {
3169  f->fromlist = foreach_delete_current(f->fromlist, cell);
3170  result_relids = bms_add_member(result_relids, varno);
3171  }
3172  }
3173 
3174  /*
3175  * Clean up if we dropped any RTE_RESULT RTEs. This is a bit
3176  * inefficient if there's more than one, but it seems better to
3177  * optimize the support code for the single-relid case.
3178  */
3179  if (result_relids)
3180  {
3181  int varno = -1;
3182 
3183  while ((varno = bms_next_member(result_relids, varno)) >= 0)
3184  remove_result_refs(root, varno, (Node *) f);
3185  }
3186 
3187  /*
3188  * If we're not at the top of the jointree, it's valid to simplify a
3189  * degenerate FromExpr into its single child. (At the top, we must
3190  * keep the FromExpr since Query.jointree is required to point to a
3191  * FromExpr.)
3192  */
3193  if (f != root->parse->jointree &&
3194  f->quals == NULL &&
3195  list_length(f->fromlist) == 1)
3196  return (Node *) linitial(f->fromlist);
3197  }
3198  else if (IsA(jtnode, JoinExpr))
3199  {
3200  JoinExpr *j = (JoinExpr *) jtnode;
3201  int varno;
3202 
3203  /* First, recurse */
3204  j->larg = remove_useless_results_recurse(root, j->larg);
3205  j->rarg = remove_useless_results_recurse(root, j->rarg);
3206 
3207  /* Apply join-type-specific optimization rules */
3208  switch (j->jointype)
3209  {
3210  case JOIN_INNER:
3211 
3212  /*
3213  * An inner join is equivalent to a FromExpr, so if either
3214  * side was simplified to an RTE_RESULT rel, we can replace
3215  * the join with a FromExpr with just the other side; and if
3216  * the qual is empty (JOIN ON TRUE) then we can omit the
3217  * FromExpr as well.
3218  *
3219  * Just as in the FromExpr case, we can't simplify if the
3220  * other input rel references any PHVs that are marked as to
3221  * be evaluated at the RTE_RESULT rel, because we can't
3222  * postpone their evaluation in that case. But we only have
3223  * to check this in cases where it's syntactically legal for
3224  * the other input to have a LATERAL reference to the
3225  * RTE_RESULT rel. Only RHSes of inner and left joins are
3226  * allowed to have such refs.
3227  */
3228  if ((varno = get_result_relid(root, j->larg)) != 0 &&
3229  !find_dependent_phvs_in_jointree(root, j->rarg, varno))
3230  {
3231  remove_result_refs(root, varno, j->rarg);
3232  if (j->quals)
3233  jtnode = (Node *)
3234  makeFromExpr(list_make1(j->rarg), j->quals);
3235  else
3236  jtnode = j->rarg;
3237  }
3238  else if ((varno = get_result_relid(root, j->rarg)) != 0)
3239  {
3240  remove_result_refs(root, varno, j->larg);
3241  if (j->quals)
3242  jtnode = (Node *)
3243  makeFromExpr(list_make1(j->larg), j->quals);
3244  else
3245  jtnode = j->larg;
3246  }
3247  break;
3248  case JOIN_LEFT:
3249 
3250  /*
3251  * We can simplify this case if the RHS is an RTE_RESULT, with
3252  * two different possibilities:
3253  *
3254  * If the qual is empty (JOIN ON TRUE), then the join can be
3255  * strength-reduced to a plain inner join, since each LHS row
3256  * necessarily has exactly one join partner. So we can always
3257  * discard the RHS, much as in the JOIN_INNER case above.
3258  * (Again, the LHS could not contain a lateral reference to
3259  * the RHS.)
3260  *
3261  * Otherwise, it's still true that each LHS row should be
3262  * returned exactly once, and since the RHS returns no columns
3263  * (unless there are PHVs that have to be evaluated there), we
3264  * don't much care if it's null-extended or not. So in this
3265  * case also, we can just ignore the qual and discard the left
3266  * join.
3267  */
3268  if ((varno = get_result_relid(root, j->rarg)) != 0 &&
3269  (j->quals == NULL ||
3270  !find_dependent_phvs(root, varno)))
3271  {
3272  remove_result_refs(root, varno, j->larg);
3273  jtnode = j->larg;
3274  }
3275  break;
3276  case JOIN_RIGHT:
3277  /* Mirror-image of the JOIN_LEFT case */
3278  if ((varno = get_result_relid(root, j->larg)) != 0 &&
3279  (j->quals == NULL ||
3280  !find_dependent_phvs(root, varno)))
3281  {
3282  remove_result_refs(root, varno, j->rarg);
3283  jtnode = j->rarg;
3284  }
3285  break;
3286  case JOIN_SEMI:
3287 
3288  /*
3289  * We may simplify this case if the RHS is an RTE_RESULT; the
3290  * join qual becomes effectively just a filter qual for the
3291  * LHS, since we should either return the LHS row or not. For
3292  * simplicity we inject the filter qual into a new FromExpr.
3293  *
3294  * Unlike the LEFT/RIGHT cases, we just Assert that there are
3295  * no PHVs that need to be evaluated at the semijoin's RHS,
3296  * since the rest of the query couldn't reference any outputs
3297  * of the semijoin's RHS.
3298  */
3299  if ((varno = get_result_relid(root, j->rarg)) != 0)
3300  {
3301  Assert(!find_dependent_phvs(root, varno));
3302  remove_result_refs(root, varno, j->larg);
3303  if (j->quals)
3304  jtnode = (Node *)
3305  makeFromExpr(list_make1(j->larg), j->quals);
3306  else
3307  jtnode = j->larg;
3308  }
3309  break;
3310  case JOIN_FULL:
3311  case JOIN_ANTI:
3312  /* We have no special smarts for these cases */
3313  break;
3314  default:
3315  elog(ERROR, "unrecognized join type: %d",
3316  (int) j->jointype);
3317  break;
3318  }
3319  }
3320  else
3321  elog(ERROR, "unrecognized node type: %d",
3322  (int) nodeTag(jtnode));
3323  return jtnode;
3324 }
3325 
3326 /*
3327  * get_result_relid
3328  * If jtnode is a RangeTblRef for an RTE_RESULT RTE, return its relid;
3329  * otherwise return 0.
3330  */
3331 static int
3333 {
3334  int varno;
3335 
3336  if (!IsA(jtnode, RangeTblRef))
3337  return 0;
3338  varno = ((RangeTblRef *) jtnode)->rtindex;
3339  if (rt_fetch(varno, root->parse->rtable)->rtekind != RTE_RESULT)
3340  return 0;
3341  return varno;
3342 }
3343 
3344 /*
3345  * remove_result_refs
3346  * Helper routine for dropping an unneeded RTE_RESULT RTE.
3347  *
3348  * This doesn't physically remove the RTE from the jointree, because that's
3349  * more easily handled in remove_useless_results_recurse. What it does do
3350  * is the necessary cleanup in the rest of the tree: we must adjust any PHVs
3351  * that may reference the RTE. Be sure to call this at a point where the
3352  * jointree is valid (no disconnected nodes).
3353  *
3354  * Note that we don't need to process the append_rel_list, since RTEs
3355  * referenced directly in the jointree won't be appendrel members.
3356  *
3357  * varno is the RTE_RESULT's relid.
3358  * newjtloc is the jointree location at which any PHVs referencing the
3359  * RTE_RESULT should be evaluated instead.
3360  */
3361 static void
3362 remove_result_refs(PlannerInfo *root, int varno, Node *newjtloc)
3363 {
3364  /* Fix up PlaceHolderVars as needed */
3365  /* If there are no PHVs anywhere, we can skip this bit */
3366  if (root->glob->lastPHId != 0)
3367  {
3368  Relids subrelids;
3369 
3370  subrelids = get_relids_in_jointree(newjtloc, false);
3371  Assert(!bms_is_empty(subrelids));
3372  substitute_phv_relids((Node *) root->parse, varno, subrelids);
3373  fix_append_rel_relids(root->append_rel_list, varno, subrelids);
3374  }
3375 
3376  /*
3377  * We also need to remove any PlanRowMark referencing the RTE, but we
3378  * postpone that work until we return to remove_useless_result_rtes.
3379  */
3380 }
3381 
3382 
3383 /*
3384  * find_dependent_phvs - are there any PlaceHolderVars whose relids are
3385  * exactly the given varno?
3386  *
3387  * find_dependent_phvs should be used when we want to see if there are
3388  * any such PHVs anywhere in the Query. Another use-case is to see if
3389  * a subtree of the join tree contains such PHVs; but for that, we have
3390  * to look not only at the join tree nodes themselves but at the
3391  * referenced RTEs. For that, use find_dependent_phvs_in_jointree.
3392  */
3393 
3394 typedef struct
3395 {
3399 
3400 static bool
3402  find_dependent_phvs_context *context)
3403 {
3404  if (node == NULL)
3405  return false;
3406  if (IsA(node, PlaceHolderVar))
3407  {
3408  PlaceHolderVar *phv = (PlaceHolderVar *) node;
3409 
3410  if (phv->phlevelsup == context->sublevels_up &&
3411  bms_equal(context->relids, phv->phrels))
3412  return true;
3413  /* fall through to examine children */
3414  }
3415  if (IsA(node, Query))
3416  {
3417  /* Recurse into subselects */
3418  bool result;
3419 
3420  context->sublevels_up++;
3421  result = query_tree_walker((Query *) node,
3423  (void *) context, 0);
3424  context->sublevels_up--;
3425  return result;
3426  }
3427  /* Shouldn't need to handle planner auxiliary nodes here */
3428  Assert(!IsA(node, SpecialJoinInfo));
3429  Assert(!IsA(node, AppendRelInfo));
3430  Assert(!IsA(node, PlaceHolderInfo));
3431  Assert(!IsA(node, MinMaxAggInfo));
3432 
3434  (void *) context);
3435 }
3436 
3437 static bool
3439 {
3441 
3442  /* If there are no PHVs anywhere, we needn't work hard */
3443  if (root->glob->lastPHId == 0)
3444  return false;
3445 
3446  context.relids = bms_make_singleton(varno);
3447  context.sublevels_up = 0;
3448 
3449  return query_tree_walker(root->parse,
3451  (void *) &context,
3452  0);
3453 }
3454 
3455 static bool
3457 {
3459  Relids subrelids;
3460  int relid;
3461 
3462  /* If there are no PHVs anywhere, we needn't work hard */
3463  if (root->glob->lastPHId == 0)
3464  return false;
3465 
3466  context.relids = bms_make_singleton(varno);
3467  context.sublevels_up = 0;
3468 
3469  /*
3470  * See if the jointree fragment itself contains references (in join quals)
3471  */
3472  if (find_dependent_phvs_walker(node, &context))
3473  return true;
3474 
3475  /*
3476  * Otherwise, identify the set of referenced RTEs (we can ignore joins,
3477  * since they should be flattened already, so their join alias lists no
3478  * longer matter), and tediously check each RTE. We can ignore RTEs that
3479  * are not marked LATERAL, though, since they couldn't possibly contain
3480  * any cross-references to other RTEs.
3481  */
3482  subrelids = get_relids_in_jointree(node, false);
3483  relid = -1;
3484  while ((relid = bms_next_member(subrelids, relid)) >= 0)
3485  {
3486  RangeTblEntry *rte = rt_fetch(relid, root->parse->rtable);
3487 
3488  if (rte->lateral &&
3491  (void *) &context,
3492  0))
3493  return true;
3494  }
3495 
3496  return false;
3497 }
3498 
3499 /*
3500  * substitute_phv_relids - adjust PlaceHolderVar relid sets after pulling up
3501  * a subquery or removing an RTE_RESULT jointree item
3502  *
3503  * Find any PlaceHolderVar nodes in the given tree that reference the
3504  * pulled-up relid, and change them to reference the replacement relid(s).
3505  *
3506  * NOTE: although this has the form of a walker, we cheat and modify the
3507  * nodes in-place. This should be OK since the tree was copied by
3508  * pullup_replace_vars earlier. Avoid scribbling on the original values of
3509  * the bitmapsets, though, because expression_tree_mutator doesn't copy those.
3510  */
3511 
3512 typedef struct
3513 {
3514  int varno;
3518 
3519 static bool
3522 {
3523  if (node == NULL)
3524  return false;
3525  if (IsA(node, PlaceHolderVar))
3526  {
3527  PlaceHolderVar *phv = (PlaceHolderVar *) node;
3528 
3529  if (phv->phlevelsup == context->sublevels_up &&
3530  bms_is_member(context->varno, phv->phrels))
3531  {
3532  phv->phrels = bms_union(phv->phrels,
3533  context->subrelids);
3534  phv->phrels = bms_del_member(phv->phrels,
3535  context->varno);
3536  /* Assert we haven't broken the PHV */
3537  Assert(!bms_is_empty(phv->phrels));
3538  }
3539  /* fall through to examine children */
3540  }
3541  if (IsA(node, Query))
3542  {
3543  /* Recurse into subselects */
3544  bool result;
3545 
3546  context->sublevels_up++;
3547  result = query_tree_walker((Query *) node,
3549  (void *) context, 0);
3550  context->sublevels_up--;
3551  return result;
3552  }
3553  /* Shouldn't need to handle planner auxiliary nodes here */
3554  Assert(!IsA(node, SpecialJoinInfo));
3555  Assert(!IsA(node, AppendRelInfo));
3556  Assert(!IsA(node, PlaceHolderInfo));
3557  Assert(!IsA(node, MinMaxAggInfo));
3558 
3560  (void *) context);
3561 }
3562 
3563 static void
3564 substitute_phv_relids(Node *node, int varno, Relids subrelids)
3565 {
3567 
3568  context.varno = varno;
3569  context.sublevels_up = 0;
3570  context.subrelids = subrelids;
3571 
3572  /*
3573  * Must be prepared to start with a Query or a bare expression tree.
3574  */
3577  (void *) &context,
3578  0);
3579 }
3580 
3581 /*
3582  * fix_append_rel_relids: update RT-index fields of AppendRelInfo nodes
3583  *
3584  * When we pull up a subquery, any AppendRelInfo references to the subquery's
3585  * RT index have to be replaced by the substituted relid (and there had better
3586  * be only one). We also need to apply substitute_phv_relids to their
3587  * translated_vars lists, since those might contain PlaceHolderVars.
3588  *
3589  * We assume we may modify the AppendRelInfo nodes in-place.
3590  */
3591 static void
3592 fix_append_rel_relids(List *append_rel_list, int varno, Relids subrelids)
3593 {
3594  ListCell *l;
3595  int subvarno = -1;
3596 
3597  /*
3598  * We only want to extract the member relid once, but we mustn't fail
3599  * immediately if there are multiple members; it could be that none of the
3600  * AppendRelInfo nodes refer to it. So compute it on first use. Note that
3601  * bms_singleton_member will complain if set is not singleton.
3602  */
3603  foreach(l, append_rel_list)
3604  {
3605  AppendRelInfo *appinfo = (AppendRelInfo *) lfirst(l);
3606 
3607  /* The parent_relid shouldn't ever be a pullup target */
3608  Assert(appinfo->parent_relid != varno);
3609 
3610  if (appinfo->child_relid == varno)
3611  {
3612  if (subvarno < 0)
3613  subvarno = bms_singleton_member(subrelids);
3614  appinfo->child_relid = subvarno;
3615  }
3616 
3617  /* Also fix up any PHVs in its translated vars */
3619  varno, subrelids);
3620  }
3621 }
3622 
3623 /*
3624  * get_relids_in_jointree: get set of RT indexes present in a jointree
3625  *
3626  * If include_joins is true, join RT indexes are included; if false,
3627  * only base rels are included.
3628  */
3629 Relids
3630 get_relids_in_jointree(Node *jtnode, bool include_joins)
3631 {
3632  Relids result = NULL;
3633 
3634  if (jtnode == NULL)
3635  return result;
3636  if (IsA(jtnode, RangeTblRef))
3637  {
3638  int varno = ((RangeTblRef *) jtnode)->rtindex;
3639 
3640  result = bms_make_singleton(varno);
3641  }
3642  else if (IsA(jtnode, FromExpr))
3643  {
3644  FromExpr *f = (FromExpr *) jtnode;
3645  ListCell *l;
3646 
3647  foreach(l, f->fromlist)
3648  {
3649  result = bms_join(result,
3651  include_joins));
3652  }
3653  }
3654  else if (IsA(jtnode, JoinExpr))
3655  {
3656  JoinExpr *j = (JoinExpr *) jtnode;
3657 
3658  result = get_relids_in_jointree(j->larg, include_joins);
3659  result = bms_join(result,
3660  get_relids_in_jointree(j->rarg, include_joins));
3661  if (include_joins && j->rtindex)
3662  result = bms_add_member(result, j->rtindex);
3663  }
3664  else
3665  elog(ERROR, "unrecognized node type: %d",
3666  (int) nodeTag(jtnode));
3667  return result;
3668 }
3669 
3670 /*
3671  * get_relids_for_join: get set of base RT indexes making up a join
3672  */
3673 Relids
3674 get_relids_for_join(Query *query, int joinrelid)
3675 {
3676  Node *jtnode;
3677 
3678  jtnode = find_jointree_node_for_rel((Node *) query->jointree,
3679  joinrelid);
3680  if (!jtnode)
3681  elog(ERROR, "could not find join node %d", joinrelid);
3682  return get_relids_in_jointree(jtnode, false);
3683 }
3684 
3685 /*
3686  * find_jointree_node_for_rel: locate jointree node for a base or join RT index
3687  *
3688  * Returns NULL if not found
3689  */
3690 static Node *
3692 {
3693  if (jtnode == NULL)
3694  return NULL;
3695  if (IsA(jtnode, RangeTblRef))
3696  {
3697  int varno = ((RangeTblRef *) jtnode)->rtindex;
3698 
3699  if (relid == varno)
3700  return jtnode;
3701  }
3702  else if (IsA(jtnode, FromExpr))
3703  {
3704  FromExpr *f = (FromExpr *) jtnode;
3705  ListCell *l;
3706 
3707  foreach(l, f->fromlist)
3708  {
3709  jtnode = find_jointree_node_for_rel(lfirst(l), relid);
3710  if (jtnode)
3711  return jtnode;
3712  }
3713  }
3714  else if (IsA(jtnode, JoinExpr))
3715  {
3716  JoinExpr *j = (JoinExpr *) jtnode;
3717 
3718  if (relid == j->rtindex)
3719  return jtnode;
3720  jtnode = find_jointree_node_for_rel(j->larg, relid);
3721  if (jtnode)
3722  return jtnode;
3723  jtnode = find_jointree_node_for_rel(j->rarg, relid);
3724  if (jtnode)
3725  return jtnode;
3726  }
3727  else
3728  elog(ERROR, "unrecognized node type: %d",
3729  (int) nodeTag(jtnode));
3730  return NULL;
3731 }
int16 AttrNumber
Definition: attnum.h:21
#define InvalidAttrNumber
Definition: attnum.h:23
Bitmapset * bms_join(Bitmapset *a, Bitmapset *b)
Definition: bitmapset.c:951
bool bms_equal(const Bitmapset *a, const Bitmapset *b)
Definition: bitmapset.c:94
int bms_next_member(const Bitmapset *a, int prevbit)
Definition: bitmapset.c:1045
bool bms_is_subset(const Bitmapset *a, const Bitmapset *b)
Definition: bitmapset.c:315
int bms_singleton_member(const Bitmapset *a)
Definition: bitmapset.c:579
void bms_free(Bitmapset *a)
Definition: bitmapset.c:208
bool bms_is_member(int x, const Bitmapset *a)
Definition: bitmapset.c:427
Bitmapset * bms_make_singleton(int x)
Definition: bitmapset.c:186
Bitmapset * bms_add_member(Bitmapset *a, int x)
Definition: bitmapset.c:738
Bitmapset * bms_union(const Bitmapset *a, const Bitmapset *b)
Definition: bitmapset.c:225
Bitmapset * bms_add_members(Bitmapset *a, const Bitmapset *b)
Definition: bitmapset.c:795
Bitmapset * bms_del_member(Bitmapset *a, int x)
Definition: bitmapset.c:775
bool bms_is_empty(const Bitmapset *a)
Definition: bitmapset.c:703
bool bms_overlap(const Bitmapset *a, const Bitmapset *b)
Definition: bitmapset.c:494
unsigned int Index
Definition: c.h:549
List * find_forced_null_vars(Node *node)
Definition: clauses.c:1816
Query * inline_set_returning_function(PlannerInfo *root, RangeTblEntry *rte)
Definition: clauses.c:4956
Relids find_nonnullable_rels(Node *clause)
Definition: clauses.c:1398
List * find_nonnullable_vars(Node *clause)
Definition: clauses.c:1623
bool contain_nonstrict_functions(Node *clause)
Definition: clauses.c:935
Node * eval_const_expressions(PlannerInfo *root, Node *node)
Definition: clauses.c:2150
bool contain_volatile_functions(Node *clause)
Definition: clauses.c:496
#define ERROR
Definition: elog.h:33
#define elog(elevel,...)
Definition: elog.h:218
TypeFuncClass get_expr_result_type(Node *expr, Oid *resultTypeId, TupleDesc *resultTupleDesc)
Definition: funcapi.c:292
TypeFuncClass
Definition: funcapi.h:147
@ TYPEFUNC_SCALAR
Definition: funcapi.h:148
int j
Definition: isn.c:74
Assert(fmt[strlen(fmt) - 1] !='\n')
List * lappend(List *list, void *datum)
Definition: list.c:336
List * list_intersection(const List *list1, const List *list2)
Definition: list.c:1133
List * list_concat(List *list1, const List *list2)
Definition: list.c:540
Alias * makeAlias(const char *aliasname, List *colnames)
Definition: makefuncs.c:388
Var * makeVarFromTargetEntry(int varno, TargetEntry *tle)
Definition: makefuncs.c:104
TargetEntry * makeTargetEntry(Expr *expr, AttrNumber resno, char *resname, bool resjunk)
Definition: makefuncs.c:239
Expr * make_andclause(List *andclauses)
Definition: makefuncs.c:637
FromExpr * makeFromExpr(List *fromlist, Node *quals)
Definition: makefuncs.c:286
void * palloc0(Size size)
Definition: mcxt.c:1099
MemoryContext CurrentMemoryContext
Definition: mcxt.c:42
void * palloc(Size size)
Definition: mcxt.c:1068
bool query_or_expression_tree_walker(Node *node, bool(*walker)(), void *context, int flags)
Definition: nodeFuncs.c:3810
bool query_tree_walker(Query *query, bool(*walker)(), void *context, int flags)
Definition: nodeFuncs.c:2570
bool expression_tree_walker(Node *node, bool(*walker)(), void *context)
Definition: nodeFuncs.c:2015
bool expression_returns_set(Node *clause)
Definition: nodeFuncs.c:736
bool range_table_entry_walker(RangeTblEntry *rte, bool(*walker)(), void *context, int flags)
Definition: nodeFuncs.c:2692
static bool is_andclause(const void *clause)
Definition: nodeFuncs.h:95
static Expr * get_notclausearg(const void *notclause)
Definition: nodeFuncs.h:122
static bool is_notclause(const void *clause)
Definition: nodeFuncs.h:113
#define IsA(nodeptr, _type_)
Definition: nodes.h:624
#define copyObject(obj)
Definition: nodes.h:689
#define nodeTag(nodeptr)
Definition: nodes.h:578
#define IS_OUTER_JOIN(jointype)
Definition: nodes.h:792
@ CMD_MERGE
Definition: nodes.h:725
@ CMD_SELECT
Definition: nodes.h:721
#define makeNode(_type_)
Definition: nodes.h:621
#define castNode(_type_, nodeptr)
Definition: nodes.h:642
JoinType
Definition: nodes.h:744
@ JOIN_SEMI
Definition: nodes.h:763
@ JOIN_FULL
Definition: nodes.h:751
@ JOIN_INNER
Definition: nodes.h:749
@ JOIN_RIGHT
Definition: nodes.h:752
@ JOIN_LEFT
Definition: nodes.h:750
@ JOIN_ANTI
Definition: nodes.h:764
TargetEntry * get_tle_by_resno(List *tlist, AttrNumber resno)
void expandRTE(RangeTblEntry *rte, int rtindex, int sublevels_up, int location, bool include_dropped, List **colnames, List **colvars)
@ SETOP_UNION
Definition: parsenodes.h:1991
@ RTE_JOIN
Definition: parsenodes.h:1000
@ RTE_CTE
Definition: parsenodes.h:1004
@ RTE_NAMEDTUPLESTORE
Definition: parsenodes.h:1005
@ RTE_VALUES
Definition: parsenodes.h:1003
@ RTE_SUBQUERY
Definition: parsenodes.h:999
@ RTE_RESULT
Definition: parsenodes.h:1006
@ RTE_FUNCTION
Definition: parsenodes.h:1001
@ RTE_TABLEFUNC
Definition: parsenodes.h:1002
@ RTE_RELATION
Definition: parsenodes.h:998
#define rt_fetch(rangetable_index, rangetable)
Definition: parsetree.h:31
#define lfirst(lc)
Definition: pg_list.h:169
static int list_length(const List *l)
Definition: pg_list.h:149
#define linitial_node(type, l)
Definition: pg_list.h:177
#define NIL
Definition: pg_list.h:65
#define forboth(cell1, list1, cell2, list2)
Definition: pg_list.h:446
#define list_make1(x1)
Definition: pg_list.h:206
#define linitial(l)
Definition: pg_list.h:174
#define lsecond(l)
Definition: pg_list.h:179
#define foreach_delete_current(lst, cell)
Definition: pg_list.h:369
PlaceHolderVar * make_placeholder_expr(PlannerInfo *root, Expr *expr, Relids phrels)
Definition: placeholder.c:39
#define InvalidOid
Definition: postgres_ext.h:36
unsigned int Oid
Definition: postgres_ext.h:31
static void remove_result_refs(PlannerInfo *root, int varno, Node *newjtloc)
void preprocess_function_rtes(PlannerInfo *root)
Definition: prepjointree.c:719
static bool find_dependent_phvs_walker(Node *node, find_dependent_phvs_context *context)
static Node * find_jointree_node_for_rel(Node *jtnode, int relid)
static Node * pull_up_simple_union_all(PlannerInfo *root, Node *jtnode, RangeTblEntry *rte)
static Node * pull_up_subqueries_recurse(PlannerInfo *root, Node *jtnode, JoinExpr *lowest_outer_join, JoinExpr *lowest_nulling_outer_join, AppendRelInfo *containing_appendrel)
Definition: prepjointree.c:810
static void pull_up_union_leaf_queries(Node *setOp, PlannerInfo *root, int parentRTindex, Query *setOpQuery, int childRToffset)
static bool is_simple_values(PlannerInfo *root, RangeTblEntry *rte)
static void make_setop_translation_list(Query *query, int newvarno, AppendRelInfo *appinfo)
void flatten_simple_union_all(PlannerInfo *root)
void transform_MERGE_to_join(Query *parse)
Definition: prepjointree.c:140
static Node * remove_useless_results_recurse(PlannerInfo *root, Node *jtnode)
static void perform_pullup_replace_vars(PlannerInfo *root, pullup_replace_vars_context *rvcontext, JoinExpr *lowest_nulling_outer_join, AppendRelInfo *containing_appendrel)
void remove_useless_result_rtes(PlannerInfo *root)
static Node * pull_up_sublinks_jointree_recurse(PlannerInfo *root, Node *jtnode, Relids *relids)
Definition: prepjointree.c:315
static bool is_simple_subquery(PlannerInfo *root, Query *subquery, RangeTblEntry *rte, JoinExpr *lowest_outer_join)
static Node * pull_up_simple_subquery(PlannerInfo *root, Node *jtnode, RangeTblEntry *rte, JoinExpr *lowest_outer_join, JoinExpr *lowest_nulling_outer_join, AppendRelInfo *containing_appendrel)
Definition: prepjointree.c:962
static void substitute_phv_relids(Node *node, int varno, Relids subrelids)
void pull_up_sublinks(PlannerInfo *root)
Definition: prepjointree.c:288
static Node * pullup_replace_vars_callback(Var *var, replace_rte_variables_context *context)
void replace_empty_jointree(Query *parse)
Definition: prepjointree.c:230
static bool is_simple_union_all_recurse(Node *setOp, Query *setOpQuery, List *colTypes)
static Node * pull_up_constant_function(PlannerInfo *root, Node *jtnode, RangeTblEntry *rte, JoinExpr *lowest_nulling_outer_join, AppendRelInfo *containing_appendrel)
static void reduce_outer_joins_pass2(Node *jtnode, reduce_outer_joins_state *state, PlannerInfo *root, Relids nonnullable_rels, List *nonnullable_vars, List *forced_null_vars)
static bool substitute_phv_relids_walker(Node *node, substitute_phv_relids_context *context)
static Query * pullup_replace_vars_subquery(Query *query, pullup_replace_vars_context *context)
Relids get_relids_for_join(Query *query, int joinrelid)
void pull_up_subqueries(PlannerInfo *root)
Definition: prepjointree.c:760
static int get_result_relid(PlannerInfo *root, Node *jtnode)
static void fix_append_rel_relids(List *append_rel_list, int varno, Relids subrelids)
static Node * pull_up_simple_values(PlannerInfo *root, Node *jtnode, RangeTblEntry *rte)
static bool is_safe_append_member(Query *subquery)
struct pullup_replace_vars_context pullup_replace_vars_context
static void replace_vars_in_jointree(Node *jtnode, pullup_replace_vars_context *context, JoinExpr *lowest_nulling_outer_join)
static Node * pull_up_sublinks_qual_recurse(PlannerInfo *root, Node *node, Node **jtlink1, Relids available_rels1, Node **jtlink2, Relids available_rels2)
Definition: prepjointree.c:469
void reduce_outer_joins(PlannerInfo *root)
static bool find_dependent_phvs(PlannerInfo *root, int varno)
static bool jointree_contains_lateral_outer_refs(PlannerInfo *root, Node *jtnode, bool restricted, Relids safe_upper_varnos)
Relids get_relids_in_jointree(Node *jtnode, bool include_joins)
struct reduce_outer_joins_state reduce_outer_joins_state
static Node * pullup_replace_vars(Node *expr, pullup_replace_vars_context *context)
static reduce_outer_joins_state * reduce_outer_joins_pass1(Node *jtnode)
static bool is_simple_union_all(Query *subquery)
static bool find_dependent_phvs_in_jointree(PlannerInfo *root, Node *node, int varno)
@ ANY_SUBLINK
Definition: primnodes.h:694
@ EXISTS_SUBLINK
Definition: primnodes.h:692
@ COERCE_IMPLICIT_CAST
Definition: primnodes.h:494
static struct subre * parse(struct vars *, int, int, struct state *, struct state *)
Definition: regcomp.c:673
void IncrementVarSublevelsUp_rtable(List *rtable, int delta_sublevels_up, int min_sublevels_up)
Definition: rewriteManip.c:799
Node * replace_rte_variables_mutator(Node *node, replace_rte_variables_context *context)
void OffsetVarNodes(Node *node, int offset, int sublevels_up)
Definition: rewriteManip.c:425
Node * replace_rte_variables(Node *node, int target_varno, int sublevels_up, replace_rte_variables_callback callback, void *callback_arg, bool *outer_hasSubLinks)
void IncrementVarSublevelsUp(Node *node, int delta_sublevels_up, int min_sublevels_up)
Definition: rewriteManip.c:776
Index child_relid
Definition: pathnodes.h:2327
List * translated_vars
Definition: pathnodes.h:2354
Index parent_relid
Definition: pathnodes.h:2326
int num_child_cols
Definition: pathnodes.h:2362
AttrNumber * parent_colnos
Definition: pathnodes.h:2363
Oid parent_reltype
Definition: pathnodes.h:2335
Node * quals
Definition: primnodes.h:1826
List * fromlist
Definition: primnodes.h:1825
Node * quals
Definition: primnodes.h:1808
JoinType jointype
Definition: primnodes.h:1802
Alias * alias
Definition: primnodes.h:1809
int rtindex
Definition: primnodes.h:1810
List * usingClause
Definition: primnodes.h:1806
Alias * join_using_alias
Definition: primnodes.h:1807
Node * larg
Definition: primnodes.h:1804
bool isNatural
Definition: primnodes.h:1803
Node * rarg
Definition: primnodes.h:1805
Definition: pg_list.h:51
Definition: nodes.h:574
Index phlevelsup
Definition: pathnodes.h:2204
Index lastPHId
Definition: pathnodes.h:116
MemoryContext planner_cxt
Definition: pathnodes.h:336
List * minmax_aggs
Definition: pathnodes.h:334
struct PathTarget * upper_targets[UPPERREL_FINAL+1]
Definition: pathnodes.h:311
List * processed_tlist
Definition: pathnodes.h:322
bool hasRecursion
Definition: pathnodes.h:353
List * cte_plan_ids
Definition: pathnodes.h:244
Index qual_security_level
Definition: pathnodes.h:344
AttrNumber * grouping_map
Definition: pathnodes.h:333
List * init_plans
Definition: pathnodes.h:242
List * multiexpr_params
Definition: pathnodes.h:247
List * row_identity_vars
Definition: pathnodes.h:287
bool ec_merging_done
Definition: pathnodes.h:252
Bitmapset * outer_params
Definition: pathnodes.h:177
Index query_level
Definition: pathnodes.h:166
List * append_rel_list
Definition: pathnodes.h:285
struct Path * non_recursive_path
Definition: pathnodes.h:366
List * placeholder_list
Definition: pathnodes.h:291
PlannerGlobal * glob
Definition: pathnodes.h:164
List * eq_classes
Definition: pathnodes.h:250
List * upper_rels[UPPERREL_FINAL+1]
Definition: pathnodes.h:308
int wt_param_id
Definition: pathnodes.h:365
List * plan_params
Definition: pathnodes.h:176
PlannerInfo * parent_root
Definition: pathnodes.h:168
Query * parse
Definition: pathnodes.h:162
List * rowMarks
Definition: pathnodes.h:289
List * update_colnos
Definition: pathnodes.h:330
List * join_info_list
Definition: pathnodes.h:267
Relids all_result_relids
Definition: pathnodes.h:277
Relids leaf_result_relids
Definition: pathnodes.h:278
List * rowMarks
Definition: parsenodes.h:180
bool hasWindowFuncs
Definition: parsenodes.h:135
Node * limitCount
Definition: parsenodes.h:177
FromExpr * jointree
Definition: parsenodes.h:149
bool hasRowSecurity
Definition: parsenodes.h:142
Node * setOperations
Definition: parsenodes.h:182
List * cteList
Definition: parsenodes.h:146
bool hasTargetSRFs
Definition: parsenodes.h:136
List * groupClause
Definition: parsenodes.h:163
Node * havingQual
Definition: parsenodes.h:168
List * rtable
Definition: parsenodes.h:148
Node * limitOffset
Definition: parsenodes.h:176
bool hasAggs
Definition: parsenodes.h:134
CmdType commandType
Definition: parsenodes.h:121
List * targetList
Definition: parsenodes.h:155
bool hasForUpdate
Definition: parsenodes.h:141
bool hasSubLinks
Definition: parsenodes.h:137
List * groupingSets
Definition: parsenodes.h:166
List * distinctClause
Definition: parsenodes.h:172
List * sortClause
Definition: parsenodes.h:174
TableFunc * tablefunc
Definition: parsenodes.h:1115
Bitmapset * extraUpdatedCols
Definition: parsenodes.h:1170
bool security_barrier
Definition: parsenodes.h:1051
AclMode requiredPerms
Definition: parsenodes.h:1165
bool funcordinality
Definition: parsenodes.h:1110
Alias * join_using_alias
Definition: parsenodes.h:1099
struct TableSampleClause * tablesample
Definition: parsenodes.h:1045
List * securityQuals
Definition: parsenodes.h:1171
Bitmapset * updatedCols
Definition: parsenodes.h:1169
Query * subquery
Definition: parsenodes.h:1050
Bitmapset * selectedCols
Definition: parsenodes.h:1167
Alias * eref
Definition: parsenodes.h:1161
List * joinrightcols
Definition: parsenodes.h:1092
List * values_lists
Definition: parsenodes.h:1120
List * joinaliasvars
Definition: parsenodes.h:1090
JoinType jointype
Definition: parsenodes.h:1088
Alias * alias
Definition: parsenodes.h:1160
List * functions
Definition: parsenodes.h:1109
Bitmapset * insertedCols
Definition: parsenodes.h:1168
List * joinleftcols
Definition: parsenodes.h:1091
RTEKind rtekind
Definition: parsenodes.h:1015
Oid row_typeid
Definition: primnodes.h:1076
int location
Definition: primnodes.h:1092
List * args
Definition: primnodes.h:1075
CoercionForm row_format
Definition: primnodes.h:1090
List * colnames
Definition: primnodes.h:1091
SetOperation op
Definition: parsenodes.h:2068
Expr * expr
Definition: primnodes.h:1716
AttrNumber resno
Definition: primnodes.h:1717
bool resjunk
Definition: primnodes.h:1723
Definition: primnodes.h:196
Oid vartype
Definition: primnodes.h:202
AttrNumber varattno
Definition: primnodes.h:200
int varno
Definition: primnodes.h:198
Index varlevelsup
Definition: primnodes.h:205
int location
Definition: primnodes.h:210
RangeTblEntry * target_rte
Definition: prepjointree.c:47
Definition: regguts.h:318
Definition: regcomp.c:238
JoinExpr * convert_ANY_sublink_to_join(PlannerInfo *root, SubLink *sublink, Relids available_rels)
Definition: subselect.c:1268
JoinExpr * convert_EXISTS_sublink_to_join(PlannerInfo *root, SubLink *sublink, bool under_not, Relids available_rels)
Definition: subselect.c:1376
bool tlist_same_datatypes(List *tlist, List *colTypes, bool junkOK)
Definition: tlist.c:237
bool contain_vars_of_level(Node *node, int levelsup)
Definition: var.c:438
Relids pull_varnos_of_level(PlannerInfo *root, Node *node, int levelsup)
Definition: var.c:126
Relids pull_varnos(PlannerInfo *root, Node *node)
Definition: var.c:100
Node * flatten_join_alias_vars(Query *query, Node *node)
Definition: var.c:733