1 /*-------------------------------------------------------------------------
4 * Planner preprocessing for subqueries and join tree manipulation.
6 * NOTE: the intended sequence for invoking these operations is
8 * inline_set_returning_functions
10 * flatten_simple_union_all
11 * do expression preprocessing (including flattening JOIN alias vars)
15 * Portions Copyright (c) 1996-2011, PostgreSQL Global Development Group
16 * Portions Copyright (c) 1994, Regents of the University of California
20 * src/backend/optimizer/prep/prepjointree.c
22 *-------------------------------------------------------------------------
26 #include "catalog/pg_type.h"
27 #include "nodes/makefuncs.h"
28 #include "nodes/nodeFuncs.h"
29 #include "optimizer/clauses.h"
30 #include "optimizer/placeholder.h"
31 #include "optimizer/prep.h"
32 #include "optimizer/subselect.h"
33 #include "optimizer/tlist.h"
34 #include "optimizer/var.h"
35 #include "parser/parse_relation.h"
36 #include "parser/parsetree.h"
37 #include "rewrite/rewriteManip.h"
40 typedef struct pullup_replace_vars_context
43 List *targetlist; /* tlist of subquery being pulled up */
44 RangeTblEntry *target_rte; /* RTE of subquery */
45 bool *outer_hasSubLinks; /* -> outer query's hasSubLinks */
46 int varno; /* varno of subquery */
47 bool need_phvs; /* do we need PlaceHolderVars? */
48 bool wrap_non_vars; /* do we need 'em on *all* non-Vars? */
49 Node **rv_cache; /* cache for results with PHVs */
50 } pullup_replace_vars_context;
52 typedef struct reduce_outer_joins_state
54 Relids relids; /* base relids within this subtree */
55 bool contains_outer; /* does subtree contain outer join(s)? */
56 List *sub_states; /* List of states for subtree components */
57 } reduce_outer_joins_state;
59 static Node *pull_up_sublinks_jointree_recurse(PlannerInfo *root, Node *jtnode,
61 static Node *pull_up_sublinks_qual_recurse(PlannerInfo *root, Node *node,
62 Relids available_rels, Node **jtlink);
63 static Node *pull_up_simple_subquery(PlannerInfo *root, Node *jtnode,
65 JoinExpr *lowest_outer_join,
66 AppendRelInfo *containing_appendrel);
67 static Node *pull_up_simple_union_all(PlannerInfo *root, Node *jtnode,
69 static void pull_up_union_leaf_queries(Node *setOp, PlannerInfo *root,
70 int parentRTindex, Query *setOpQuery,
72 static void make_setop_translation_list(Query *query, Index newvarno,
73 List **translated_vars);
74 static bool is_simple_subquery(Query *subquery);
75 static bool is_simple_union_all(Query *subquery);
76 static bool is_simple_union_all_recurse(Node *setOp, Query *setOpQuery,
78 static bool is_safe_append_member(Query *subquery);
79 static void replace_vars_in_jointree(Node *jtnode,
80 pullup_replace_vars_context *context,
81 JoinExpr *lowest_outer_join);
82 static Node *pullup_replace_vars(Node *expr,
83 pullup_replace_vars_context *context);
84 static Node *pullup_replace_vars_callback(Var *var,
85 replace_rte_variables_context *context);
86 static reduce_outer_joins_state *reduce_outer_joins_pass1(Node *jtnode);
87 static void reduce_outer_joins_pass2(Node *jtnode,
88 reduce_outer_joins_state *state,
90 Relids nonnullable_rels,
91 List *nonnullable_vars,
92 List *forced_null_vars);
93 static void substitute_multiple_relids(Node *node,
94 int varno, Relids subrelids);
95 static void fix_append_rel_relids(List *append_rel_list, int varno,
97 static Node *find_jointree_node_for_rel(Node *jtnode, int relid);
102 * Attempt to pull up ANY and EXISTS SubLinks to be treated as
103 * semijoins or anti-semijoins.
105 * A clause "foo op ANY (sub-SELECT)" can be processed by pulling the
106 * sub-SELECT up to become a rangetable entry and treating the implied
107 * comparisons as quals of a semijoin. However, this optimization *only*
108 * works at the top level of WHERE or a JOIN/ON clause, because we cannot
109 * distinguish whether the ANY ought to return FALSE or NULL in cases
110 * involving NULL inputs. Also, in an outer join's ON clause we can only
111 * do this if the sublink is degenerate (ie, references only the nullable
112 * side of the join). In that case it is legal to push the semijoin
113 * down into the nullable side of the join. If the sublink references any
114 * nonnullable-side variables then it would have to be evaluated as part
115 * of the outer join, which makes things way too complicated.
117 * Under similar conditions, EXISTS and NOT EXISTS clauses can be handled
118 * by pulling up the sub-SELECT and creating a semijoin or anti-semijoin.
120 * This routine searches for such clauses and does the necessary parsetree
121 * transformations if any are found.
123 * This routine has to run before preprocess_expression(), so the quals
124 * clauses are not yet reduced to implicit-AND format. That means we need
125 * to recursively search through explicit AND clauses, which are
126 * probably only binary ANDs. We stop as soon as we hit a non-AND item.
129 pull_up_sublinks(PlannerInfo *root)
134 /* Begin recursion through the jointree */
135 jtnode = pull_up_sublinks_jointree_recurse(root,
136 (Node *) root->parse->jointree,
140 * root->parse->jointree must always be a FromExpr, so insert a dummy one
141 * if we got a bare RangeTblRef or JoinExpr out of the recursion.
143 if (IsA(jtnode, FromExpr))
144 root->parse->jointree = (FromExpr *) jtnode;
146 root->parse->jointree = makeFromExpr(list_make1(jtnode), NULL);
150 * Recurse through jointree nodes for pull_up_sublinks()
152 * In addition to returning the possibly-modified jointree node, we return
153 * a relids set of the contained rels into *relids.
156 pull_up_sublinks_jointree_recurse(PlannerInfo *root, Node *jtnode,
163 else if (IsA(jtnode, RangeTblRef))
165 int varno = ((RangeTblRef *) jtnode)->rtindex;
167 *relids = bms_make_singleton(varno);
168 /* jtnode is returned unmodified */
170 else if (IsA(jtnode, FromExpr))
172 FromExpr *f = (FromExpr *) jtnode;
173 List *newfromlist = NIL;
174 Relids frelids = NULL;
179 /* First, recurse to process children and collect their relids */
180 foreach(l, f->fromlist)
185 newchild = pull_up_sublinks_jointree_recurse(root,
188 newfromlist = lappend(newfromlist, newchild);
189 frelids = bms_join(frelids, childrelids);
191 /* Build the replacement FromExpr; no quals yet */
192 newf = makeFromExpr(newfromlist, NULL);
193 /* Set up a link representing the rebuilt jointree */
194 jtlink = (Node *) newf;
195 /* Now process qual --- all children are available for use */
196 newf->quals = pull_up_sublinks_qual_recurse(root, f->quals, frelids,
200 * Note that the result will be either newf, or a stack of JoinExprs
201 * with newf at the base. We rely on subsequent optimization steps to
202 * flatten this and rearrange the joins as needed.
204 * Although we could include the pulled-up subqueries in the returned
205 * relids, there's no need since upper quals couldn't refer to their
211 else if (IsA(jtnode, JoinExpr))
219 * Make a modifiable copy of join node, but don't bother copying its
222 j = (JoinExpr *) palloc(sizeof(JoinExpr));
223 memcpy(j, jtnode, sizeof(JoinExpr));
226 /* Recurse to process children and collect their relids */
227 j->larg = pull_up_sublinks_jointree_recurse(root, j->larg,
229 j->rarg = pull_up_sublinks_jointree_recurse(root, j->rarg,
233 * Now process qual, showing appropriate child relids as available,
234 * and attach any pulled-up jointree items at the right place. In the
235 * inner-join case we put new JoinExprs above the existing one (much
236 * as for a FromExpr-style join). In outer-join cases the new
237 * JoinExprs must go into the nullable side of the outer join. The
238 * point of the available_rels machinations is to ensure that we only
239 * pull up quals for which that's okay.
241 * XXX for the moment, we refrain from pulling up IN/EXISTS clauses
242 * appearing in LEFT or RIGHT join conditions. Although it is
243 * semantically valid to do so under the above conditions, we end up
244 * with a query in which the semijoin or antijoin must be evaluated
245 * below the outer join, which could perform far worse than leaving it
246 * as a sublink that is executed only for row pairs that meet the
247 * other join conditions. Fixing this seems to require considerable
248 * restructuring of the executor, but maybe someday it can happen.
249 * (See also the comparable case in pull_up_sublinks_qual_recurse.)
251 * We don't expect to see any pre-existing JOIN_SEMI or JOIN_ANTI
257 j->quals = pull_up_sublinks_qual_recurse(root, j->quals,
258 bms_union(leftrelids,
263 #ifdef NOT_USED /* see XXX comment above */
264 j->quals = pull_up_sublinks_qual_recurse(root, j->quals,
270 /* can't do anything with full-join quals */
273 #ifdef NOT_USED /* see XXX comment above */
274 j->quals = pull_up_sublinks_qual_recurse(root, j->quals,
280 elog(ERROR, "unrecognized join type: %d",
286 * Although we could include the pulled-up subqueries in the returned
287 * relids, there's no need since upper quals couldn't refer to their
288 * outputs anyway. But we *do* need to include the join's own rtindex
289 * because we haven't yet collapsed join alias variables, so upper
290 * levels would mistakenly think they couldn't use references to this
293 *relids = bms_join(leftrelids, rightrelids);
295 *relids = bms_add_member(*relids, j->rtindex);
299 elog(ERROR, "unrecognized node type: %d",
300 (int) nodeTag(jtnode));
305 * Recurse through top-level qual nodes for pull_up_sublinks()
307 * jtlink points to the link in the jointree where any new JoinExprs should be
308 * inserted. If we find multiple pull-up-able SubLinks, they'll get stacked
309 * there in the order we encounter them. We rely on subsequent optimization
310 * to rearrange the stack if appropriate.
313 pull_up_sublinks_qual_recurse(PlannerInfo *root, Node *node,
314 Relids available_rels, Node **jtlink)
318 if (IsA(node, SubLink))
320 SubLink *sublink = (SubLink *) node;
324 /* Is it a convertible ANY or EXISTS clause? */
325 if (sublink->subLinkType == ANY_SUBLINK)
327 j = convert_ANY_sublink_to_join(root, sublink,
331 /* Yes; recursively process what we pulled up */
332 j->rarg = pull_up_sublinks_jointree_recurse(root,
335 /* Any inserted joins get stacked onto j->rarg */
336 j->quals = pull_up_sublinks_qual_recurse(root,
340 /* Now insert the new join node into the join tree */
342 *jtlink = (Node *) j;
343 /* and return NULL representing constant TRUE */
347 else if (sublink->subLinkType == EXISTS_SUBLINK)
349 j = convert_EXISTS_sublink_to_join(root, sublink, false,
353 /* Yes; recursively process what we pulled up */
354 j->rarg = pull_up_sublinks_jointree_recurse(root,
357 /* Any inserted joins get stacked onto j->rarg */
358 j->quals = pull_up_sublinks_qual_recurse(root,
362 /* Now insert the new join node into the join tree */
364 *jtlink = (Node *) j;
365 /* and return NULL representing constant TRUE */
369 /* Else return it unmodified */
372 if (not_clause(node))
374 /* If the immediate argument of NOT is EXISTS, try to convert */
375 SubLink *sublink = (SubLink *) get_notclausearg((Expr *) node);
378 if (sublink && IsA(sublink, SubLink))
380 if (sublink->subLinkType == EXISTS_SUBLINK)
382 j = convert_EXISTS_sublink_to_join(root, sublink, true,
387 * For the moment, refrain from recursing underneath NOT.
388 * As in pull_up_sublinks_jointree_recurse, recursing here
389 * would result in inserting a join underneath an ANTI
390 * join with which it could not commute, and that could
391 * easily lead to a worse plan than what we've
392 * historically generated.
395 /* Yes; recursively process what we pulled up */
398 j->rarg = pull_up_sublinks_jointree_recurse(root,
401 /* Any inserted joins get stacked onto j->rarg */
402 j->quals = pull_up_sublinks_qual_recurse(root,
407 /* Now insert the new join node into the join tree */
409 *jtlink = (Node *) j;
410 /* and return NULL representing constant TRUE */
415 /* Else return it unmodified */
418 if (and_clause(node))
420 /* Recurse into AND clause */
421 List *newclauses = NIL;
424 foreach(l, ((BoolExpr *) node)->args)
426 Node *oldclause = (Node *) lfirst(l);
429 newclause = pull_up_sublinks_qual_recurse(root,
434 newclauses = lappend(newclauses, newclause);
436 /* We might have got back fewer clauses than we started with */
437 if (newclauses == NIL)
439 else if (list_length(newclauses) == 1)
440 return (Node *) linitial(newclauses);
442 return (Node *) make_andclause(newclauses);
444 /* Stop if not an AND */
449 * inline_set_returning_functions
450 * Attempt to "inline" set-returning functions in the FROM clause.
452 * If an RTE_FUNCTION rtable entry invokes a set-returning function that
453 * contains just a simple SELECT, we can convert the rtable entry to an
454 * RTE_SUBQUERY entry exposing the SELECT directly. This is especially
455 * useful if the subquery can then be "pulled up" for further optimization,
456 * but we do it even if not, to reduce executor overhead.
458 * This has to be done before we have started to do any optimization of
459 * subqueries, else any such steps wouldn't get applied to subqueries
460 * obtained via inlining. However, we do it after pull_up_sublinks
461 * so that we can inline any functions used in SubLink subselects.
463 * Like most of the planner, this feels free to scribble on its input data
467 inline_set_returning_functions(PlannerInfo *root)
471 foreach(rt, root->parse->rtable)
473 RangeTblEntry *rte = (RangeTblEntry *) lfirst(rt);
475 if (rte->rtekind == RTE_FUNCTION)
479 /* Check safety of expansion, and expand if possible */
480 funcquery = inline_set_returning_function(root, rte);
483 /* Successful expansion, replace the rtable entry */
484 rte->rtekind = RTE_SUBQUERY;
485 rte->subquery = funcquery;
486 rte->funcexpr = NULL;
487 rte->funccoltypes = NIL;
488 rte->funccoltypmods = NIL;
489 rte->funccolcollations = NIL;
497 * Look for subqueries in the rangetable that can be pulled up into
498 * the parent query. If the subquery has no special features like
499 * grouping/aggregation then we can merge it into the parent's jointree.
500 * Also, subqueries that are simple UNION ALL structures can be
501 * converted into "append relations".
503 * If this jointree node is within the nullable side of an outer join, then
504 * lowest_outer_join references the lowest such JoinExpr node; otherwise it
505 * is NULL. This forces use of the PlaceHolderVar mechanism for references
506 * to non-nullable targetlist items, but only for references above that join.
508 * If we are looking at a member subquery of an append relation,
509 * containing_appendrel describes that relation; else it is NULL.
510 * This forces use of the PlaceHolderVar mechanism for all non-Var targetlist
511 * items, and puts some additional restrictions on what can be pulled up.
513 * A tricky aspect of this code is that if we pull up a subquery we have
514 * to replace Vars that reference the subquery's outputs throughout the
515 * parent query, including quals attached to jointree nodes above the one
516 * we are currently processing! We handle this by being careful not to
517 * change the jointree structure while recursing: no nodes other than
518 * subquery RangeTblRef entries will be replaced. Also, we can't turn
519 * pullup_replace_vars loose on the whole jointree, because it'll return a
520 * mutated copy of the tree; we have to invoke it just on the quals, instead.
521 * This behavior is what makes it reasonable to pass lowest_outer_join as a
522 * pointer rather than some more-indirect way of identifying the lowest OJ.
523 * Likewise, we don't replace append_rel_list members but only their
524 * substructure, so the containing_appendrel reference is safe to use.
527 pull_up_subqueries(PlannerInfo *root, Node *jtnode,
528 JoinExpr *lowest_outer_join,
529 AppendRelInfo *containing_appendrel)
533 if (IsA(jtnode, RangeTblRef))
535 int varno = ((RangeTblRef *) jtnode)->rtindex;
536 RangeTblEntry *rte = rt_fetch(varno, root->parse->rtable);
539 * Is this a subquery RTE, and if so, is the subquery simple enough to
542 * If we are looking at an append-relation member, we can't pull it up
543 * unless is_safe_append_member says so.
545 if (rte->rtekind == RTE_SUBQUERY &&
546 is_simple_subquery(rte->subquery) &&
547 (containing_appendrel == NULL ||
548 is_safe_append_member(rte->subquery)))
549 return pull_up_simple_subquery(root, jtnode, rte,
551 containing_appendrel);
554 * Alternatively, is it a simple UNION ALL subquery? If so, flatten
555 * into an "append relation".
557 * It's safe to do this regardless of whether this query is itself an
558 * appendrel member. (If you're thinking we should try to flatten the
559 * two levels of appendrel together, you're right; but we handle that
560 * in set_append_rel_pathlist, not here.)
562 if (rte->rtekind == RTE_SUBQUERY &&
563 is_simple_union_all(rte->subquery))
564 return pull_up_simple_union_all(root, jtnode, rte);
566 /* Otherwise, do nothing at this node. */
568 else if (IsA(jtnode, FromExpr))
570 FromExpr *f = (FromExpr *) jtnode;
573 Assert(containing_appendrel == NULL);
574 foreach(l, f->fromlist)
575 lfirst(l) = pull_up_subqueries(root, lfirst(l),
576 lowest_outer_join, NULL);
578 else if (IsA(jtnode, JoinExpr))
580 JoinExpr *j = (JoinExpr *) jtnode;
582 Assert(containing_appendrel == NULL);
583 /* Recurse, being careful to tell myself when inside outer join */
587 j->larg = pull_up_subqueries(root, j->larg,
588 lowest_outer_join, NULL);
589 j->rarg = pull_up_subqueries(root, j->rarg,
590 lowest_outer_join, NULL);
595 j->larg = pull_up_subqueries(root, j->larg,
596 lowest_outer_join, NULL);
597 j->rarg = pull_up_subqueries(root, j->rarg,
601 j->larg = pull_up_subqueries(root, j->larg,
603 j->rarg = pull_up_subqueries(root, j->rarg,
607 j->larg = pull_up_subqueries(root, j->larg,
609 j->rarg = pull_up_subqueries(root, j->rarg,
610 lowest_outer_join, NULL);
613 elog(ERROR, "unrecognized join type: %d",
619 elog(ERROR, "unrecognized node type: %d",
620 (int) nodeTag(jtnode));
625 * pull_up_simple_subquery
626 * Attempt to pull up a single simple subquery.
628 * jtnode is a RangeTblRef that has been tentatively identified as a simple
629 * subquery by pull_up_subqueries. We return the replacement jointree node,
630 * or jtnode itself if we determine that the subquery can't be pulled up after
633 * rte is the RangeTblEntry referenced by jtnode. Remaining parameters are
634 * as for pull_up_subqueries.
637 pull_up_simple_subquery(PlannerInfo *root, Node *jtnode, RangeTblEntry *rte,
638 JoinExpr *lowest_outer_join,
639 AppendRelInfo *containing_appendrel)
641 Query *parse = root->parse;
642 int varno = ((RangeTblRef *) jtnode)->rtindex;
644 PlannerInfo *subroot;
646 pullup_replace_vars_context rvcontext;
650 * Need a modifiable copy of the subquery to hack on. Even if we didn't
651 * sometimes choose not to pull up below, we must do this to avoid
652 * problems if the same subquery is referenced from multiple jointree
653 * items (which can't happen normally, but might after rule rewriting).
655 subquery = copyObject(rte->subquery);
658 * Create a PlannerInfo data structure for this subquery.
660 * NOTE: the next few steps should match the first processing in
661 * subquery_planner(). Can we refactor to avoid code duplication, or
662 * would that just make things uglier?
664 subroot = makeNode(PlannerInfo);
665 subroot->parse = subquery;
666 subroot->glob = root->glob;
667 subroot->query_level = root->query_level;
668 subroot->parent_root = root->parent_root;
669 subroot->planner_cxt = CurrentMemoryContext;
670 subroot->init_plans = NIL;
671 subroot->cte_plan_ids = NIL;
672 subroot->eq_classes = NIL;
673 subroot->append_rel_list = NIL;
674 subroot->rowMarks = NIL;
675 subroot->hasRecursion = false;
676 subroot->wt_param_id = -1;
677 subroot->non_recursive_plan = NULL;
679 /* No CTEs to worry about */
680 Assert(subquery->cteList == NIL);
683 * Pull up any SubLinks within the subquery's quals, so that we don't
684 * leave unoptimized SubLinks behind.
686 if (subquery->hasSubLinks)
687 pull_up_sublinks(subroot);
690 * Similarly, inline any set-returning functions in its rangetable.
692 inline_set_returning_functions(subroot);
695 * Recursively pull up the subquery's subqueries, so that
696 * pull_up_subqueries' processing is complete for its jointree and
699 * Note: we should pass NULL for containing-join info even if we are
700 * within an outer join in the upper query; the lower query starts with a
701 * clean slate for outer-join semantics. Likewise, we say we aren't
702 * handling an appendrel member.
704 subquery->jointree = (FromExpr *)
705 pull_up_subqueries(subroot, (Node *) subquery->jointree, NULL, NULL);
708 * Now we must recheck whether the subquery is still simple enough to pull
709 * up. If not, abandon processing it.
711 * We don't really need to recheck all the conditions involved, but it's
712 * easier just to keep this "if" looking the same as the one in
713 * pull_up_subqueries.
715 if (is_simple_subquery(subquery) &&
716 (containing_appendrel == NULL || is_safe_append_member(subquery)))
723 * Give up, return unmodified RangeTblRef.
725 * Note: The work we just did will be redone when the subquery gets
726 * planned on its own. Perhaps we could avoid that by storing the
727 * modified subquery back into the rangetable, but I'm not gonna risk
734 * Adjust level-0 varnos in subquery so that we can append its rangetable
735 * to upper query's. We have to fix the subquery's append_rel_list as
738 rtoffset = list_length(parse->rtable);
739 OffsetVarNodes((Node *) subquery, rtoffset, 0);
740 OffsetVarNodes((Node *) subroot->append_rel_list, rtoffset, 0);
743 * Upper-level vars in subquery are now one level closer to their parent
746 IncrementVarSublevelsUp((Node *) subquery, -1, 1);
747 IncrementVarSublevelsUp((Node *) subroot->append_rel_list, -1, 1);
750 * The subquery's targetlist items are now in the appropriate form to
751 * insert into the top query, but if we are under an outer join then
752 * non-nullable items may have to be turned into PlaceHolderVars. If we
753 * are dealing with an appendrel member then anything that's not a simple
754 * Var has to be turned into a PlaceHolderVar. Set up appropriate context
755 * data for pullup_replace_vars.
757 rvcontext.root = root;
758 rvcontext.targetlist = subquery->targetList;
759 rvcontext.target_rte = rte;
760 rvcontext.outer_hasSubLinks = &parse->hasSubLinks;
761 rvcontext.varno = varno;
762 rvcontext.need_phvs = (lowest_outer_join != NULL ||
763 containing_appendrel != NULL);
764 rvcontext.wrap_non_vars = (containing_appendrel != NULL);
765 /* initialize cache array with indexes 0 .. length(tlist) */
766 rvcontext.rv_cache = palloc0((list_length(subquery->targetList) + 1) *
770 * Replace all of the top query's references to the subquery's outputs
771 * with copies of the adjusted subtlist items, being careful not to
772 * replace any of the jointree structure. (This'd be a lot cleaner if we
773 * could use query_tree_mutator.) We have to use PHVs in the targetList,
774 * returningList, and havingQual, since those are certainly above any
775 * outer join. replace_vars_in_jointree tracks its location in the
776 * jointree and uses PHVs or not appropriately.
778 parse->targetList = (List *)
779 pullup_replace_vars((Node *) parse->targetList, &rvcontext);
780 parse->returningList = (List *)
781 pullup_replace_vars((Node *) parse->returningList, &rvcontext);
782 replace_vars_in_jointree((Node *) parse->jointree, &rvcontext,
784 Assert(parse->setOperations == NULL);
785 parse->havingQual = pullup_replace_vars(parse->havingQual, &rvcontext);
788 * Replace references in the translated_vars lists of appendrels. When
789 * pulling up an appendrel member, we do not need PHVs in the list of the
790 * parent appendrel --- there isn't any outer join between. Elsewhere, use
791 * PHVs for safety. (This analysis could be made tighter but it seems
792 * unlikely to be worth much trouble.)
794 foreach(lc, root->append_rel_list)
796 AppendRelInfo *appinfo = (AppendRelInfo *) lfirst(lc);
797 bool save_need_phvs = rvcontext.need_phvs;
799 if (appinfo == containing_appendrel)
800 rvcontext.need_phvs = false;
801 appinfo->translated_vars = (List *)
802 pullup_replace_vars((Node *) appinfo->translated_vars, &rvcontext);
803 rvcontext.need_phvs = save_need_phvs;
807 * Replace references in the joinaliasvars lists of join RTEs.
809 * You might think that we could avoid using PHVs for alias vars of joins
810 * below lowest_outer_join, but that doesn't work because the alias vars
811 * could be referenced above that join; we need the PHVs to be present in
812 * such references after the alias vars get flattened. (It might be worth
813 * trying to be smarter here, someday.)
815 foreach(lc, parse->rtable)
817 RangeTblEntry *otherrte = (RangeTblEntry *) lfirst(lc);
819 if (otherrte->rtekind == RTE_JOIN)
820 otherrte->joinaliasvars = (List *)
821 pullup_replace_vars((Node *) otherrte->joinaliasvars,
826 * Now append the adjusted rtable entries to upper query. (We hold off
827 * until after fixing the upper rtable entries; no point in running that
828 * code on the subquery ones too.)
830 parse->rtable = list_concat(parse->rtable, subquery->rtable);
833 * Pull up any FOR UPDATE/SHARE markers, too. (OffsetVarNodes already
834 * adjusted the marker rtindexes, so just concat the lists.)
836 parse->rowMarks = list_concat(parse->rowMarks, subquery->rowMarks);
839 * We also have to fix the relid sets of any PlaceHolderVar nodes in the
840 * parent query. (This could perhaps be done by pullup_replace_vars(),
841 * but it seems cleaner to use two passes.) Note in particular that any
842 * PlaceHolderVar nodes just created by pullup_replace_vars() will be
843 * adjusted, so having created them with the subquery's varno is correct.
845 * Likewise, relids appearing in AppendRelInfo nodes have to be fixed. We
846 * already checked that this won't require introducing multiple subrelids
847 * into the single-slot AppendRelInfo structs.
849 if (parse->hasSubLinks || root->glob->lastPHId != 0 ||
850 root->append_rel_list)
854 subrelids = get_relids_in_jointree((Node *) subquery->jointree, false);
855 substitute_multiple_relids((Node *) parse, varno, subrelids);
856 fix_append_rel_relids(root->append_rel_list, varno, subrelids);
860 * And now add subquery's AppendRelInfos to our list.
862 root->append_rel_list = list_concat(root->append_rel_list,
863 subroot->append_rel_list);
866 * We don't have to do the equivalent bookkeeping for outer-join info,
867 * because that hasn't been set up yet. placeholder_list likewise.
869 Assert(root->join_info_list == NIL);
870 Assert(subroot->join_info_list == NIL);
871 Assert(root->placeholder_list == NIL);
872 Assert(subroot->placeholder_list == NIL);
875 * Miscellaneous housekeeping.
877 * Although replace_rte_variables() faithfully updated parse->hasSubLinks
878 * if it copied any SubLinks out of the subquery's targetlist, we still
879 * could have SubLinks added to the query in the expressions of FUNCTION
880 * and VALUES RTEs copied up from the subquery. So it's necessary to copy
881 * subquery->hasSubLinks anyway. Perhaps this can be improved someday.
883 parse->hasSubLinks |= subquery->hasSubLinks;
886 * subquery won't be pulled up if it hasAggs or hasWindowFuncs, so no work
887 * needed on those flags
891 * Return the adjusted subquery jointree to replace the RangeTblRef entry
892 * in parent's jointree.
894 return (Node *) subquery->jointree;
898 * pull_up_simple_union_all
899 * Pull up a single simple UNION ALL subquery.
901 * jtnode is a RangeTblRef that has been identified as a simple UNION ALL
902 * subquery by pull_up_subqueries. We pull up the leaf subqueries and
903 * build an "append relation" for the union set. The result value is just
904 * jtnode, since we don't actually need to change the query jointree.
907 pull_up_simple_union_all(PlannerInfo *root, Node *jtnode, RangeTblEntry *rte)
909 int varno = ((RangeTblRef *) jtnode)->rtindex;
910 Query *subquery = rte->subquery;
915 * Append child RTEs to parent rtable.
917 * Upper-level vars in subquery are now one level closer to their parent
918 * than before. We don't have to worry about offsetting varnos, though,
919 * because any such vars must refer to stuff above the level of the query
920 * we are pulling into.
922 rtoffset = list_length(root->parse->rtable);
923 rtable = copyObject(subquery->rtable);
924 IncrementVarSublevelsUp_rtable(rtable, -1, 1);
925 root->parse->rtable = list_concat(root->parse->rtable, rtable);
928 * Recursively scan the subquery's setOperations tree and add
929 * AppendRelInfo nodes for leaf subqueries to the parent's
930 * append_rel_list. Also apply pull_up_subqueries to the leaf subqueries.
932 Assert(subquery->setOperations);
933 pull_up_union_leaf_queries(subquery->setOperations, root, varno, subquery,
937 * Mark the parent as an append relation.
945 * pull_up_union_leaf_queries -- recursive guts of pull_up_simple_union_all
947 * Build an AppendRelInfo for each leaf query in the setop tree, and then
948 * apply pull_up_subqueries to the leaf query.
950 * Note that setOpQuery is the Query containing the setOp node, whose tlist
951 * contains references to all the setop output columns. When called from
952 * pull_up_simple_union_all, this is *not* the same as root->parse, which is
953 * the parent Query we are pulling up into.
955 * parentRTindex is the appendrel parent's index in root->parse->rtable.
957 * The child RTEs have already been copied to the parent. childRToffset
958 * tells us where in the parent's range table they were copied. When called
959 * from flatten_simple_union_all, childRToffset is 0 since the child RTEs
960 * were already in root->parse->rtable and no RT index adjustment is needed.
963 pull_up_union_leaf_queries(Node *setOp, PlannerInfo *root, int parentRTindex,
964 Query *setOpQuery, int childRToffset)
966 if (IsA(setOp, RangeTblRef))
968 RangeTblRef *rtr = (RangeTblRef *) setOp;
970 AppendRelInfo *appinfo;
973 * Calculate the index in the parent's range table
975 childRTindex = childRToffset + rtr->rtindex;
978 * Build a suitable AppendRelInfo, and attach to parent's list.
980 appinfo = makeNode(AppendRelInfo);
981 appinfo->parent_relid = parentRTindex;
982 appinfo->child_relid = childRTindex;
983 appinfo->parent_reltype = InvalidOid;
984 appinfo->child_reltype = InvalidOid;
985 make_setop_translation_list(setOpQuery, childRTindex,
986 &appinfo->translated_vars);
987 appinfo->parent_reloid = InvalidOid;
988 root->append_rel_list = lappend(root->append_rel_list, appinfo);
991 * Recursively apply pull_up_subqueries to the new child RTE. (We
992 * must build the AppendRelInfo first, because this will modify it.)
993 * Note that we can pass NULL for containing-join info even if we're
994 * actually under an outer join, because the child's expressions
995 * aren't going to propagate up above the join.
997 rtr = makeNode(RangeTblRef);
998 rtr->rtindex = childRTindex;
999 (void) pull_up_subqueries(root, (Node *) rtr, NULL, appinfo);
1001 else if (IsA(setOp, SetOperationStmt))
1003 SetOperationStmt *op = (SetOperationStmt *) setOp;
1005 /* Recurse to reach leaf queries */
1006 pull_up_union_leaf_queries(op->larg, root, parentRTindex, setOpQuery,
1008 pull_up_union_leaf_queries(op->rarg, root, parentRTindex, setOpQuery,
1013 elog(ERROR, "unrecognized node type: %d",
1014 (int) nodeTag(setOp));
1019 * make_setop_translation_list
1020 * Build the list of translations from parent Vars to child Vars for
1021 * a UNION ALL member. (At this point it's just a simple list of
1022 * referencing Vars, but if we succeed in pulling up the member
1023 * subquery, the Vars will get replaced by pulled-up expressions.)
1026 make_setop_translation_list(Query *query, Index newvarno,
1027 List **translated_vars)
1032 foreach(l, query->targetList)
1034 TargetEntry *tle = (TargetEntry *) lfirst(l);
1039 vars = lappend(vars, makeVarFromTargetEntry(newvarno, tle));
1042 *translated_vars = vars;
1046 * is_simple_subquery
1047 * Check a subquery in the range table to see if it's simple enough
1048 * to pull up into the parent query.
1051 is_simple_subquery(Query *subquery)
1054 * Let's just make sure it's a valid subselect ...
1056 if (!IsA(subquery, Query) ||
1057 subquery->commandType != CMD_SELECT ||
1058 subquery->utilityStmt != NULL ||
1059 subquery->intoClause != NULL)
1060 elog(ERROR, "subquery is bogus");
1063 * Can't currently pull up a query with setops (unless it's simple UNION
1064 * ALL, which is handled by a different code path). Maybe after querytree
1067 if (subquery->setOperations)
1071 * Can't pull up a subquery involving grouping, aggregation, sorting,
1072 * limiting, or WITH. (XXX WITH could possibly be allowed later)
1074 * We also don't pull up a subquery that has explicit FOR UPDATE/SHARE
1075 * clauses, because pullup would cause the locking to occur semantically
1076 * higher than it should. Implicit FOR UPDATE/SHARE is okay because in
1077 * that case the locking was originally declared in the upper query
1080 if (subquery->hasAggs ||
1081 subquery->hasWindowFuncs ||
1082 subquery->groupClause ||
1083 subquery->havingQual ||
1084 subquery->sortClause ||
1085 subquery->distinctClause ||
1086 subquery->limitOffset ||
1087 subquery->limitCount ||
1088 subquery->hasForUpdate ||
1093 * Don't pull up a subquery that has any set-returning functions in its
1094 * targetlist. Otherwise we might well wind up inserting set-returning
1095 * functions into places where they mustn't go, such as quals of higher
1098 if (expression_returns_set((Node *) subquery->targetList))
1102 * Don't pull up a subquery that has any volatile functions in its
1103 * targetlist. Otherwise we might introduce multiple evaluations of these
1104 * functions, if they get copied to multiple places in the upper query,
1105 * leading to surprising results. (Note: the PlaceHolderVar mechanism
1106 * doesn't quite guarantee single evaluation; else we could pull up anyway
1107 * and just wrap such items in PlaceHolderVars ...)
1109 if (contain_volatile_functions((Node *) subquery->targetList))
1113 * Hack: don't try to pull up a subquery with an empty jointree.
1114 * query_planner() will correctly generate a Result plan for a jointree
1115 * that's totally empty, but I don't think the right things happen if an
1116 * empty FromExpr appears lower down in a jointree. It would pose a
1117 * problem for the PlaceHolderVar mechanism too, since we'd have no way to
1118 * identify where to evaluate a PHV coming out of the subquery. Not worth
1119 * working hard on this, just to collapse SubqueryScan/Result into Result;
1120 * especially since the SubqueryScan can often be optimized away by
1123 if (subquery->jointree->fromlist == NIL)
1130 * is_simple_union_all
1131 * Check a subquery to see if it's a simple UNION ALL.
1133 * We require all the setops to be UNION ALL (no mixing) and there can't be
1134 * any datatype coercions involved, ie, all the leaf queries must emit the
1138 is_simple_union_all(Query *subquery)
1140 SetOperationStmt *topop;
1142 /* Let's just make sure it's a valid subselect ... */
1143 if (!IsA(subquery, Query) ||
1144 subquery->commandType != CMD_SELECT ||
1145 subquery->utilityStmt != NULL ||
1146 subquery->intoClause != NULL)
1147 elog(ERROR, "subquery is bogus");
1149 /* Is it a set-operation query at all? */
1150 topop = (SetOperationStmt *) subquery->setOperations;
1153 Assert(IsA(topop, SetOperationStmt));
1155 /* Can't handle ORDER BY, LIMIT/OFFSET, locking, or WITH */
1156 if (subquery->sortClause ||
1157 subquery->limitOffset ||
1158 subquery->limitCount ||
1159 subquery->rowMarks ||
1163 /* Recursively check the tree of set operations */
1164 return is_simple_union_all_recurse((Node *) topop, subquery,
1169 is_simple_union_all_recurse(Node *setOp, Query *setOpQuery, List *colTypes)
1171 if (IsA(setOp, RangeTblRef))
1173 RangeTblRef *rtr = (RangeTblRef *) setOp;
1174 RangeTblEntry *rte = rt_fetch(rtr->rtindex, setOpQuery->rtable);
1175 Query *subquery = rte->subquery;
1177 Assert(subquery != NULL);
1179 /* Leaf nodes are OK if they match the toplevel column types */
1180 /* We don't have to compare typmods or collations here */
1181 return tlist_same_datatypes(subquery->targetList, colTypes, true);
1183 else if (IsA(setOp, SetOperationStmt))
1185 SetOperationStmt *op = (SetOperationStmt *) setOp;
1187 /* Must be UNION ALL */
1188 if (op->op != SETOP_UNION || !op->all)
1191 /* Recurse to check inputs */
1192 return is_simple_union_all_recurse(op->larg, setOpQuery, colTypes) &&
1193 is_simple_union_all_recurse(op->rarg, setOpQuery, colTypes);
1197 elog(ERROR, "unrecognized node type: %d",
1198 (int) nodeTag(setOp));
1199 return false; /* keep compiler quiet */
1204 * is_safe_append_member
1205 * Check a subquery that is a leaf of a UNION ALL appendrel to see if it's
1209 is_safe_append_member(Query *subquery)
1214 * It's only safe to pull up the child if its jointree contains exactly
1215 * one RTE, else the AppendRelInfo data structure breaks. The one base RTE
1216 * could be buried in several levels of FromExpr, however.
1218 * Also, the child can't have any WHERE quals because there's no place to
1219 * put them in an appendrel. (This is a bit annoying...) If we didn't
1220 * need to check this, we'd just test whether get_relids_in_jointree()
1221 * yields a singleton set, to be more consistent with the coding of
1222 * fix_append_rel_relids().
1224 jtnode = subquery->jointree;
1225 while (IsA(jtnode, FromExpr))
1227 if (jtnode->quals != NULL)
1229 if (list_length(jtnode->fromlist) != 1)
1231 jtnode = linitial(jtnode->fromlist);
1233 if (!IsA(jtnode, RangeTblRef))
1240 * Helper routine for pull_up_subqueries: do pullup_replace_vars on every
1241 * expression in the jointree, without changing the jointree structure itself.
1242 * Ugly, but there's no other way...
1244 * If we are at or below lowest_outer_join, we can suppress use of
1245 * PlaceHolderVars wrapped around the replacement expressions.
1248 replace_vars_in_jointree(Node *jtnode,
1249 pullup_replace_vars_context *context,
1250 JoinExpr *lowest_outer_join)
1254 if (IsA(jtnode, RangeTblRef))
1256 /* nothing to do here */
1258 else if (IsA(jtnode, FromExpr))
1260 FromExpr *f = (FromExpr *) jtnode;
1263 foreach(l, f->fromlist)
1264 replace_vars_in_jointree(lfirst(l), context, lowest_outer_join);
1265 f->quals = pullup_replace_vars(f->quals, context);
1267 else if (IsA(jtnode, JoinExpr))
1269 JoinExpr *j = (JoinExpr *) jtnode;
1270 bool save_need_phvs = context->need_phvs;
1272 if (j == lowest_outer_join)
1274 /* no more PHVs in or below this join */
1275 context->need_phvs = false;
1276 lowest_outer_join = NULL;
1278 replace_vars_in_jointree(j->larg, context, lowest_outer_join);
1279 replace_vars_in_jointree(j->rarg, context, lowest_outer_join);
1280 j->quals = pullup_replace_vars(j->quals, context);
1283 * We don't bother to update the colvars list, since it won't be used
1286 context->need_phvs = save_need_phvs;
1289 elog(ERROR, "unrecognized node type: %d",
1290 (int) nodeTag(jtnode));
1294 * Apply pullup variable replacement throughout an expression tree
1296 * Returns a modified copy of the tree, so this can't be used where we
1297 * need to do in-place replacement.
1300 pullup_replace_vars(Node *expr, pullup_replace_vars_context *context)
1302 return replace_rte_variables(expr,
1304 pullup_replace_vars_callback,
1306 context->outer_hasSubLinks);
1310 pullup_replace_vars_callback(Var *var,
1311 replace_rte_variables_context *context)
1313 pullup_replace_vars_context *rcon = (pullup_replace_vars_context *) context->callback_arg;
1314 int varattno = var->varattno;
1318 * If PlaceHolderVars are needed, we cache the modified expressions in
1319 * rcon->rv_cache[]. This is not in hopes of any material speed gain
1320 * within this function, but to avoid generating identical PHVs with
1321 * different IDs. That would result in duplicate evaluations at runtime,
1322 * and possibly prevent optimizations that rely on recognizing different
1323 * references to the same subquery output as being equal(). So it's worth
1324 * a bit of extra effort to avoid it.
1326 if (rcon->need_phvs &&
1327 varattno >= InvalidAttrNumber &&
1328 varattno <= list_length(rcon->targetlist) &&
1329 rcon->rv_cache[varattno] != NULL)
1331 /* Just copy the entry and fall through to adjust its varlevelsup */
1332 newnode = copyObject(rcon->rv_cache[varattno]);
1334 else if (varattno == InvalidAttrNumber)
1336 /* Must expand whole-tuple reference into RowExpr */
1340 bool save_need_phvs = rcon->need_phvs;
1341 int save_sublevelsup = context->sublevels_up;
1344 * If generating an expansion for a var of a named rowtype (ie, this
1345 * is a plain relation RTE), then we must include dummy items for
1346 * dropped columns. If the var is RECORD (ie, this is a JOIN), then
1347 * omit dropped columns. Either way, attach column names to the
1348 * RowExpr for use of ruleutils.c.
1350 * In order to be able to cache the results, we always generate the
1351 * expansion with varlevelsup = 0, and then adjust if needed.
1353 expandRTE(rcon->target_rte,
1354 var->varno, 0 /* not varlevelsup */ , var->location,
1355 (var->vartype != RECORDOID),
1356 &colnames, &fields);
1357 /* Adjust the generated per-field Vars, but don't insert PHVs */
1358 rcon->need_phvs = false;
1359 context->sublevels_up = 0; /* to match the expandRTE output */
1360 fields = (List *) replace_rte_variables_mutator((Node *) fields,
1362 rcon->need_phvs = save_need_phvs;
1363 context->sublevels_up = save_sublevelsup;
1365 rowexpr = makeNode(RowExpr);
1366 rowexpr->args = fields;
1367 rowexpr->row_typeid = var->vartype;
1368 rowexpr->row_format = COERCE_IMPLICIT_CAST;
1369 rowexpr->colnames = colnames;
1370 rowexpr->location = var->location;
1371 newnode = (Node *) rowexpr;
1374 * Insert PlaceHolderVar if needed. Notice that we are wrapping one
1375 * PlaceHolderVar around the whole RowExpr, rather than putting one
1376 * around each element of the row. This is because we need the
1377 * expression to yield NULL, not ROW(NULL,NULL,...) when it is forced
1378 * to null by an outer join.
1380 if (rcon->need_phvs)
1382 /* RowExpr is certainly not strict, so always need PHV */
1384 make_placeholder_expr(rcon->root,
1386 bms_make_singleton(rcon->varno));
1387 /* cache it with the PHV, and with varlevelsup still zero */
1388 rcon->rv_cache[InvalidAttrNumber] = copyObject(newnode);
1393 /* Normal case referencing one targetlist element */
1394 TargetEntry *tle = get_tle_by_resno(rcon->targetlist, varattno);
1396 if (tle == NULL) /* shouldn't happen */
1397 elog(ERROR, "could not find attribute %d in subquery targetlist",
1400 /* Make a copy of the tlist item to return */
1401 newnode = copyObject(tle->expr);
1403 /* Insert PlaceHolderVar if needed */
1404 if (rcon->need_phvs)
1408 if (newnode && IsA(newnode, Var) &&
1409 ((Var *) newnode)->varlevelsup == 0)
1411 /* Simple Vars always escape being wrapped */
1414 else if (rcon->wrap_non_vars)
1416 /* Wrap all non-Vars in a PlaceHolderVar */
1422 * If it contains a Var of current level, and does not contain
1423 * any non-strict constructs, then it's certainly nullable and
1424 * we don't need to insert a PlaceHolderVar. (Note: in future
1425 * maybe we should insert PlaceHolderVars anyway, when a tlist
1426 * item is expensive to evaluate?
1428 if (contain_vars_of_level((Node *) newnode, 0) &&
1429 !contain_nonstrict_functions((Node *) newnode))
1431 /* No wrap needed */
1436 /* Else wrap it in a PlaceHolderVar */
1443 make_placeholder_expr(rcon->root,
1445 bms_make_singleton(rcon->varno));
1448 * Cache it if possible (ie, if the attno is in range, which it
1449 * probably always should be). We can cache the value even if we
1450 * decided we didn't need a PHV, since this result will be
1451 * suitable for any request that has need_phvs.
1453 if (varattno > InvalidAttrNumber &&
1454 varattno <= list_length(rcon->targetlist))
1455 rcon->rv_cache[varattno] = copyObject(newnode);
1459 /* Must adjust varlevelsup if tlist item is from higher query */
1460 if (var->varlevelsup > 0)
1461 IncrementVarSublevelsUp(newnode, var->varlevelsup, 0);
1468 * flatten_simple_union_all
1469 * Try to optimize top-level UNION ALL structure into an appendrel
1471 * If a query's setOperations tree consists entirely of simple UNION ALL
1472 * operations, flatten it into an append relation, which we can process more
1473 * intelligently than the general setops case. Otherwise, do nothing.
1475 * In most cases, this can succeed only for a top-level query, because for a
1476 * subquery in FROM, the parent query's invocation of pull_up_subqueries would
1477 * already have flattened the UNION via pull_up_simple_union_all. But there
1478 * are a few cases we can support here but not in that code path, for example
1479 * when the subquery also contains ORDER BY.
1482 flatten_simple_union_all(PlannerInfo *root)
1484 Query *parse = root->parse;
1485 SetOperationStmt *topop;
1486 Node *leftmostjtnode;
1488 RangeTblEntry *leftmostRTE;
1490 RangeTblEntry *childRTE;
1493 /* Shouldn't be called unless query has setops */
1494 topop = (SetOperationStmt *) parse->setOperations;
1495 Assert(topop && IsA(topop, SetOperationStmt));
1497 /* Can't optimize away a recursive UNION */
1498 if (root->hasRecursion)
1502 * Recursively check the tree of set operations. If not all UNION ALL
1503 * with identical column types, punt.
1505 if (!is_simple_union_all_recurse((Node *) topop, parse, topop->colTypes))
1509 * Locate the leftmost leaf query in the setops tree. The upper query's
1510 * Vars all refer to this RTE (see transformSetOperationStmt).
1512 leftmostjtnode = topop->larg;
1513 while (leftmostjtnode && IsA(leftmostjtnode, SetOperationStmt))
1514 leftmostjtnode = ((SetOperationStmt *) leftmostjtnode)->larg;
1515 Assert(leftmostjtnode && IsA(leftmostjtnode, RangeTblRef));
1516 leftmostRTI = ((RangeTblRef *) leftmostjtnode)->rtindex;
1517 leftmostRTE = rt_fetch(leftmostRTI, parse->rtable);
1518 Assert(leftmostRTE->rtekind == RTE_SUBQUERY);
1521 * Make a copy of the leftmost RTE and add it to the rtable. This copy
1522 * will represent the leftmost leaf query in its capacity as a member of
1523 * the appendrel. The original will represent the appendrel as a whole.
1524 * (We must do things this way because the upper query's Vars have to be
1525 * seen as referring to the whole appendrel.)
1527 childRTE = copyObject(leftmostRTE);
1528 parse->rtable = lappend(parse->rtable, childRTE);
1529 childRTI = list_length(parse->rtable);
1531 /* Modify the setops tree to reference the child copy */
1532 ((RangeTblRef *) leftmostjtnode)->rtindex = childRTI;
1534 /* Modify the formerly-leftmost RTE to mark it as an appendrel parent */
1535 leftmostRTE->inh = true;
1538 * Form a RangeTblRef for the appendrel, and insert it into FROM. The top
1539 * Query of a setops tree should have had an empty FromClause initially.
1541 rtr = makeNode(RangeTblRef);
1542 rtr->rtindex = leftmostRTI;
1543 Assert(parse->jointree->fromlist == NIL);
1544 parse->jointree->fromlist = list_make1(rtr);
1547 * Now pretend the query has no setops. We must do this before trying to
1548 * do subquery pullup, because of Assert in pull_up_simple_subquery.
1550 parse->setOperations = NULL;
1553 * Build AppendRelInfo information, and apply pull_up_subqueries to the
1554 * leaf queries of the UNION ALL. (We must do that now because they
1555 * weren't previously referenced by the jointree, and so were missed by
1556 * the main invocation of pull_up_subqueries.)
1558 pull_up_union_leaf_queries((Node *) topop, root, leftmostRTI, parse, 0);
1563 * reduce_outer_joins
1564 * Attempt to reduce outer joins to plain inner joins.
1566 * The idea here is that given a query like
1567 * SELECT ... FROM a LEFT JOIN b ON (...) WHERE b.y = 42;
1568 * we can reduce the LEFT JOIN to a plain JOIN if the "=" operator in WHERE
1569 * is strict. The strict operator will always return NULL, causing the outer
1570 * WHERE to fail, on any row where the LEFT JOIN filled in NULLs for b's
1571 * columns. Therefore, there's no need for the join to produce null-extended
1572 * rows in the first place --- which makes it a plain join not an outer join.
1573 * (This scenario may not be very likely in a query written out by hand, but
1574 * it's reasonably likely when pushing quals down into complex views.)
1576 * More generally, an outer join can be reduced in strength if there is a
1577 * strict qual above it in the qual tree that constrains a Var from the
1578 * nullable side of the join to be non-null. (For FULL joins this applies
1579 * to each side separately.)
1581 * Another transformation we apply here is to recognize cases like
1582 * SELECT ... FROM a LEFT JOIN b ON (a.x = b.y) WHERE b.y IS NULL;
1583 * If the join clause is strict for b.y, then only null-extended rows could
1584 * pass the upper WHERE, and we can conclude that what the query is really
1585 * specifying is an anti-semijoin. We change the join type from JOIN_LEFT
1586 * to JOIN_ANTI. The IS NULL clause then becomes redundant, and must be
1587 * removed to prevent bogus selectivity calculations, but we leave it to
1588 * distribute_qual_to_rels to get rid of such clauses.
1590 * Also, we get rid of JOIN_RIGHT cases by flipping them around to become
1591 * JOIN_LEFT. This saves some code here and in some later planner routines,
1592 * but the main reason to do it is to not need to invent a JOIN_REVERSE_ANTI
1595 * To ease recognition of strict qual clauses, we require this routine to be
1596 * run after expression preprocessing (i.e., qual canonicalization and JOIN
1597 * alias-var expansion).
1600 reduce_outer_joins(PlannerInfo *root)
1602 reduce_outer_joins_state *state;
1605 * To avoid doing strictness checks on more quals than necessary, we want
1606 * to stop descending the jointree as soon as there are no outer joins
1607 * below our current point. This consideration forces a two-pass process.
1608 * The first pass gathers information about which base rels appear below
1609 * each side of each join clause, and about whether there are outer
1610 * join(s) below each side of each join clause. The second pass examines
1611 * qual clauses and changes join types as it descends the tree.
1613 state = reduce_outer_joins_pass1((Node *) root->parse->jointree);
1615 /* planner.c shouldn't have called me if no outer joins */
1616 if (state == NULL || !state->contains_outer)
1617 elog(ERROR, "so where are the outer joins?");
1619 reduce_outer_joins_pass2((Node *) root->parse->jointree,
1620 state, root, NULL, NIL, NIL);
1624 * reduce_outer_joins_pass1 - phase 1 data collection
1626 * Returns a state node describing the given jointree node.
1628 static reduce_outer_joins_state *
1629 reduce_outer_joins_pass1(Node *jtnode)
1631 reduce_outer_joins_state *result;
1633 result = (reduce_outer_joins_state *)
1634 palloc(sizeof(reduce_outer_joins_state));
1635 result->relids = NULL;
1636 result->contains_outer = false;
1637 result->sub_states = NIL;
1641 if (IsA(jtnode, RangeTblRef))
1643 int varno = ((RangeTblRef *) jtnode)->rtindex;
1645 result->relids = bms_make_singleton(varno);
1647 else if (IsA(jtnode, FromExpr))
1649 FromExpr *f = (FromExpr *) jtnode;
1652 foreach(l, f->fromlist)
1654 reduce_outer_joins_state *sub_state;
1656 sub_state = reduce_outer_joins_pass1(lfirst(l));
1657 result->relids = bms_add_members(result->relids,
1659 result->contains_outer |= sub_state->contains_outer;
1660 result->sub_states = lappend(result->sub_states, sub_state);
1663 else if (IsA(jtnode, JoinExpr))
1665 JoinExpr *j = (JoinExpr *) jtnode;
1666 reduce_outer_joins_state *sub_state;
1668 /* join's own RT index is not wanted in result->relids */
1669 if (IS_OUTER_JOIN(j->jointype))
1670 result->contains_outer = true;
1672 sub_state = reduce_outer_joins_pass1(j->larg);
1673 result->relids = bms_add_members(result->relids,
1675 result->contains_outer |= sub_state->contains_outer;
1676 result->sub_states = lappend(result->sub_states, sub_state);
1678 sub_state = reduce_outer_joins_pass1(j->rarg);
1679 result->relids = bms_add_members(result->relids,
1681 result->contains_outer |= sub_state->contains_outer;
1682 result->sub_states = lappend(result->sub_states, sub_state);
1685 elog(ERROR, "unrecognized node type: %d",
1686 (int) nodeTag(jtnode));
1691 * reduce_outer_joins_pass2 - phase 2 processing
1693 * jtnode: current jointree node
1694 * state: state data collected by phase 1 for this node
1695 * root: toplevel planner state
1696 * nonnullable_rels: set of base relids forced non-null by upper quals
1697 * nonnullable_vars: list of Vars forced non-null by upper quals
1698 * forced_null_vars: list of Vars forced null by upper quals
1701 reduce_outer_joins_pass2(Node *jtnode,
1702 reduce_outer_joins_state *state,
1704 Relids nonnullable_rels,
1705 List *nonnullable_vars,
1706 List *forced_null_vars)
1709 * pass 2 should never descend as far as an empty subnode or base rel,
1710 * because it's only called on subtrees marked as contains_outer.
1713 elog(ERROR, "reached empty jointree");
1714 if (IsA(jtnode, RangeTblRef))
1715 elog(ERROR, "reached base rel");
1716 else if (IsA(jtnode, FromExpr))
1718 FromExpr *f = (FromExpr *) jtnode;
1721 Relids pass_nonnullable_rels;
1722 List *pass_nonnullable_vars;
1723 List *pass_forced_null_vars;
1725 /* Scan quals to see if we can add any constraints */
1726 pass_nonnullable_rels = find_nonnullable_rels(f->quals);
1727 pass_nonnullable_rels = bms_add_members(pass_nonnullable_rels,
1729 /* NB: we rely on list_concat to not damage its second argument */
1730 pass_nonnullable_vars = find_nonnullable_vars(f->quals);
1731 pass_nonnullable_vars = list_concat(pass_nonnullable_vars,
1733 pass_forced_null_vars = find_forced_null_vars(f->quals);
1734 pass_forced_null_vars = list_concat(pass_forced_null_vars,
1736 /* And recurse --- but only into interesting subtrees */
1737 Assert(list_length(f->fromlist) == list_length(state->sub_states));
1738 forboth(l, f->fromlist, s, state->sub_states)
1740 reduce_outer_joins_state *sub_state = lfirst(s);
1742 if (sub_state->contains_outer)
1743 reduce_outer_joins_pass2(lfirst(l), sub_state, root,
1744 pass_nonnullable_rels,
1745 pass_nonnullable_vars,
1746 pass_forced_null_vars);
1748 bms_free(pass_nonnullable_rels);
1749 /* can't so easily clean up var lists, unfortunately */
1751 else if (IsA(jtnode, JoinExpr))
1753 JoinExpr *j = (JoinExpr *) jtnode;
1754 int rtindex = j->rtindex;
1755 JoinType jointype = j->jointype;
1756 reduce_outer_joins_state *left_state = linitial(state->sub_states);
1757 reduce_outer_joins_state *right_state = lsecond(state->sub_states);
1758 List *local_nonnullable_vars = NIL;
1759 bool computed_local_nonnullable_vars = false;
1761 /* Can we simplify this join? */
1767 if (bms_overlap(nonnullable_rels, right_state->relids))
1768 jointype = JOIN_INNER;
1771 if (bms_overlap(nonnullable_rels, left_state->relids))
1772 jointype = JOIN_INNER;
1775 if (bms_overlap(nonnullable_rels, left_state->relids))
1777 if (bms_overlap(nonnullable_rels, right_state->relids))
1778 jointype = JOIN_INNER;
1780 jointype = JOIN_LEFT;
1784 if (bms_overlap(nonnullable_rels, right_state->relids))
1785 jointype = JOIN_RIGHT;
1792 * These could only have been introduced by pull_up_sublinks,
1793 * so there's no way that upper quals could refer to their
1794 * righthand sides, and no point in checking.
1798 elog(ERROR, "unrecognized join type: %d",
1804 * Convert JOIN_RIGHT to JOIN_LEFT. Note that in the case where we
1805 * reduced JOIN_FULL to JOIN_RIGHT, this will mean the JoinExpr no
1806 * longer matches the internal ordering of any CoalesceExpr's built to
1807 * represent merged join variables. We don't care about that at
1808 * present, but be wary of it ...
1810 if (jointype == JOIN_RIGHT)
1817 jointype = JOIN_LEFT;
1818 right_state = linitial(state->sub_states);
1819 left_state = lsecond(state->sub_states);
1823 * See if we can reduce JOIN_LEFT to JOIN_ANTI. This is the case if
1824 * the join's own quals are strict for any var that was forced null by
1825 * higher qual levels. NOTE: there are other ways that we could
1826 * detect an anti-join, in particular if we were to check whether Vars
1827 * coming from the RHS must be non-null because of table constraints.
1828 * That seems complicated and expensive though (in particular, one
1829 * would have to be wary of lower outer joins). For the moment this
1832 if (jointype == JOIN_LEFT)
1836 local_nonnullable_vars = find_nonnullable_vars(j->quals);
1837 computed_local_nonnullable_vars = true;
1840 * It's not sufficient to check whether local_nonnullable_vars and
1841 * forced_null_vars overlap: we need to know if the overlap
1842 * includes any RHS variables.
1844 overlap = list_intersection(local_nonnullable_vars,
1846 if (overlap != NIL &&
1847 bms_overlap(pull_varnos((Node *) overlap),
1848 right_state->relids))
1849 jointype = JOIN_ANTI;
1852 /* Apply the jointype change, if any, to both jointree node and RTE */
1853 if (rtindex && jointype != j->jointype)
1855 RangeTblEntry *rte = rt_fetch(rtindex, root->parse->rtable);
1857 Assert(rte->rtekind == RTE_JOIN);
1858 Assert(rte->jointype == j->jointype);
1859 rte->jointype = jointype;
1861 j->jointype = jointype;
1863 /* Only recurse if there's more to do below here */
1864 if (left_state->contains_outer || right_state->contains_outer)
1866 Relids local_nonnullable_rels;
1867 List *local_forced_null_vars;
1868 Relids pass_nonnullable_rels;
1869 List *pass_nonnullable_vars;
1870 List *pass_forced_null_vars;
1873 * If this join is (now) inner, we can add any constraints its
1874 * quals provide to those we got from above. But if it is outer,
1875 * we can pass down the local constraints only into the nullable
1876 * side, because an outer join never eliminates any rows from its
1877 * non-nullable side. Also, there is no point in passing upper
1878 * constraints into the nullable side, since if there were any
1879 * we'd have been able to reduce the join. (In the case of upper
1880 * forced-null constraints, we *must not* pass them into the
1881 * nullable side --- they either applied here, or not.) The upshot
1882 * is that we pass either the local or the upper constraints,
1883 * never both, to the children of an outer join.
1885 * Note that a SEMI join works like an inner join here: it's okay
1886 * to pass down both local and upper constraints. (There can't be
1887 * any upper constraints affecting its inner side, but it's not
1888 * worth having a separate code path to avoid passing them.)
1890 * At a FULL join we just punt and pass nothing down --- is it
1891 * possible to be smarter?
1893 if (jointype != JOIN_FULL)
1895 local_nonnullable_rels = find_nonnullable_rels(j->quals);
1896 if (!computed_local_nonnullable_vars)
1897 local_nonnullable_vars = find_nonnullable_vars(j->quals);
1898 local_forced_null_vars = find_forced_null_vars(j->quals);
1899 if (jointype == JOIN_INNER || jointype == JOIN_SEMI)
1901 /* OK to merge upper and local constraints */
1902 local_nonnullable_rels = bms_add_members(local_nonnullable_rels,
1904 local_nonnullable_vars = list_concat(local_nonnullable_vars,
1906 local_forced_null_vars = list_concat(local_forced_null_vars,
1912 /* no use in calculating these */
1913 local_nonnullable_rels = NULL;
1914 local_forced_null_vars = NIL;
1917 if (left_state->contains_outer)
1919 if (jointype == JOIN_INNER || jointype == JOIN_SEMI)
1921 /* pass union of local and upper constraints */
1922 pass_nonnullable_rels = local_nonnullable_rels;
1923 pass_nonnullable_vars = local_nonnullable_vars;
1924 pass_forced_null_vars = local_forced_null_vars;
1926 else if (jointype != JOIN_FULL) /* ie, LEFT or ANTI */
1928 /* can't pass local constraints to non-nullable side */
1929 pass_nonnullable_rels = nonnullable_rels;
1930 pass_nonnullable_vars = nonnullable_vars;
1931 pass_forced_null_vars = forced_null_vars;
1935 /* no constraints pass through JOIN_FULL */
1936 pass_nonnullable_rels = NULL;
1937 pass_nonnullable_vars = NIL;
1938 pass_forced_null_vars = NIL;
1940 reduce_outer_joins_pass2(j->larg, left_state, root,
1941 pass_nonnullable_rels,
1942 pass_nonnullable_vars,
1943 pass_forced_null_vars);
1946 if (right_state->contains_outer)
1948 if (jointype != JOIN_FULL) /* ie, INNER/LEFT/SEMI/ANTI */
1950 /* pass appropriate constraints, per comment above */
1951 pass_nonnullable_rels = local_nonnullable_rels;
1952 pass_nonnullable_vars = local_nonnullable_vars;
1953 pass_forced_null_vars = local_forced_null_vars;
1957 /* no constraints pass through JOIN_FULL */
1958 pass_nonnullable_rels = NULL;
1959 pass_nonnullable_vars = NIL;
1960 pass_forced_null_vars = NIL;
1962 reduce_outer_joins_pass2(j->rarg, right_state, root,
1963 pass_nonnullable_rels,
1964 pass_nonnullable_vars,
1965 pass_forced_null_vars);
1967 bms_free(local_nonnullable_rels);
1971 elog(ERROR, "unrecognized node type: %d",
1972 (int) nodeTag(jtnode));
1976 * substitute_multiple_relids - adjust node relid sets after pulling up
1979 * Find any PlaceHolderVar nodes in the given tree that reference the
1980 * pulled-up relid, and change them to reference the replacement relid(s).
1981 * We do not need to recurse into subqueries, since no subquery of the current
1982 * top query could (yet) contain such a reference.
1984 * NOTE: although this has the form of a walker, we cheat and modify the
1985 * nodes in-place. This should be OK since the tree was copied by
1986 * pullup_replace_vars earlier. Avoid scribbling on the original values of
1987 * the bitmapsets, though, because expression_tree_mutator doesn't copy those.
1994 } substitute_multiple_relids_context;
1997 substitute_multiple_relids_walker(Node *node,
1998 substitute_multiple_relids_context *context)
2002 if (IsA(node, PlaceHolderVar))
2004 PlaceHolderVar *phv = (PlaceHolderVar *) node;
2006 if (bms_is_member(context->varno, phv->phrels))
2008 phv->phrels = bms_union(phv->phrels,
2009 context->subrelids);
2010 phv->phrels = bms_del_member(phv->phrels,
2013 /* fall through to examine children */
2015 /* Shouldn't need to handle planner auxiliary nodes here */
2016 Assert(!IsA(node, SpecialJoinInfo));
2017 Assert(!IsA(node, AppendRelInfo));
2018 Assert(!IsA(node, PlaceHolderInfo));
2019 Assert(!IsA(node, MinMaxAggInfo));
2021 return expression_tree_walker(node, substitute_multiple_relids_walker,
2026 substitute_multiple_relids(Node *node, int varno, Relids subrelids)
2028 substitute_multiple_relids_context context;
2030 context.varno = varno;
2031 context.subrelids = subrelids;
2034 * Must be prepared to start with a Query or a bare expression tree.
2036 query_or_expression_tree_walker(node,
2037 substitute_multiple_relids_walker,
2043 * fix_append_rel_relids: update RT-index fields of AppendRelInfo nodes
2045 * When we pull up a subquery, any AppendRelInfo references to the subquery's
2046 * RT index have to be replaced by the substituted relid (and there had better
2047 * be only one). We also need to apply substitute_multiple_relids to their
2048 * translated_vars lists, since those might contain PlaceHolderVars.
2050 * We assume we may modify the AppendRelInfo nodes in-place.
2053 fix_append_rel_relids(List *append_rel_list, int varno, Relids subrelids)
2059 * We only want to extract the member relid once, but we mustn't fail
2060 * immediately if there are multiple members; it could be that none of the
2061 * AppendRelInfo nodes refer to it. So compute it on first use. Note that
2062 * bms_singleton_member will complain if set is not singleton.
2064 foreach(l, append_rel_list)
2066 AppendRelInfo *appinfo = (AppendRelInfo *) lfirst(l);
2068 /* The parent_relid shouldn't ever be a pullup target */
2069 Assert(appinfo->parent_relid != varno);
2071 if (appinfo->child_relid == varno)
2074 subvarno = bms_singleton_member(subrelids);
2075 appinfo->child_relid = subvarno;
2078 /* Also finish fixups for its translated vars */
2079 substitute_multiple_relids((Node *) appinfo->translated_vars,
2085 * get_relids_in_jointree: get set of RT indexes present in a jointree
2087 * If include_joins is true, join RT indexes are included; if false,
2088 * only base rels are included.
2091 get_relids_in_jointree(Node *jtnode, bool include_joins)
2093 Relids result = NULL;
2097 if (IsA(jtnode, RangeTblRef))
2099 int varno = ((RangeTblRef *) jtnode)->rtindex;
2101 result = bms_make_singleton(varno);
2103 else if (IsA(jtnode, FromExpr))
2105 FromExpr *f = (FromExpr *) jtnode;
2108 foreach(l, f->fromlist)
2110 result = bms_join(result,
2111 get_relids_in_jointree(lfirst(l),
2115 else if (IsA(jtnode, JoinExpr))
2117 JoinExpr *j = (JoinExpr *) jtnode;
2119 result = get_relids_in_jointree(j->larg, include_joins);
2120 result = bms_join(result,
2121 get_relids_in_jointree(j->rarg, include_joins));
2122 if (include_joins && j->rtindex)
2123 result = bms_add_member(result, j->rtindex);
2126 elog(ERROR, "unrecognized node type: %d",
2127 (int) nodeTag(jtnode));
2132 * get_relids_for_join: get set of base RT indexes making up a join
2135 get_relids_for_join(PlannerInfo *root, int joinrelid)
2139 jtnode = find_jointree_node_for_rel((Node *) root->parse->jointree,
2142 elog(ERROR, "could not find join node %d", joinrelid);
2143 return get_relids_in_jointree(jtnode, false);
2147 * find_jointree_node_for_rel: locate jointree node for a base or join RT index
2149 * Returns NULL if not found
2152 find_jointree_node_for_rel(Node *jtnode, int relid)
2156 if (IsA(jtnode, RangeTblRef))
2158 int varno = ((RangeTblRef *) jtnode)->rtindex;
2163 else if (IsA(jtnode, FromExpr))
2165 FromExpr *f = (FromExpr *) jtnode;
2168 foreach(l, f->fromlist)
2170 jtnode = find_jointree_node_for_rel(lfirst(l), relid);
2175 else if (IsA(jtnode, JoinExpr))
2177 JoinExpr *j = (JoinExpr *) jtnode;
2179 if (relid == j->rtindex)
2181 jtnode = find_jointree_node_for_rel(j->larg, relid);
2184 jtnode = find_jointree_node_for_rel(j->rarg, relid);
2189 elog(ERROR, "unrecognized node type: %d",
2190 (int) nodeTag(jtnode));