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