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