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-2023, 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  /* No need to wrap a PlaceHolderVar with another one, either */
2439  wrap = false;
2440  }
2441  else
2442  {
2443  /*
2444  * Must wrap, either because we need a place to insert
2445  * varnullingrels or because caller told us to wrap
2446  * everything.
2447  */
2448  wrap = true;
2449  }
2450 
2451  if (wrap)
2452  {
2453  newnode = (Node *)
2455  (Expr *) newnode,
2456  bms_make_singleton(rcon->varno));
2457 
2458  /*
2459  * Cache it if possible (ie, if the attno is in range, which
2460  * it probably always should be).
2461  */
2462  if (varattno > InvalidAttrNumber &&
2463  varattno <= list_length(rcon->targetlist))
2464  rcon->rv_cache[varattno] = copyObject(newnode);
2465  }
2466  }
2467  }
2468 
2469  /* Must adjust varlevelsup if replaced Var is within a subquery */
2470  if (var->varlevelsup > 0)
2471  IncrementVarSublevelsUp(newnode, var->varlevelsup, 0);
2472 
2473  /* Propagate any varnullingrels into the replacement Var or PHV */
2474  if (var->varnullingrels != NULL)
2475  {
2476  if (IsA(newnode, Var))
2477  {
2478  Var *newvar = (Var *) newnode;
2479 
2480  Assert(newvar->varlevelsup == var->varlevelsup);
2481  newvar->varnullingrels = bms_add_members(newvar->varnullingrels,
2482  var->varnullingrels);
2483  }
2484  else if (IsA(newnode, PlaceHolderVar))
2485  {
2486  PlaceHolderVar *newphv = (PlaceHolderVar *) newnode;
2487 
2488  Assert(newphv->phlevelsup == var->varlevelsup);
2489  newphv->phnullingrels = bms_add_members(newphv->phnullingrels,
2490  var->varnullingrels);
2491  }
2492  else
2493  elog(ERROR, "failed to wrap a non-Var");
2494  }
2495 
2496  return newnode;
2497 }
2498 
2499 /*
2500  * Apply pullup variable replacement to a subquery
2501  *
2502  * This needs to be different from pullup_replace_vars() because
2503  * replace_rte_variables will think that it shouldn't increment sublevels_up
2504  * before entering the Query; so we need to call it with sublevels_up == 1.
2505  */
2506 static Query *
2508  pullup_replace_vars_context *context)
2509 {
2510  Assert(IsA(query, Query));
2511  return (Query *) replace_rte_variables((Node *) query,
2512  context->varno, 1,
2514  (void *) context,
2515  NULL);
2516 }
2517 
2518 
2519 /*
2520  * flatten_simple_union_all
2521  * Try to optimize top-level UNION ALL structure into an appendrel
2522  *
2523  * If a query's setOperations tree consists entirely of simple UNION ALL
2524  * operations, flatten it into an append relation, which we can process more
2525  * intelligently than the general setops case. Otherwise, do nothing.
2526  *
2527  * In most cases, this can succeed only for a top-level query, because for a
2528  * subquery in FROM, the parent query's invocation of pull_up_subqueries would
2529  * already have flattened the UNION via pull_up_simple_union_all. But there
2530  * are a few cases we can support here but not in that code path, for example
2531  * when the subquery also contains ORDER BY.
2532  */
2533 void
2535 {
2536  Query *parse = root->parse;
2537  SetOperationStmt *topop;
2538  Node *leftmostjtnode;
2539  int leftmostRTI;
2540  RangeTblEntry *leftmostRTE;
2541  int childRTI;
2542  RangeTblEntry *childRTE;
2543  RangeTblRef *rtr;
2544 
2545  /* Shouldn't be called unless query has setops */
2546  topop = castNode(SetOperationStmt, parse->setOperations);
2547  Assert(topop);
2548 
2549  /* Can't optimize away a recursive UNION */
2550  if (root->hasRecursion)
2551  return;
2552 
2553  /*
2554  * Recursively check the tree of set operations. If not all UNION ALL
2555  * with identical column types, punt.
2556  */
2557  if (!is_simple_union_all_recurse((Node *) topop, parse, topop->colTypes))
2558  return;
2559 
2560  /*
2561  * Locate the leftmost leaf query in the setops tree. The upper query's
2562  * Vars all refer to this RTE (see transformSetOperationStmt).
2563  */
2564  leftmostjtnode = topop->larg;
2565  while (leftmostjtnode && IsA(leftmostjtnode, SetOperationStmt))
2566  leftmostjtnode = ((SetOperationStmt *) leftmostjtnode)->larg;
2567  Assert(leftmostjtnode && IsA(leftmostjtnode, RangeTblRef));
2568  leftmostRTI = ((RangeTblRef *) leftmostjtnode)->rtindex;
2569  leftmostRTE = rt_fetch(leftmostRTI, parse->rtable);
2570  Assert(leftmostRTE->rtekind == RTE_SUBQUERY);
2571 
2572  /*
2573  * Make a copy of the leftmost RTE and add it to the rtable. This copy
2574  * will represent the leftmost leaf query in its capacity as a member of
2575  * the appendrel. The original will represent the appendrel as a whole.
2576  * (We must do things this way because the upper query's Vars have to be
2577  * seen as referring to the whole appendrel.)
2578  */
2579  childRTE = copyObject(leftmostRTE);
2580  parse->rtable = lappend(parse->rtable, childRTE);
2581  childRTI = list_length(parse->rtable);
2582 
2583  /* Modify the setops tree to reference the child copy */
2584  ((RangeTblRef *) leftmostjtnode)->rtindex = childRTI;
2585 
2586  /* Modify the formerly-leftmost RTE to mark it as an appendrel parent */
2587  leftmostRTE->inh = true;
2588 
2589  /*
2590  * Form a RangeTblRef for the appendrel, and insert it into FROM. The top
2591  * Query of a setops tree should have had an empty FromClause initially.
2592  */
2593  rtr = makeNode(RangeTblRef);
2594  rtr->rtindex = leftmostRTI;
2595  Assert(parse->jointree->fromlist == NIL);
2596  parse->jointree->fromlist = list_make1(rtr);
2597 
2598  /*
2599  * Now pretend the query has no setops. We must do this before trying to
2600  * do subquery pullup, because of Assert in pull_up_simple_subquery.
2601  */
2602  parse->setOperations = NULL;
2603 
2604  /*
2605  * Build AppendRelInfo information, and apply pull_up_subqueries to the
2606  * leaf queries of the UNION ALL. (We must do that now because they
2607  * weren't previously referenced by the jointree, and so were missed by
2608  * the main invocation of pull_up_subqueries.)
2609  */
2610  pull_up_union_leaf_queries((Node *) topop, root, leftmostRTI, parse, 0);
2611 }
2612 
2613 
2614 /*
2615  * reduce_outer_joins
2616  * Attempt to reduce outer joins to plain inner joins.
2617  *
2618  * The idea here is that given a query like
2619  * SELECT ... FROM a LEFT JOIN b ON (...) WHERE b.y = 42;
2620  * we can reduce the LEFT JOIN to a plain JOIN if the "=" operator in WHERE
2621  * is strict. The strict operator will always return NULL, causing the outer
2622  * WHERE to fail, on any row where the LEFT JOIN filled in NULLs for b's
2623  * columns. Therefore, there's no need for the join to produce null-extended
2624  * rows in the first place --- which makes it a plain join not an outer join.
2625  * (This scenario may not be very likely in a query written out by hand, but
2626  * it's reasonably likely when pushing quals down into complex views.)
2627  *
2628  * More generally, an outer join can be reduced in strength if there is a
2629  * strict qual above it in the qual tree that constrains a Var from the
2630  * nullable side of the join to be non-null. (For FULL joins this applies
2631  * to each side separately.)
2632  *
2633  * Another transformation we apply here is to recognize cases like
2634  * SELECT ... FROM a LEFT JOIN b ON (a.x = b.y) WHERE b.y IS NULL;
2635  * If the join clause is strict for b.y, then only null-extended rows could
2636  * pass the upper WHERE, and we can conclude that what the query is really
2637  * specifying is an anti-semijoin. We change the join type from JOIN_LEFT
2638  * to JOIN_ANTI. The IS NULL clause then becomes redundant, and must be
2639  * removed to prevent bogus selectivity calculations, but we leave it to
2640  * distribute_qual_to_rels to get rid of such clauses.
2641  *
2642  * Also, we get rid of JOIN_RIGHT cases by flipping them around to become
2643  * JOIN_LEFT. This saves some code here and in some later planner routines;
2644  * the main benefit is to reduce the number of jointypes that can appear in
2645  * SpecialJoinInfo nodes. Note that we can still generate Paths and Plans
2646  * that use JOIN_RIGHT (or JOIN_RIGHT_ANTI) by switching the inputs again.
2647  *
2648  * To ease recognition of strict qual clauses, we require this routine to be
2649  * run after expression preprocessing (i.e., qual canonicalization and JOIN
2650  * alias-var expansion).
2651  */
2652 void
2654 {
2657  ListCell *lc;
2658 
2659  /*
2660  * To avoid doing strictness checks on more quals than necessary, we want
2661  * to stop descending the jointree as soon as there are no outer joins
2662  * below our current point. This consideration forces a two-pass process.
2663  * The first pass gathers information about which base rels appear below
2664  * each side of each join clause, and about whether there are outer
2665  * join(s) below each side of each join clause. The second pass examines
2666  * qual clauses and changes join types as it descends the tree.
2667  */
2668  state1 = reduce_outer_joins_pass1((Node *) root->parse->jointree);
2669 
2670  /* planner.c shouldn't have called me if no outer joins */
2671  if (state1 == NULL || !state1->contains_outer)
2672  elog(ERROR, "so where are the outer joins?");
2673 
2674  state2.inner_reduced = NULL;
2675  state2.partial_reduced = NIL;
2676 
2678  state1, &state2,
2679  root, NULL, NIL);
2680 
2681  /*
2682  * If we successfully reduced the strength of any outer joins, we must
2683  * remove references to those joins as nulling rels. This is handled as
2684  * an additional pass, for simplicity and because we can handle all
2685  * fully-reduced joins in a single pass over the parse tree.
2686  */
2687  if (!bms_is_empty(state2.inner_reduced))
2688  {
2689  root->parse = (Query *)
2690  remove_nulling_relids((Node *) root->parse,
2691  state2.inner_reduced,
2692  NULL);
2693  /* There could be references in the append_rel_list, too */
2694  root->append_rel_list = (List *)
2696  state2.inner_reduced,
2697  NULL);
2698  }
2699 
2700  /*
2701  * Partially-reduced full joins have to be done one at a time, since
2702  * they'll each need a different setting of except_relids.
2703  */
2704  foreach(lc, state2.partial_reduced)
2705  {
2707  Relids full_join_relids = bms_make_singleton(statep->full_join_rti);
2708 
2709  root->parse = (Query *)
2710  remove_nulling_relids((Node *) root->parse,
2711  full_join_relids,
2712  statep->unreduced_side);
2713  root->append_rel_list = (List *)
2715  full_join_relids,
2716  statep->unreduced_side);
2717  }
2718 }
2719 
2720 /*
2721  * reduce_outer_joins_pass1 - phase 1 data collection
2722  *
2723  * Returns a state node describing the given jointree node.
2724  */
2727 {
2729 
2730  result = (reduce_outer_joins_pass1_state *)
2732  result->relids = NULL;
2733  result->contains_outer = false;
2734  result->sub_states = NIL;
2735 
2736  if (jtnode == NULL)
2737  return result;
2738  if (IsA(jtnode, RangeTblRef))
2739  {
2740  int varno = ((RangeTblRef *) jtnode)->rtindex;
2741 
2742  result->relids = bms_make_singleton(varno);
2743  }
2744  else if (IsA(jtnode, FromExpr))
2745  {
2746  FromExpr *f = (FromExpr *) jtnode;
2747  ListCell *l;
2748 
2749  foreach(l, f->fromlist)
2750  {
2751  reduce_outer_joins_pass1_state *sub_state;
2752 
2753  sub_state = reduce_outer_joins_pass1(lfirst(l));
2754  result->relids = bms_add_members(result->relids,
2755  sub_state->relids);
2756  result->contains_outer |= sub_state->contains_outer;
2757  result->sub_states = lappend(result->sub_states, sub_state);
2758  }
2759  }
2760  else if (IsA(jtnode, JoinExpr))
2761  {
2762  JoinExpr *j = (JoinExpr *) jtnode;
2763  reduce_outer_joins_pass1_state *sub_state;
2764 
2765  /* join's own RT index is not wanted in result->relids */
2766  if (IS_OUTER_JOIN(j->jointype))
2767  result->contains_outer = true;
2768 
2769  sub_state = reduce_outer_joins_pass1(j->larg);
2770  result->relids = bms_add_members(result->relids,
2771  sub_state->relids);
2772  result->contains_outer |= sub_state->contains_outer;
2773  result->sub_states = lappend(result->sub_states, sub_state);
2774 
2775  sub_state = reduce_outer_joins_pass1(j->rarg);
2776  result->relids = bms_add_members(result->relids,
2777  sub_state->relids);
2778  result->contains_outer |= sub_state->contains_outer;
2779  result->sub_states = lappend(result->sub_states, sub_state);
2780  }
2781  else
2782  elog(ERROR, "unrecognized node type: %d",
2783  (int) nodeTag(jtnode));
2784  return result;
2785 }
2786 
2787 /*
2788  * reduce_outer_joins_pass2 - phase 2 processing
2789  *
2790  * jtnode: current jointree node
2791  * state1: state data collected by phase 1 for this node
2792  * state2: where to accumulate info about successfully-reduced joins
2793  * root: toplevel planner state
2794  * nonnullable_rels: set of base relids forced non-null by upper quals
2795  * forced_null_vars: multibitmapset of Vars forced null by upper quals
2796  *
2797  * Returns info in state2 about outer joins that were successfully simplified.
2798  * Joins that were fully reduced to inner joins are all added to
2799  * state2->inner_reduced. If a full join is reduced to a left join,
2800  * it needs its own entry in state2->partial_reduced, since that will
2801  * require custom processing to remove only the correct nullingrel markers.
2802  */
2803 static void
2807  PlannerInfo *root,
2808  Relids nonnullable_rels,
2809  List *forced_null_vars)
2810 {
2811  /*
2812  * pass 2 should never descend as far as an empty subnode or base rel,
2813  * because it's only called on subtrees marked as contains_outer.
2814  */
2815  if (jtnode == NULL)
2816  elog(ERROR, "reached empty jointree");
2817  if (IsA(jtnode, RangeTblRef))
2818  elog(ERROR, "reached base rel");
2819  else if (IsA(jtnode, FromExpr))
2820  {
2821  FromExpr *f = (FromExpr *) jtnode;
2822  ListCell *l;
2823  ListCell *s;
2824  Relids pass_nonnullable_rels;
2825  List *pass_forced_null_vars;
2826 
2827  /* Scan quals to see if we can add any constraints */
2828  pass_nonnullable_rels = find_nonnullable_rels(f->quals);
2829  pass_nonnullable_rels = bms_add_members(pass_nonnullable_rels,
2830  nonnullable_rels);
2831  pass_forced_null_vars = find_forced_null_vars(f->quals);
2832  pass_forced_null_vars = mbms_add_members(pass_forced_null_vars,
2833  forced_null_vars);
2834  /* And recurse --- but only into interesting subtrees */
2836  forboth(l, f->fromlist, s, state1->sub_states)
2837  {
2838  reduce_outer_joins_pass1_state *sub_state = lfirst(s);
2839 
2840  if (sub_state->contains_outer)
2841  reduce_outer_joins_pass2(lfirst(l), sub_state,
2842  state2, root,
2843  pass_nonnullable_rels,
2844  pass_forced_null_vars);
2845  }
2846  bms_free(pass_nonnullable_rels);
2847  /* can't so easily clean up var lists, unfortunately */
2848  }
2849  else if (IsA(jtnode, JoinExpr))
2850  {
2851  JoinExpr *j = (JoinExpr *) jtnode;
2852  int rtindex = j->rtindex;
2853  JoinType jointype = j->jointype;
2854  reduce_outer_joins_pass1_state *left_state = linitial(state1->sub_states);
2855  reduce_outer_joins_pass1_state *right_state = lsecond(state1->sub_states);
2856 
2857  /* Can we simplify this join? */
2858  switch (jointype)
2859  {
2860  case JOIN_INNER:
2861  break;
2862  case JOIN_LEFT:
2863  if (bms_overlap(nonnullable_rels, right_state->relids))
2864  jointype = JOIN_INNER;
2865  break;
2866  case JOIN_RIGHT:
2867  if (bms_overlap(nonnullable_rels, left_state->relids))
2868  jointype = JOIN_INNER;
2869  break;
2870  case JOIN_FULL:
2871  if (bms_overlap(nonnullable_rels, left_state->relids))
2872  {
2873  if (bms_overlap(nonnullable_rels, right_state->relids))
2874  jointype = JOIN_INNER;
2875  else
2876  {
2877  jointype = JOIN_LEFT;
2878  /* Also report partial reduction in state2 */
2879  report_reduced_full_join(state2, rtindex,
2880  right_state->relids);
2881  }
2882  }
2883  else
2884  {
2885  if (bms_overlap(nonnullable_rels, right_state->relids))
2886  {
2887  jointype = JOIN_RIGHT;
2888  /* Also report partial reduction in state2 */
2889  report_reduced_full_join(state2, rtindex,
2890  left_state->relids);
2891  }
2892  }
2893  break;
2894  case JOIN_SEMI:
2895  case JOIN_ANTI:
2896 
2897  /*
2898  * These could only have been introduced by pull_up_sublinks,
2899  * so there's no way that upper quals could refer to their
2900  * righthand sides, and no point in checking. We don't expect
2901  * to see JOIN_RIGHT_ANTI yet.
2902  */
2903  break;
2904  default:
2905  elog(ERROR, "unrecognized join type: %d",
2906  (int) jointype);
2907  break;
2908  }
2909 
2910  /*
2911  * Convert JOIN_RIGHT to JOIN_LEFT. Note that in the case where we
2912  * reduced JOIN_FULL to JOIN_RIGHT, this will mean the JoinExpr no
2913  * longer matches the internal ordering of any CoalesceExpr's built to
2914  * represent merged join variables. We don't care about that at
2915  * present, but be wary of it ...
2916  */
2917  if (jointype == JOIN_RIGHT)
2918  {
2919  Node *tmparg;
2920 
2921  tmparg = j->larg;
2922  j->larg = j->rarg;
2923  j->rarg = tmparg;
2924  jointype = JOIN_LEFT;
2925  right_state = linitial(state1->sub_states);
2926  left_state = lsecond(state1->sub_states);
2927  }
2928 
2929  /*
2930  * See if we can reduce JOIN_LEFT to JOIN_ANTI. This is the case if
2931  * the join's own quals are strict for any var that was forced null by
2932  * higher qual levels. NOTE: there are other ways that we could
2933  * detect an anti-join, in particular if we were to check whether Vars
2934  * coming from the RHS must be non-null because of table constraints.
2935  * That seems complicated and expensive though (in particular, one
2936  * would have to be wary of lower outer joins). For the moment this
2937  * seems sufficient.
2938  */
2939  if (jointype == JOIN_LEFT)
2940  {
2941  List *nonnullable_vars;
2942  Bitmapset *overlap;
2943 
2944  /* Find Vars in j->quals that must be non-null in joined rows */
2945  nonnullable_vars = find_nonnullable_vars(j->quals);
2946 
2947  /*
2948  * It's not sufficient to check whether nonnullable_vars and
2949  * forced_null_vars overlap: we need to know if the overlap
2950  * includes any RHS variables.
2951  */
2952  overlap = mbms_overlap_sets(nonnullable_vars, forced_null_vars);
2953  if (bms_overlap(overlap, right_state->relids))
2954  jointype = JOIN_ANTI;
2955  }
2956 
2957  /*
2958  * Apply the jointype change, if any, to both jointree node and RTE.
2959  * Also, if we changed an RTE to INNER, add its RTI to inner_reduced.
2960  */
2961  if (rtindex && jointype != j->jointype)
2962  {
2963  RangeTblEntry *rte = rt_fetch(rtindex, root->parse->rtable);
2964 
2965  Assert(rte->rtekind == RTE_JOIN);
2966  Assert(rte->jointype == j->jointype);
2967  rte->jointype = jointype;
2968  if (jointype == JOIN_INNER)
2969  state2->inner_reduced = bms_add_member(state2->inner_reduced,
2970  rtindex);
2971  }
2972  j->jointype = jointype;
2973 
2974  /* Only recurse if there's more to do below here */
2975  if (left_state->contains_outer || right_state->contains_outer)
2976  {
2977  Relids local_nonnullable_rels;
2978  List *local_forced_null_vars;
2979  Relids pass_nonnullable_rels;
2980  List *pass_forced_null_vars;
2981 
2982  /*
2983  * If this join is (now) inner, we can add any constraints its
2984  * quals provide to those we got from above. But if it is outer,
2985  * we can pass down the local constraints only into the nullable
2986  * side, because an outer join never eliminates any rows from its
2987  * non-nullable side. Also, there is no point in passing upper
2988  * constraints into the nullable side, since if there were any
2989  * we'd have been able to reduce the join. (In the case of upper
2990  * forced-null constraints, we *must not* pass them into the
2991  * nullable side --- they either applied here, or not.) The upshot
2992  * is that we pass either the local or the upper constraints,
2993  * never both, to the children of an outer join.
2994  *
2995  * Note that a SEMI join works like an inner join here: it's okay
2996  * to pass down both local and upper constraints. (There can't be
2997  * any upper constraints affecting its inner side, but it's not
2998  * worth having a separate code path to avoid passing them.)
2999  *
3000  * At a FULL join we just punt and pass nothing down --- is it
3001  * possible to be smarter?
3002  */
3003  if (jointype != JOIN_FULL)
3004  {
3005  local_nonnullable_rels = find_nonnullable_rels(j->quals);
3006  local_forced_null_vars = find_forced_null_vars(j->quals);
3007  if (jointype == JOIN_INNER || jointype == JOIN_SEMI)
3008  {
3009  /* OK to merge upper and local constraints */
3010  local_nonnullable_rels = bms_add_members(local_nonnullable_rels,
3011  nonnullable_rels);
3012  local_forced_null_vars = mbms_add_members(local_forced_null_vars,
3013  forced_null_vars);
3014  }
3015  }
3016  else
3017  {
3018  /* no use in calculating these */
3019  local_nonnullable_rels = NULL;
3020  local_forced_null_vars = NIL;
3021  }
3022 
3023  if (left_state->contains_outer)
3024  {
3025  if (jointype == JOIN_INNER || jointype == JOIN_SEMI)
3026  {
3027  /* pass union of local and upper constraints */
3028  pass_nonnullable_rels = local_nonnullable_rels;
3029  pass_forced_null_vars = local_forced_null_vars;
3030  }
3031  else if (jointype != JOIN_FULL) /* ie, LEFT or ANTI */
3032  {
3033  /* can't pass local constraints to non-nullable side */
3034  pass_nonnullable_rels = nonnullable_rels;
3035  pass_forced_null_vars = forced_null_vars;
3036  }
3037  else
3038  {
3039  /* no constraints pass through JOIN_FULL */
3040  pass_nonnullable_rels = NULL;
3041  pass_forced_null_vars = NIL;
3042  }
3043  reduce_outer_joins_pass2(j->larg, left_state,
3044  state2, root,
3045  pass_nonnullable_rels,
3046  pass_forced_null_vars);
3047  }
3048 
3049  if (right_state->contains_outer)
3050  {
3051  if (jointype != JOIN_FULL) /* ie, INNER/LEFT/SEMI/ANTI */
3052  {
3053  /* pass appropriate constraints, per comment above */
3054  pass_nonnullable_rels = local_nonnullable_rels;
3055  pass_forced_null_vars = local_forced_null_vars;
3056  }
3057  else
3058  {
3059  /* no constraints pass through JOIN_FULL */
3060  pass_nonnullable_rels = NULL;
3061  pass_forced_null_vars = NIL;
3062  }
3063  reduce_outer_joins_pass2(j->rarg, right_state,
3064  state2, root,
3065  pass_nonnullable_rels,
3066  pass_forced_null_vars);
3067  }
3068  bms_free(local_nonnullable_rels);
3069  }
3070  }
3071  else
3072  elog(ERROR, "unrecognized node type: %d",
3073  (int) nodeTag(jtnode));
3074 }
3075 
3076 /* Helper for reduce_outer_joins_pass2 */
3077 static void
3079  int rtindex, Relids relids)
3080 {
3082 
3083  statep = palloc(sizeof(reduce_outer_joins_partial_state));
3084  statep->full_join_rti = rtindex;
3085  statep->unreduced_side = relids;
3086  state2->partial_reduced = lappend(state2->partial_reduced, statep);
3087 }
3088 
3089 
3090 /*
3091  * remove_useless_result_rtes
3092  * Attempt to remove RTE_RESULT RTEs from the join tree.
3093  * Also, elide single-child FromExprs where possible.
3094  *
3095  * We can remove RTE_RESULT entries from the join tree using the knowledge
3096  * that RTE_RESULT returns exactly one row and has no output columns. Hence,
3097  * if one is inner-joined to anything else, we can delete it. Optimizations
3098  * are also possible for some outer-join cases, as detailed below.
3099  *
3100  * This pass also replaces single-child FromExprs with their child node
3101  * where possible. It's appropriate to do that here and not earlier because
3102  * RTE_RESULT removal might reduce a multiple-child FromExpr to have only one
3103  * child. We can remove such a FromExpr if its quals are empty, or if it's
3104  * semantically valid to merge the quals into those of the parent node.
3105  * While removing unnecessary join tree nodes has some micro-efficiency value,
3106  * the real reason to do this is to eliminate cases where the nullable side of
3107  * an outer join node is a FromExpr whose single child is another outer join.
3108  * To correctly determine whether the two outer joins can commute,
3109  * deconstruct_jointree() must treat any quals of such a FromExpr as being
3110  * degenerate quals of the upper outer join. The best way to do that is to
3111  * make them actually *be* quals of the upper join, by dropping the FromExpr
3112  * and hoisting the quals up into the upper join's quals. (Note that there is
3113  * no hazard when the intermediate FromExpr has multiple children, since then
3114  * it represents an inner join that cannot commute with the upper outer join.)
3115  * As long as we have to do that, we might as well elide such FromExprs
3116  * everywhere.
3117  *
3118  * Some of these optimizations depend on recognizing empty (constant-true)
3119  * quals for FromExprs and JoinExprs. That makes it useful to apply this
3120  * optimization pass after expression preprocessing, since that will have
3121  * eliminated constant-true quals, allowing more cases to be recognized as
3122  * optimizable. What's more, the usual reason for an RTE_RESULT to be present
3123  * is that we pulled up a subquery or VALUES clause, thus very possibly
3124  * replacing Vars with constants, making it more likely that a qual can be
3125  * reduced to constant true. Also, because some optimizations depend on
3126  * the outer-join type, it's best to have done reduce_outer_joins() first.
3127  *
3128  * A PlaceHolderVar referencing an RTE_RESULT RTE poses an obstacle to this
3129  * process: we must remove the RTE_RESULT's relid from the PHV's phrels, but
3130  * we must not reduce the phrels set to empty. If that would happen, and
3131  * the RTE_RESULT is an immediate child of an outer join, we have to give up
3132  * and not remove the RTE_RESULT: there is noplace else to evaluate the
3133  * PlaceHolderVar. (That is, in such cases the RTE_RESULT *does* have output
3134  * columns.) But if the RTE_RESULT is an immediate child of an inner join,
3135  * we can usually change the PlaceHolderVar's phrels so as to evaluate it at
3136  * the inner join instead. This is OK because we really only care that PHVs
3137  * are evaluated above or below the correct outer joins. We can't, however,
3138  * postpone the evaluation of a PHV to above where it is used; so there are
3139  * some checks below on whether output PHVs are laterally referenced in the
3140  * other join input rel(s).
3141  *
3142  * We used to try to do this work as part of pull_up_subqueries() where the
3143  * potentially-optimizable cases get introduced; but it's way simpler, and
3144  * more effective, to do it separately.
3145  */
3146 void
3148 {
3149  Relids dropped_outer_joins = NULL;
3150  ListCell *cell;
3151 
3152  /* Top level of jointree must always be a FromExpr */
3153  Assert(IsA(root->parse->jointree, FromExpr));
3154  /* Recurse ... */
3155  root->parse->jointree = (FromExpr *)
3157  (Node *) root->parse->jointree,
3158  NULL,
3159  &dropped_outer_joins);
3160  /* We should still have a FromExpr */
3161  Assert(IsA(root->parse->jointree, FromExpr));
3162 
3163  /*
3164  * If we removed any outer-join nodes from the jointree, run around and
3165  * remove references to those joins as nulling rels. (There could be such
3166  * references in PHVs that we pulled up out of the original subquery that
3167  * the RESULT rel replaced. This is kosher on the grounds that we now
3168  * know that such an outer join wouldn't really have nulled anything.) We
3169  * don't do this during the main recursion, for simplicity and because we
3170  * can handle all such joins in a single pass over the parse tree.
3171  */
3172  if (!bms_is_empty(dropped_outer_joins))
3173  {
3174  root->parse = (Query *)
3175  remove_nulling_relids((Node *) root->parse,
3176  dropped_outer_joins,
3177  NULL);
3178  /* There could be references in the append_rel_list, too */
3179  root->append_rel_list = (List *)
3181  dropped_outer_joins,
3182  NULL);
3183  }
3184 
3185  /*
3186  * Remove any PlanRowMark referencing an RTE_RESULT RTE. We obviously
3187  * must do that for any RTE_RESULT that we just removed. But one for a
3188  * RTE that we did not remove can be dropped anyway: since the RTE has
3189  * only one possible output row, there is no need for EPQ to mark and
3190  * restore that row.
3191  *
3192  * It's necessary, not optional, to remove the PlanRowMark for a surviving
3193  * RTE_RESULT RTE; otherwise we'll generate a whole-row Var for the
3194  * RTE_RESULT, which the executor has no support for.
3195  */
3196  foreach(cell, root->rowMarks)
3197  {
3198  PlanRowMark *rc = (PlanRowMark *) lfirst(cell);
3199 
3200  if (rt_fetch(rc->rti, root->parse->rtable)->rtekind == RTE_RESULT)
3201  root->rowMarks = foreach_delete_current(root->rowMarks, cell);
3202  }
3203 }
3204 
3205 /*
3206  * remove_useless_results_recurse
3207  * Recursive guts of remove_useless_result_rtes.
3208  *
3209  * This recursively processes the jointree and returns a modified jointree.
3210  * In addition, the RT indexes of any removed outer-join nodes are added to
3211  * *dropped_outer_joins.
3212  *
3213  * jtnode is the current jointree node. If it could be valid to merge
3214  * its quals into those of the parent node, parent_quals should point to
3215  * the parent's quals list; otherwise, pass NULL for parent_quals.
3216  * (Note that in some cases, parent_quals points to the quals of a parent
3217  * more than one level up in the tree.)
3218  */
3219 static Node *
3221  Node **parent_quals,
3222  Relids *dropped_outer_joins)
3223 {
3224  Assert(jtnode != NULL);
3225  if (IsA(jtnode, RangeTblRef))
3226  {
3227  /* Can't immediately do anything with a RangeTblRef */
3228  }
3229  else if (IsA(jtnode, FromExpr))
3230  {
3231  FromExpr *f = (FromExpr *) jtnode;
3232  Relids result_relids = NULL;
3233  ListCell *cell;
3234 
3235  /*
3236  * We can drop RTE_RESULT rels from the fromlist so long as at least
3237  * one child remains, since joining to a one-row table changes
3238  * nothing. (But we can't drop a RTE_RESULT that computes PHV(s) that
3239  * are needed by some sibling. The cleanup transformation below would
3240  * reassign the PHVs to be computed at the join, which is too late for
3241  * the sibling's use.) The easiest way to mechanize this rule is to
3242  * modify the list in-place.
3243  */
3244  foreach(cell, f->fromlist)
3245  {
3246  Node *child = (Node *) lfirst(cell);
3247  int varno;
3248 
3249  /* Recursively transform child, allowing it to push up quals ... */
3250  child = remove_useless_results_recurse(root, child,
3251  &f->quals,
3252  dropped_outer_joins);
3253  /* ... and stick it back into the tree */
3254  lfirst(cell) = child;
3255 
3256  /*
3257  * If it's an RTE_RESULT with at least one sibling, and no sibling
3258  * references dependent PHVs, we can drop it. We don't yet know
3259  * what the inner join's final relid set will be, so postpone
3260  * cleanup of PHVs etc till after this loop.
3261  */
3262  if (list_length(f->fromlist) > 1 &&
3263  (varno = get_result_relid(root, child)) != 0 &&
3264  !find_dependent_phvs_in_jointree(root, (Node *) f, varno))
3265  {
3266  f->fromlist = foreach_delete_current(f->fromlist, cell);
3267  result_relids = bms_add_member(result_relids, varno);
3268  }
3269  }
3270 
3271  /*
3272  * Clean up if we dropped any RTE_RESULT RTEs. This is a bit
3273  * inefficient if there's more than one, but it seems better to
3274  * optimize the support code for the single-relid case.
3275  */
3276  if (result_relids)
3277  {
3278  int varno = -1;
3279 
3280  while ((varno = bms_next_member(result_relids, varno)) >= 0)
3281  remove_result_refs(root, varno, (Node *) f);
3282  }
3283 
3284  /*
3285  * If the FromExpr now has only one child, see if we can elide it.
3286  * This is always valid if there are no quals, except at the top of
3287  * the jointree (since Query.jointree is required to point to a
3288  * FromExpr). Otherwise, we can do it if we can push the quals up to
3289  * the parent node.
3290  *
3291  * Note: while it would not be terribly hard to generalize this
3292  * transformation to merge multi-child FromExprs into their parent
3293  * FromExpr, that risks making the parent join too expensive to plan.
3294  * We leave it to later processing to decide heuristically whether
3295  * that's a good idea. Pulling up a single child is always OK,
3296  * however.
3297  */
3298  if (list_length(f->fromlist) == 1 &&
3299  f != root->parse->jointree &&
3300  (f->quals == NULL || parent_quals != NULL))
3301  {
3302  /*
3303  * Merge any quals up to parent. They should be in implicit-AND
3304  * format by now, so we just need to concatenate lists. Put the
3305  * child quals at the front, on the grounds that they should
3306  * nominally be evaluated earlier.
3307  */
3308  if (f->quals != NULL)
3309  *parent_quals = (Node *)
3311  castNode(List, *parent_quals));
3312  return (Node *) linitial(f->fromlist);
3313  }
3314  }
3315  else if (IsA(jtnode, JoinExpr))
3316  {
3317  JoinExpr *j = (JoinExpr *) jtnode;
3318  int varno;
3319 
3320  /*
3321  * First, recurse. We can absorb pushed-up FromExpr quals from either
3322  * child into this node if the jointype is INNER, since then this is
3323  * equivalent to a FromExpr. When the jointype is LEFT, we can absorb
3324  * quals from the RHS child into the current node, as they're
3325  * essentially degenerate quals of the outer join. Moreover, if we've
3326  * been passed down a parent_quals pointer then we can allow quals of
3327  * the LHS child to be absorbed into the parent. (This is important
3328  * to ensure we remove single-child FromExprs immediately below
3329  * commutable left joins.) For other jointypes, we can't move child
3330  * quals up, or at least there's no particular reason to.
3331  */
3332  j->larg = remove_useless_results_recurse(root, j->larg,
3333  (j->jointype == JOIN_INNER) ?
3334  &j->quals :
3335  (j->jointype == JOIN_LEFT) ?
3336  parent_quals : NULL,
3337  dropped_outer_joins);
3338  j->rarg = remove_useless_results_recurse(root, j->rarg,
3339  (j->jointype == JOIN_INNER ||
3340  j->jointype == JOIN_LEFT) ?
3341  &j->quals : NULL,
3342  dropped_outer_joins);
3343 
3344  /* Apply join-type-specific optimization rules */
3345  switch (j->jointype)
3346  {
3347  case JOIN_INNER:
3348 
3349  /*
3350  * An inner join is equivalent to a FromExpr, so if either
3351  * side was simplified to an RTE_RESULT rel, we can replace
3352  * the join with a FromExpr with just the other side.
3353  * Furthermore, we can elide that FromExpr according to the
3354  * same rules as above.
3355  *
3356  * Just as in the FromExpr case, we can't simplify if the
3357  * other input rel references any PHVs that are marked as to
3358  * be evaluated at the RTE_RESULT rel, because we can't
3359  * postpone their evaluation in that case. But we only have
3360  * to check this in cases where it's syntactically legal for
3361  * the other input to have a LATERAL reference to the
3362  * RTE_RESULT rel. Only RHSes of inner and left joins are
3363  * allowed to have such refs.
3364  */
3365  if ((varno = get_result_relid(root, j->larg)) != 0 &&
3366  !find_dependent_phvs_in_jointree(root, j->rarg, varno))
3367  {
3368  remove_result_refs(root, varno, j->rarg);
3369  if (j->quals != NULL && parent_quals == NULL)
3370  jtnode = (Node *)
3371  makeFromExpr(list_make1(j->rarg), j->quals);
3372  else
3373  {
3374  /* Merge any quals up to parent */
3375  if (j->quals != NULL)
3376  *parent_quals = (Node *)
3377  list_concat(castNode(List, j->quals),
3378  castNode(List, *parent_quals));
3379  jtnode = j->rarg;
3380  }
3381  }
3382  else if ((varno = get_result_relid(root, j->rarg)) != 0)
3383  {
3384  remove_result_refs(root, varno, j->larg);
3385  if (j->quals != NULL && parent_quals == NULL)
3386  jtnode = (Node *)
3387  makeFromExpr(list_make1(j->larg), j->quals);
3388  else
3389  {
3390  /* Merge any quals up to parent */
3391  if (j->quals != NULL)
3392  *parent_quals = (Node *)
3393  list_concat(castNode(List, j->quals),
3394  castNode(List, *parent_quals));
3395  jtnode = j->larg;
3396  }
3397  }
3398  break;
3399  case JOIN_LEFT:
3400 
3401  /*
3402  * We can simplify this case if the RHS is an RTE_RESULT, with
3403  * two different possibilities:
3404  *
3405  * If the qual is empty (JOIN ON TRUE), then the join can be
3406  * strength-reduced to a plain inner join, since each LHS row
3407  * necessarily has exactly one join partner. So we can always
3408  * discard the RHS, much as in the JOIN_INNER case above.
3409  * (Again, the LHS could not contain a lateral reference to
3410  * the RHS.)
3411  *
3412  * Otherwise, it's still true that each LHS row should be
3413  * returned exactly once, and since the RHS returns no columns
3414  * (unless there are PHVs that have to be evaluated there), we
3415  * don't much care if it's null-extended or not. So in this
3416  * case also, we can just ignore the qual and discard the left
3417  * join.
3418  */
3419  if ((varno = get_result_relid(root, j->rarg)) != 0 &&
3420  (j->quals == NULL ||
3421  !find_dependent_phvs(root, varno)))
3422  {
3423  remove_result_refs(root, varno, j->larg);
3424  *dropped_outer_joins = bms_add_member(*dropped_outer_joins,
3425  j->rtindex);
3426  jtnode = j->larg;
3427  }
3428  break;
3429  case JOIN_SEMI:
3430 
3431  /*
3432  * We may simplify this case if the RHS is an RTE_RESULT; the
3433  * join qual becomes effectively just a filter qual for the
3434  * LHS, since we should either return the LHS row or not. The
3435  * filter clause must go into a new FromExpr if we can't push
3436  * it up to the parent.
3437  *
3438  * There is a fine point about PHVs that are supposed to be
3439  * evaluated at the RHS. Such PHVs could only appear in the
3440  * semijoin's qual, since the rest of the query cannot
3441  * reference any outputs of the semijoin's RHS. Therefore,
3442  * they can't actually go to null before being examined, and
3443  * it'd be OK to just remove the PHV wrapping. We don't have
3444  * infrastructure for that, but remove_result_refs() will
3445  * relabel them as to be evaluated at the LHS, which is fine.
3446  *
3447  * Also, we don't need to worry about removing traces of the
3448  * join's rtindex, since it hasn't got one.
3449  */
3450  if ((varno = get_result_relid(root, j->rarg)) != 0)
3451  {
3452  Assert(j->rtindex == 0);
3453  remove_result_refs(root, varno, j->larg);
3454  if (j->quals != NULL && parent_quals == NULL)
3455  jtnode = (Node *)
3456  makeFromExpr(list_make1(j->larg), j->quals);
3457  else
3458  {
3459  /* Merge any quals up to parent */
3460  if (j->quals != NULL)
3461  *parent_quals = (Node *)
3462  list_concat(castNode(List, j->quals),
3463  castNode(List, *parent_quals));
3464  jtnode = j->larg;
3465  }
3466  }
3467  break;
3468  case JOIN_FULL:
3469  case JOIN_ANTI:
3470  /* We have no special smarts for these cases */
3471  break;
3472  default:
3473  /* Note: JOIN_RIGHT should be gone at this point */
3474  elog(ERROR, "unrecognized join type: %d",
3475  (int) j->jointype);
3476  break;
3477  }
3478  }
3479  else
3480  elog(ERROR, "unrecognized node type: %d",
3481  (int) nodeTag(jtnode));
3482  return jtnode;
3483 }
3484 
3485 /*
3486  * get_result_relid
3487  * If jtnode is a RangeTblRef for an RTE_RESULT RTE, return its relid;
3488  * otherwise return 0.
3489  */
3490 static int
3492 {
3493  int varno;
3494 
3495  if (!IsA(jtnode, RangeTblRef))
3496  return 0;
3497  varno = ((RangeTblRef *) jtnode)->rtindex;
3498  if (rt_fetch(varno, root->parse->rtable)->rtekind != RTE_RESULT)
3499  return 0;
3500  return varno;
3501 }
3502 
3503 /*
3504  * remove_result_refs
3505  * Helper routine for dropping an unneeded RTE_RESULT RTE.
3506  *
3507  * This doesn't physically remove the RTE from the jointree, because that's
3508  * more easily handled in remove_useless_results_recurse. What it does do
3509  * is the necessary cleanup in the rest of the tree: we must adjust any PHVs
3510  * that may reference the RTE. Be sure to call this at a point where the
3511  * jointree is valid (no disconnected nodes).
3512  *
3513  * Note that we don't need to process the append_rel_list, since RTEs
3514  * referenced directly in the jointree won't be appendrel members.
3515  *
3516  * varno is the RTE_RESULT's relid.
3517  * newjtloc is the jointree location at which any PHVs referencing the
3518  * RTE_RESULT should be evaluated instead.
3519  */
3520 static void
3521 remove_result_refs(PlannerInfo *root, int varno, Node *newjtloc)
3522 {
3523  /* Fix up PlaceHolderVars as needed */
3524  /* If there are no PHVs anywhere, we can skip this bit */
3525  if (root->glob->lastPHId != 0)
3526  {
3527  Relids subrelids;
3528 
3529  subrelids = get_relids_in_jointree(newjtloc, true, false);
3530  Assert(!bms_is_empty(subrelids));
3531  substitute_phv_relids((Node *) root->parse, varno, subrelids);
3532  fix_append_rel_relids(root, varno, subrelids);
3533  }
3534 
3535  /*
3536  * We also need to remove any PlanRowMark referencing the RTE, but we
3537  * postpone that work until we return to remove_useless_result_rtes.
3538  */
3539 }
3540 
3541 
3542 /*
3543  * find_dependent_phvs - are there any PlaceHolderVars whose relids are
3544  * exactly the given varno?
3545  *
3546  * find_dependent_phvs should be used when we want to see if there are
3547  * any such PHVs anywhere in the Query. Another use-case is to see if
3548  * a subtree of the join tree contains such PHVs; but for that, we have
3549  * to look not only at the join tree nodes themselves but at the
3550  * referenced RTEs. For that, use find_dependent_phvs_in_jointree.
3551  */
3552 
3553 typedef struct
3554 {
3558 
3559 static bool
3561  find_dependent_phvs_context *context)
3562 {
3563  if (node == NULL)
3564  return false;
3565  if (IsA(node, PlaceHolderVar))
3566  {
3567  PlaceHolderVar *phv = (PlaceHolderVar *) node;
3568 
3569  if (phv->phlevelsup == context->sublevels_up &&
3570  bms_equal(context->relids, phv->phrels))
3571  return true;
3572  /* fall through to examine children */
3573  }
3574  if (IsA(node, Query))
3575  {
3576  /* Recurse into subselects */
3577  bool result;
3578 
3579  context->sublevels_up++;
3580  result = query_tree_walker((Query *) node,
3582  (void *) context, 0);
3583  context->sublevels_up--;
3584  return result;
3585  }
3586  /* Shouldn't need to handle most planner auxiliary nodes here */
3587  Assert(!IsA(node, SpecialJoinInfo));
3588  Assert(!IsA(node, PlaceHolderInfo));
3589  Assert(!IsA(node, MinMaxAggInfo));
3590 
3592  (void *) context);
3593 }
3594 
3595 static bool
3597 {
3599 
3600  /* If there are no PHVs anywhere, we needn't work hard */
3601  if (root->glob->lastPHId == 0)
3602  return false;
3603 
3604  context.relids = bms_make_singleton(varno);
3605  context.sublevels_up = 0;
3606 
3607  if (query_tree_walker(root->parse,
3609  (void *) &context,
3610  0))
3611  return true;
3612  /* The append_rel_list could be populated already, so check it too */
3615  (void *) &context))
3616  return true;
3617  return false;
3618 }
3619 
3620 static bool
3622 {
3624  Relids subrelids;
3625  int relid;
3626 
3627  /* If there are no PHVs anywhere, we needn't work hard */
3628  if (root->glob->lastPHId == 0)
3629  return false;
3630 
3631  context.relids = bms_make_singleton(varno);
3632  context.sublevels_up = 0;
3633 
3634  /*
3635  * See if the jointree fragment itself contains references (in join quals)
3636  */
3637  if (find_dependent_phvs_walker(node, &context))
3638  return true;
3639 
3640  /*
3641  * Otherwise, identify the set of referenced RTEs (we can ignore joins,
3642  * since they should be flattened already, so their join alias lists no
3643  * longer matter), and tediously check each RTE. We can ignore RTEs that
3644  * are not marked LATERAL, though, since they couldn't possibly contain
3645  * any cross-references to other RTEs.
3646  */
3647  subrelids = get_relids_in_jointree(node, false, false);
3648  relid = -1;
3649  while ((relid = bms_next_member(subrelids, relid)) >= 0)
3650  {
3651  RangeTblEntry *rte = rt_fetch(relid, root->parse->rtable);
3652 
3653  if (rte->lateral &&
3656  (void *) &context,
3657  0))
3658  return true;
3659  }
3660 
3661  return false;
3662 }
3663 
3664 /*
3665  * substitute_phv_relids - adjust PlaceHolderVar relid sets after pulling up
3666  * a subquery or removing an RTE_RESULT jointree item
3667  *
3668  * Find any PlaceHolderVar nodes in the given tree that reference the
3669  * pulled-up relid, and change them to reference the replacement relid(s).
3670  *
3671  * NOTE: although this has the form of a walker, we cheat and modify the
3672  * nodes in-place. This should be OK since the tree was copied by
3673  * pullup_replace_vars earlier. Avoid scribbling on the original values of
3674  * the bitmapsets, though, because expression_tree_mutator doesn't copy those.
3675  */
3676 
3677 typedef struct
3678 {
3679  int varno;
3683 
3684 static bool
3687 {
3688  if (node == NULL)
3689  return false;
3690  if (IsA(node, PlaceHolderVar))
3691  {
3692  PlaceHolderVar *phv = (PlaceHolderVar *) node;
3693 
3694  if (phv->phlevelsup == context->sublevels_up &&
3695  bms_is_member(context->varno, phv->phrels))
3696  {
3697  phv->phrels = bms_union(phv->phrels,
3698  context->subrelids);
3699  phv->phrels = bms_del_member(phv->phrels,
3700  context->varno);
3701  /* Assert we haven't broken the PHV */
3702  Assert(!bms_is_empty(phv->phrels));
3703  }
3704  /* fall through to examine children */
3705  }
3706  if (IsA(node, Query))
3707  {
3708  /* Recurse into subselects */
3709  bool result;
3710 
3711  context->sublevels_up++;
3712  result = query_tree_walker((Query *) node,
3714  (void *) context, 0);
3715  context->sublevels_up--;
3716  return result;
3717  }
3718  /* Shouldn't need to handle planner auxiliary nodes here */
3719  Assert(!IsA(node, SpecialJoinInfo));
3720  Assert(!IsA(node, AppendRelInfo));
3721  Assert(!IsA(node, PlaceHolderInfo));
3722  Assert(!IsA(node, MinMaxAggInfo));
3723 
3725  (void *) context);
3726 }
3727 
3728 static void
3729 substitute_phv_relids(Node *node, int varno, Relids subrelids)
3730 {
3732 
3733  context.varno = varno;
3734  context.sublevels_up = 0;
3735  context.subrelids = subrelids;
3736 
3737  /*
3738  * Must be prepared to start with a Query or a bare expression tree.
3739  */
3742  (void *) &context,
3743  0);
3744 }
3745 
3746 /*
3747  * fix_append_rel_relids: update RT-index fields of AppendRelInfo nodes
3748  *
3749  * When we pull up a subquery, any AppendRelInfo references to the subquery's
3750  * RT index have to be replaced by the substituted relid (and there had better
3751  * be only one). We also need to apply substitute_phv_relids to their
3752  * translated_vars lists, since those might contain PlaceHolderVars.
3753  *
3754  * We assume we may modify the AppendRelInfo nodes in-place.
3755  */
3756 static void
3757 fix_append_rel_relids(PlannerInfo *root, int varno, Relids subrelids)
3758 {
3759  ListCell *l;
3760  int subvarno = -1;
3761 
3762  /*
3763  * We only want to extract the member relid once, but we mustn't fail
3764  * immediately if there are multiple members; it could be that none of the
3765  * AppendRelInfo nodes refer to it. So compute it on first use. Note that
3766  * bms_singleton_member will complain if set is not singleton.
3767  */
3768  foreach(l, root->append_rel_list)
3769  {
3770  AppendRelInfo *appinfo = (AppendRelInfo *) lfirst(l);
3771 
3772  /* The parent_relid shouldn't ever be a pullup target */
3773  Assert(appinfo->parent_relid != varno);
3774 
3775  if (appinfo->child_relid == varno)
3776  {
3777  if (subvarno < 0)
3778  subvarno = bms_singleton_member(subrelids);
3779  appinfo->child_relid = subvarno;
3780  }
3781 
3782  /* Also fix up any PHVs in its translated vars */
3783  if (root->glob->lastPHId != 0)
3785  varno, subrelids);
3786  }
3787 }
3788 
3789 /*
3790  * get_relids_in_jointree: get set of RT indexes present in a jointree
3791  *
3792  * Base-relation relids are always included in the result.
3793  * If include_outer_joins is true, outer-join RT indexes are included.
3794  * If include_inner_joins is true, inner-join RT indexes are included.
3795  *
3796  * Note that for most purposes in the planner, outer joins are included
3797  * in standard relid sets. Setting include_inner_joins true is only
3798  * appropriate for special purposes during subquery flattening.
3799  */
3800 Relids
3801 get_relids_in_jointree(Node *jtnode, bool include_outer_joins,
3802  bool include_inner_joins)
3803 {
3804  Relids result = NULL;
3805 
3806  if (jtnode == NULL)
3807  return result;
3808  if (IsA(jtnode, RangeTblRef))
3809  {
3810  int varno = ((RangeTblRef *) jtnode)->rtindex;
3811 
3812  result = bms_make_singleton(varno);
3813  }
3814  else if (IsA(jtnode, FromExpr))
3815  {
3816  FromExpr *f = (FromExpr *) jtnode;
3817  ListCell *l;
3818 
3819  foreach(l, f->fromlist)
3820  {
3821  result = bms_join(result,
3823  include_outer_joins,
3824  include_inner_joins));
3825  }
3826  }
3827  else if (IsA(jtnode, JoinExpr))
3828  {
3829  JoinExpr *j = (JoinExpr *) jtnode;
3830 
3831  result = get_relids_in_jointree(j->larg,
3832  include_outer_joins,
3833  include_inner_joins);
3834  result = bms_join(result,
3835  get_relids_in_jointree(j->rarg,
3836  include_outer_joins,
3837  include_inner_joins));
3838  if (j->rtindex)
3839  {
3840  if (j->jointype == JOIN_INNER)
3841  {
3842  if (include_inner_joins)
3843  result = bms_add_member(result, j->rtindex);
3844  }
3845  else
3846  {
3847  if (include_outer_joins)
3848  result = bms_add_member(result, j->rtindex);
3849  }
3850  }
3851  }
3852  else
3853  elog(ERROR, "unrecognized node type: %d",
3854  (int) nodeTag(jtnode));
3855  return result;
3856 }
3857 
3858 /*
3859  * get_relids_for_join: get set of base+OJ RT indexes making up a join
3860  */
3861 Relids
3862 get_relids_for_join(Query *query, int joinrelid)
3863 {
3864  Node *jtnode;
3865 
3866  jtnode = find_jointree_node_for_rel((Node *) query->jointree,
3867  joinrelid);
3868  if (!jtnode)
3869  elog(ERROR, "could not find join node %d", joinrelid);
3870  return get_relids_in_jointree(jtnode, true, false);
3871 }
3872 
3873 /*
3874  * find_jointree_node_for_rel: locate jointree node for a base or join RT index
3875  *
3876  * Returns NULL if not found
3877  */
3878 static Node *
3880 {
3881  if (jtnode == NULL)
3882  return NULL;
3883  if (IsA(jtnode, RangeTblRef))
3884  {
3885  int varno = ((RangeTblRef *) jtnode)->rtindex;
3886 
3887  if (relid == varno)
3888  return jtnode;
3889  }
3890  else if (IsA(jtnode, FromExpr))
3891  {
3892  FromExpr *f = (FromExpr *) jtnode;
3893  ListCell *l;
3894 
3895  foreach(l, f->fromlist)
3896  {
3897  jtnode = find_jointree_node_for_rel(lfirst(l), relid);
3898  if (jtnode)
3899  return jtnode;
3900  }
3901  }
3902  else if (IsA(jtnode, JoinExpr))
3903  {
3904  JoinExpr *j = (JoinExpr *) jtnode;
3905 
3906  if (relid == j->rtindex)
3907  return jtnode;
3908  jtnode = find_jointree_node_for_rel(j->larg, relid);
3909  if (jtnode)
3910  return jtnode;
3911  jtnode = find_jointree_node_for_rel(j->rarg, relid);
3912  if (jtnode)
3913  return jtnode;
3914  }
3915  else
3916  elog(ERROR, "unrecognized node type: %d",
3917  (int) nodeTag(jtnode));
3918  return NULL;
3919 }
int16 AttrNumber
Definition: attnum.h:21
#define InvalidAttrNumber
Definition: attnum.h:23
Bitmapset * bms_join(Bitmapset *a, Bitmapset *b)
Definition: bitmapset.c:1051
bool bms_equal(const Bitmapset *a, const Bitmapset *b)
Definition: bitmapset.c:97
int bms_next_member(const Bitmapset *a, int prevbit)
Definition: bitmapset.c:1106
bool bms_is_subset(const Bitmapset *a, const Bitmapset *b)
Definition: bitmapset.c:363
int bms_singleton_member(const Bitmapset *a)
Definition: bitmapset.c:612
void bms_free(Bitmapset *a)
Definition: bitmapset.c:194
bool bms_is_member(int x, const Bitmapset *a)
Definition: bitmapset.c:460
Bitmapset * bms_make_singleton(int x)
Definition: bitmapset.c:171
Bitmapset * bms_add_member(Bitmapset *a, int x)
Definition: bitmapset.c:753
Bitmapset * bms_union(const Bitmapset *a, const Bitmapset *b)
Definition: bitmapset.c:211
Bitmapset * bms_add_members(Bitmapset *a, const Bitmapset *b)
Definition: bitmapset.c:835
Bitmapset * bms_del_member(Bitmapset *a, int x)
Definition: bitmapset.c:793
bool bms_overlap(const Bitmapset *a, const Bitmapset *b)
Definition: bitmapset.c:527
#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:1833
Query * inline_set_returning_function(PlannerInfo *root, RangeTblEntry *rte)
Definition: clauses.c:4958
Relids find_nonnullable_rels(Node *clause)
Definition: clauses.c:1373
List * find_nonnullable_vars(Node *clause)
Definition: clauses.c:1624
Node * eval_const_expressions(PlannerInfo *root, Node *node)
Definition: clauses.c:2171
bool contain_volatile_functions(Node *clause)
Definition: clauses.c:483
#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:338
List * list_concat(List *list1, const List *list2)
Definition: list.c:560
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:1257
MemoryContext CurrentMemoryContext
Definition: mcxt.c:135
void * palloc(Size size)
Definition: mcxt.c:1226
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:121
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:179
#define copyObject(obj)
Definition: nodes.h:244
#define nodeTag(nodeptr)
Definition: nodes.h:133
#define IS_OUTER_JOIN(jointype)
Definition: nodes.h:348
@ CMD_MERGE
Definition: nodes.h:280
@ CMD_SELECT
Definition: nodes.h:276
#define makeNode(_type_)
Definition: nodes.h:176
#define castNode(_type_, nodeptr)
Definition: nodes.h:197
JoinType
Definition: nodes.h:299
@ JOIN_SEMI
Definition: nodes.h:318
@ JOIN_FULL
Definition: nodes.h:306
@ JOIN_INNER
Definition: nodes.h:304
@ JOIN_RIGHT
Definition: nodes.h:307
@ JOIN_LEFT
Definition: nodes.h:305
@ JOIN_ANTI
Definition: nodes.h:319
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:1973
@ RTE_JOIN
Definition: parsenodes.h:1015
@ RTE_CTE
Definition: parsenodes.h:1019
@ RTE_NAMEDTUPLESTORE
Definition: parsenodes.h:1020
@ RTE_VALUES
Definition: parsenodes.h:1018
@ RTE_SUBQUERY
Definition: parsenodes.h:1014
@ RTE_RESULT
Definition: parsenodes.h:1021
@ RTE_FUNCTION
Definition: parsenodes.h:1016
@ RTE_TABLEFUNC
Definition: parsenodes.h:1017
@ RTE_RELATION
Definition: parsenodes.h:1013
#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:467
#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
#define foreach_delete_current(lst, cell)
Definition: pg_list.h:390
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:926
@ EXISTS_SUBLINK
Definition: primnodes.h:924
@ COERCE_IMPLICIT_CAST
Definition: primnodes.h:663
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:2929
List * translated_vars
Definition: pathnodes.h:2956
Index parent_relid
Definition: pathnodes.h:2928
int num_child_cols
Definition: pathnodes.h:2964
Oid parent_reltype
Definition: pathnodes.h:2937
Node * quals
Definition: primnodes.h:2014
List * fromlist
Definition: primnodes.h:2013
Node * quals
Definition: primnodes.h:1994
JoinType jointype
Definition: primnodes.h:1985
int rtindex
Definition: primnodes.h:1998
Node * larg
Definition: primnodes.h:1987
bool isNatural
Definition: primnodes.h:1986
Node * rarg
Definition: primnodes.h:1988
Definition: pg_list.h:54
Definition: nodes.h:129
Relids phnullingrels
Definition: pathnodes.h:2753
Index phlevelsup
Definition: pathnodes.h:2759
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:214
Node * limitCount
Definition: parsenodes.h:211
FromExpr * jointree
Definition: parsenodes.h:181
Node * setOperations
Definition: parsenodes.h:216
List * cteList
Definition: parsenodes.h:172
List * groupClause
Definition: parsenodes.h:197
Node * havingQual
Definition: parsenodes.h:202
List * rtable
Definition: parsenodes.h:174
Node * limitOffset
Definition: parsenodes.h:210
CmdType commandType
Definition: parsenodes.h:127
List * targetList
Definition: parsenodes.h:188
List * groupingSets
Definition: parsenodes.h:200
List * distinctClause
Definition: parsenodes.h:206
List * sortClause
Definition: parsenodes.h:208
TableFunc * tablefunc
Definition: parsenodes.h:1153
bool security_barrier
Definition: parsenodes.h:1081
bool funcordinality
Definition: parsenodes.h:1148
Alias * join_using_alias
Definition: parsenodes.h:1137
struct TableSampleClause * tablesample
Definition: parsenodes.h:1074
Query * subquery
Definition: parsenodes.h:1080
Alias * eref
Definition: parsenodes.h:1199
List * joinrightcols
Definition: parsenodes.h:1130
List * values_lists
Definition: parsenodes.h:1158
List * joinaliasvars
Definition: parsenodes.h:1128
JoinType jointype
Definition: parsenodes.h:1126
Alias * alias
Definition: parsenodes.h:1198
List * functions
Definition: parsenodes.h:1147
List * joinleftcols
Definition: parsenodes.h:1129
RTEKind rtekind
Definition: parsenodes.h:1032
int location
Definition: primnodes.h:1362
List * args
Definition: primnodes.h:1338
SetOperation op
Definition: parsenodes.h:2050
Expr * expr
Definition: primnodes.h:1895
AttrNumber resno
Definition: primnodes.h:1897
Definition: primnodes.h:226
AttrNumber varattno
Definition: primnodes.h:238
int varno
Definition: primnodes.h:233
Index varlevelsup
Definition: primnodes.h:258
int location
Definition: primnodes.h:271
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:1375
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