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