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