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