1 /*-------------------------------------------------------------------------
4 * Planning routines for subselects and parameters.
6 * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
10 * $PostgreSQL: pgsql/src/backend/optimizer/plan/subselect.c,v 1.124 2007/08/26 21:44:25 tgl Exp $
12 *-------------------------------------------------------------------------
16 #include "catalog/pg_operator.h"
17 #include "catalog/pg_type.h"
18 #include "miscadmin.h"
19 #include "nodes/makefuncs.h"
20 #include "optimizer/clauses.h"
21 #include "optimizer/planmain.h"
22 #include "optimizer/planner.h"
23 #include "optimizer/subselect.h"
24 #include "optimizer/var.h"
25 #include "parser/parse_expr.h"
26 #include "parser/parse_relation.h"
27 #include "parser/parsetree.h"
28 #include "rewrite/rewriteManip.h"
29 #include "utils/builtins.h"
30 #include "utils/lsyscache.h"
31 #include "utils/syscache.h"
34 typedef struct convert_testexpr_context
37 int rtindex; /* RT index for Vars, or 0 for Params */
38 List *righthandIds; /* accumulated list of Vars or Param IDs */
39 } convert_testexpr_context;
41 typedef struct process_sublinks_context
45 } process_sublinks_context;
47 typedef struct finalize_primnode_context
50 Bitmapset *paramids; /* Set of PARAM_EXEC paramids found */
51 Bitmapset *outer_params; /* Set of accessible outer paramids */
52 } finalize_primnode_context;
55 static Node *convert_testexpr(PlannerInfo *root,
59 static Node *convert_testexpr_mutator(Node *node,
60 convert_testexpr_context *context);
61 static bool subplan_is_hashable(SubLink *slink, SubPlan *node, Plan *plan);
62 static bool hash_ok_operator(OpExpr *expr);
63 static Node *replace_correlation_vars_mutator(Node *node, PlannerInfo *root);
64 static Node *process_sublinks_mutator(Node *node,
65 process_sublinks_context *context);
66 static Bitmapset *finalize_plan(PlannerInfo *root,
68 Bitmapset *outer_params,
69 Bitmapset *valid_params);
70 static bool finalize_primnode(Node *node, finalize_primnode_context *context);
74 * Generate a Param node to replace the given Var,
75 * which is expected to have varlevelsup > 0 (ie, it is not local).
78 replace_outer_var(PlannerInfo *root, Var *var)
82 PlannerParamItem *pitem;
86 Assert(var->varlevelsup > 0 && var->varlevelsup < root->query_level);
87 abslevel = root->query_level - var->varlevelsup;
90 * If there's already a paramlist entry for this same Var, just use
91 * it. NOTE: in sufficiently complex querytrees, it is possible for the
92 * same varno/abslevel to refer to different RTEs in different parts of
93 * the parsetree, so that different fields might end up sharing the same
94 * Param number. As long as we check the vartype as well, I believe that
95 * this sort of aliasing will cause no trouble. The correct field should
96 * get stored into the Param slot at execution in each part of the tree.
98 * We also need to demand a match on vartypmod. This does not matter for
99 * the Param itself, since those are not typmod-dependent, but it does
100 * matter when make_subplan() instantiates a modified copy of the Var for
101 * a subplan's args list.
104 foreach(ppl, root->glob->paramlist)
106 pitem = (PlannerParamItem *) lfirst(ppl);
107 if (pitem->abslevel == abslevel && IsA(pitem->item, Var))
109 Var *pvar = (Var *) pitem->item;
111 if (pvar->varno == var->varno &&
112 pvar->varattno == var->varattno &&
113 pvar->vartype == var->vartype &&
114 pvar->vartypmod == var->vartypmod)
122 /* Nope, so make a new one */
123 var = (Var *) copyObject(var);
124 var->varlevelsup = 0;
126 pitem = makeNode(PlannerParamItem);
127 pitem->item = (Node *) var;
128 pitem->abslevel = abslevel;
130 root->glob->paramlist = lappend(root->glob->paramlist, pitem);
131 /* i is already the correct index for the new item */
134 retval = makeNode(Param);
135 retval->paramkind = PARAM_EXEC;
137 retval->paramtype = var->vartype;
138 retval->paramtypmod = var->vartypmod;
144 * Generate a Param node to replace the given Aggref
145 * which is expected to have agglevelsup > 0 (ie, it is not local).
148 replace_outer_agg(PlannerInfo *root, Aggref *agg)
151 PlannerParamItem *pitem;
155 Assert(agg->agglevelsup > 0 && agg->agglevelsup < root->query_level);
156 abslevel = root->query_level - agg->agglevelsup;
159 * It does not seem worthwhile to try to match duplicate outer aggs. Just
160 * make a new slot every time.
162 agg = (Aggref *) copyObject(agg);
163 IncrementVarSublevelsUp((Node *) agg, -((int) agg->agglevelsup), 0);
164 Assert(agg->agglevelsup == 0);
166 pitem = makeNode(PlannerParamItem);
167 pitem->item = (Node *) agg;
168 pitem->abslevel = abslevel;
170 root->glob->paramlist = lappend(root->glob->paramlist, pitem);
171 i = list_length(root->glob->paramlist) - 1;
173 retval = makeNode(Param);
174 retval->paramkind = PARAM_EXEC;
176 retval->paramtype = agg->aggtype;
177 retval->paramtypmod = -1;
183 * Generate a new Param node that will not conflict with any other.
185 * This is used to allocate PARAM_EXEC slots for subplan outputs.
188 generate_new_param(PlannerInfo *root, Oid paramtype, int32 paramtypmod)
191 PlannerParamItem *pitem;
193 retval = makeNode(Param);
194 retval->paramkind = PARAM_EXEC;
195 retval->paramid = list_length(root->glob->paramlist);
196 retval->paramtype = paramtype;
197 retval->paramtypmod = paramtypmod;
199 pitem = makeNode(PlannerParamItem);
200 pitem->item = (Node *) retval;
201 pitem->abslevel = root->query_level;
203 root->glob->paramlist = lappend(root->glob->paramlist, pitem);
209 * Get the datatype of the first column of the plan's output.
211 * This is stored for ARRAY_SUBLINK and for exprType(), which doesn't have any
212 * way to get at the plan associated with a SubPlan node. We really only need
213 * the value for EXPR_SUBLINK and ARRAY_SUBLINK subplans, but for consistency
217 get_first_col_type(Plan *plan)
219 TargetEntry *tent = (TargetEntry *) linitial(plan->targetlist);
221 Assert(IsA(tent, TargetEntry));
222 Assert(!tent->resjunk);
223 return exprType((Node *) tent->expr);
227 * Convert a SubLink (as created by the parser) into a SubPlan.
229 * We are given the original SubLink and the already-processed testexpr
230 * (use this instead of the SubLink's own field). We are also told if
231 * this expression appears at top level of a WHERE/HAVING qual.
233 * The result is whatever we need to substitute in place of the SubLink
234 * node in the executable expression. This will be either the SubPlan
235 * node (if we have to do the subplan as a subplan), or a Param node
236 * representing the result of an InitPlan, or a row comparison expression
237 * tree containing InitPlan Param nodes.
240 make_subplan(PlannerInfo *root, SubLink *slink, Node *testexpr, bool isTopQual)
242 Query *subquery = (Query *) (slink->subselect);
243 double tuple_fraction;
246 PlannerInfo *subroot;
253 * Copy the source Query node. This is a quick and dirty kluge to resolve
254 * the fact that the parser can generate trees with multiple links to the
255 * same sub-Query node, but the planner wants to scribble on the Query.
256 * Try to clean this up when we do querytree redesign...
258 subquery = (Query *) copyObject(subquery);
261 * For an EXISTS subplan, tell lower-level planner to expect that only the
262 * first tuple will be retrieved. For ALL and ANY subplans, we will be
263 * able to stop evaluating if the test condition fails, so very often not
264 * all the tuples will be retrieved; for lack of a better idea, specify
265 * 50% retrieval. For EXPR and ROWCOMPARE subplans, use default behavior
266 * (we're only expecting one row out, anyway).
268 * NOTE: if you change these numbers, also change cost_qual_eval_walker()
269 * in path/costsize.c.
271 * XXX If an ALL/ANY subplan is uncorrelated, we may decide to hash or
272 * materialize its result below. In that case it would've been better to
273 * specify full retrieval. At present, however, we can only detect
274 * correlation or lack of it after we've made the subplan :-(. Perhaps
275 * detection of correlation should be done as a separate step. Meanwhile,
276 * we don't want to be too optimistic about the percentage of tuples
277 * retrieved, for fear of selecting a plan that's bad for the
278 * materialization case.
280 if (slink->subLinkType == EXISTS_SUBLINK)
281 tuple_fraction = 1.0; /* just like a LIMIT 1 */
282 else if (slink->subLinkType == ALL_SUBLINK ||
283 slink->subLinkType == ANY_SUBLINK)
284 tuple_fraction = 0.5; /* 50% */
286 tuple_fraction = 0.0; /* default behavior */
289 * Generate the plan for the subquery.
291 plan = subquery_planner(root->glob, subquery,
292 root->query_level + 1,
297 * Initialize the SubPlan node. Note plan_id isn't set yet.
299 splan = makeNode(SubPlan);
300 splan->subLinkType = slink->subLinkType;
301 splan->testexpr = NULL;
302 splan->paramIds = NIL;
303 splan->firstColType = get_first_col_type(plan);
304 splan->useHashTable = false;
305 /* At top level of a qual, can treat UNKNOWN the same as FALSE */
306 splan->unknownEqFalse = isTopQual;
307 splan->setParam = NIL;
308 splan->parParam = NIL;
312 * Make parParam list of params that current query level will pass to this
315 tmpset = bms_copy(plan->extParam);
316 while ((paramid = bms_first_member(tmpset)) >= 0)
318 PlannerParamItem *pitem = list_nth(root->glob->paramlist, paramid);
320 if (pitem->abslevel == root->query_level)
321 splan->parParam = lappend_int(splan->parParam, paramid);
326 * Un-correlated or undirect correlated plans of EXISTS, EXPR, ARRAY, or
327 * ROWCOMPARE types can be used as initPlans. For EXISTS, EXPR, or ARRAY,
328 * we just produce a Param referring to the result of evaluating the
329 * initPlan. For ROWCOMPARE, we must modify the testexpr tree to contain
330 * PARAM_EXEC Params instead of the PARAM_SUBLINK Params emitted by the
333 if (splan->parParam == NIL && slink->subLinkType == EXISTS_SUBLINK)
337 prm = generate_new_param(root, BOOLOID, -1);
338 splan->setParam = list_make1_int(prm->paramid);
340 result = (Node *) prm;
342 else if (splan->parParam == NIL && slink->subLinkType == EXPR_SUBLINK)
344 TargetEntry *te = linitial(plan->targetlist);
347 Assert(!te->resjunk);
348 prm = generate_new_param(root,
349 exprType((Node *) te->expr),
350 exprTypmod((Node *) te->expr));
351 splan->setParam = list_make1_int(prm->paramid);
353 result = (Node *) prm;
355 else if (splan->parParam == NIL && slink->subLinkType == ARRAY_SUBLINK)
357 TargetEntry *te = linitial(plan->targetlist);
361 Assert(!te->resjunk);
362 arraytype = get_array_type(exprType((Node *) te->expr));
363 if (!OidIsValid(arraytype))
364 elog(ERROR, "could not find array type for datatype %s",
365 format_type_be(exprType((Node *) te->expr)));
366 prm = generate_new_param(root,
368 exprTypmod((Node *) te->expr));
369 splan->setParam = list_make1_int(prm->paramid);
371 result = (Node *) prm;
373 else if (splan->parParam == NIL && slink->subLinkType == ROWCOMPARE_SUBLINK)
375 /* Adjust the Params */
376 result = convert_testexpr(root,
380 splan->setParam = list_copy(splan->paramIds);
384 * The executable expression is returned to become part of the outer
385 * plan's expression tree; it is not kept in the initplan node.
393 /* Adjust the Params */
394 splan->testexpr = convert_testexpr(root,
400 * We can't convert subplans of ALL_SUBLINK or ANY_SUBLINK types to
401 * initPlans, even when they are uncorrelated or undirect correlated,
402 * because we need to scan the output of the subplan for each outer
403 * tuple. But if it's an IN (= ANY) test, we might be able to use a
404 * hashtable to avoid comparing all the tuples.
406 if (subplan_is_hashable(slink, splan, plan))
407 splan->useHashTable = true;
410 * Otherwise, we have the option to tack a MATERIAL node onto the top
411 * of the subplan, to reduce the cost of reading it repeatedly. This
412 * is pointless for a direct-correlated subplan, since we'd have to
413 * recompute its results each time anyway. For uncorrelated/undirect
414 * correlated subplans, we add MATERIAL unless the subplan's top plan
415 * node would materialize its output anyway.
417 else if (splan->parParam == NIL)
421 switch (nodeTag(plan))
426 use_material = false;
433 plan = materialize_finished_plan(plan);
437 * Make splan->args from parParam.
440 foreach(l, splan->parParam)
442 PlannerParamItem *pitem = list_nth(root->glob->paramlist,
446 * The Var or Aggref has already been adjusted to have the correct
447 * varlevelsup or agglevelsup. We probably don't even need to
448 * copy it again, but be safe.
450 args = lappend(args, copyObject(pitem->item));
454 result = (Node *) splan;
459 * Add the subplan and its rtable to the global lists.
461 root->glob->subplans = lappend(root->glob->subplans,
463 root->glob->subrtables = lappend(root->glob->subrtables,
464 subroot->parse->rtable);
465 splan->plan_id = list_length(root->glob->subplans);
468 root->init_plans = lappend(root->init_plans, splan);
471 * A parameterless subplan (not initplan) should be prepared to handle
472 * REWIND efficiently. If it has direct parameters then there's no point
473 * since it'll be reset on each scan anyway; and if it's an initplan
474 * then there's no point since it won't get re-run without parameter
475 * changes anyway. The input of a hashed subplan doesn't need REWIND
478 if (splan->parParam == NIL && !isInitPlan && !splan->useHashTable)
479 root->glob->rewindPlanIDs = bms_add_member(root->glob->rewindPlanIDs,
486 * convert_testexpr: convert the testexpr given by the parser into
487 * actually executable form. This entails replacing PARAM_SUBLINK Params
488 * with Params or Vars representing the results of the sub-select:
490 * If rtindex is 0, we build Params to represent the sub-select outputs.
491 * The paramids of the Params created are returned in the *righthandIds list.
493 * If rtindex is not 0, we build Vars using that rtindex as varno. Copies
494 * of the Var nodes are returned in *righthandIds (this is a bit of a type
495 * cheat, but we can get away with it).
497 * The given testexpr has already been recursively processed by
498 * process_sublinks_mutator. Hence it can no longer contain any
499 * PARAM_SUBLINK Params for lower SubLink nodes; we can safely assume that
500 * any we find are for our own level of SubLink.
503 convert_testexpr(PlannerInfo *root,
509 convert_testexpr_context context;
512 context.rtindex = rtindex;
513 context.righthandIds = NIL;
514 result = convert_testexpr_mutator(testexpr, &context);
515 *righthandIds = context.righthandIds;
520 convert_testexpr_mutator(Node *node,
521 convert_testexpr_context *context)
525 if (IsA(node, Param))
527 Param *param = (Param *) node;
529 if (param->paramkind == PARAM_SUBLINK)
532 * We expect to encounter the Params in column-number sequence. We
533 * could handle non-sequential order if necessary, but for now
534 * there's no need. (This is also a useful cross-check that we
535 * aren't finding any unexpected Params.)
537 if (param->paramid != list_length(context->righthandIds) + 1)
538 elog(ERROR, "unexpected PARAM_SUBLINK ID: %d", param->paramid);
540 if (context->rtindex)
542 /* Make the Var node representing the subplan's result */
545 newvar = makeVar(context->rtindex,
552 * Copy it for caller. NB: we need a copy to avoid having
553 * doubly-linked substructure in the modified parse tree.
555 context->righthandIds = lappend(context->righthandIds,
557 return (Node *) newvar;
561 /* Make the Param node representing the subplan's result */
564 newparam = generate_new_param(context->root,
568 context->righthandIds = lappend_int(context->righthandIds,
570 return (Node *) newparam;
574 return expression_tree_mutator(node,
575 convert_testexpr_mutator,
580 * subplan_is_hashable: decide whether we can implement a subplan by hashing
582 * Caution: the SubPlan node is not completely filled in yet. We can rely
583 * on its plan and parParam fields, however.
586 subplan_is_hashable(SubLink *slink, SubPlan *node, Plan *plan)
588 double subquery_size;
592 * The sublink type must be "= ANY" --- that is, an IN operator. We
593 * expect that the test expression will be either a single OpExpr, or an
594 * AND-clause containing OpExprs. (If it's anything else then the parser
595 * must have determined that the operators have non-equality-like
596 * semantics. In the OpExpr case we can't be sure what the operator's
597 * semantics are like, but the test below for hashability will reject
598 * anything that's not equality.)
600 if (slink->subLinkType != ANY_SUBLINK)
602 if (slink->testexpr == NULL ||
603 (!IsA(slink->testexpr, OpExpr) &&
604 !and_clause(slink->testexpr)))
608 * The subplan must not have any direct correlation vars --- else we'd
609 * have to recompute its output each time, so that the hashtable wouldn't
612 if (node->parParam != NIL)
616 * The estimated size of the subquery result must fit in work_mem. (Note:
617 * we use sizeof(HeapTupleHeaderData) here even though the tuples will
618 * actually be stored as MinimalTuples; this provides some fudge factor
619 * for hashtable overhead.)
621 subquery_size = plan->plan_rows *
622 (MAXALIGN(plan->plan_width) + MAXALIGN(sizeof(HeapTupleHeaderData)));
623 if (subquery_size > work_mem * 1024L)
627 * The combining operators must be hashable and strict.
628 * The need for hashability is obvious, since we want to use hashing.
629 * Without strictness, behavior in the presence of nulls is too
630 * unpredictable. We actually must assume even more than plain
631 * strictness: they can't yield NULL for non-null inputs, either
632 * (see nodeSubplan.c). However, hash indexes and hash joins assume
635 if (IsA(slink->testexpr, OpExpr))
637 if (!hash_ok_operator((OpExpr *) slink->testexpr))
642 foreach(l, ((BoolExpr *) slink->testexpr)->args)
644 Node *andarg = (Node *) lfirst(l);
646 if (!IsA(andarg, OpExpr))
647 return false; /* probably can't happen */
648 if (!hash_ok_operator((OpExpr *) andarg))
657 hash_ok_operator(OpExpr *expr)
659 Oid opid = expr->opno;
661 Form_pg_operator optup;
663 tup = SearchSysCache(OPEROID,
664 ObjectIdGetDatum(opid),
666 if (!HeapTupleIsValid(tup))
667 elog(ERROR, "cache lookup failed for operator %u", opid);
668 optup = (Form_pg_operator) GETSTRUCT(tup);
669 if (!optup->oprcanhash || !func_strict(optup->oprcode))
671 ReleaseSysCache(tup);
674 ReleaseSysCache(tup);
679 * convert_IN_to_join: can we convert an IN SubLink to join style?
681 * The caller has found a SubLink at the top level of WHERE, but has not
682 * checked the properties of the SubLink at all. Decide whether it is
683 * appropriate to process this SubLink in join style. If not, return NULL.
684 * If so, build the qual clause(s) to replace the SubLink, and return them.
686 * Side effects of a successful conversion include adding the SubLink's
687 * subselect to the query's rangetable and adding an InClauseInfo node to
691 convert_IN_to_join(PlannerInfo *root, SubLink *sublink)
693 Query *parse = root->parse;
694 Query *subselect = (Query *) sublink->subselect;
700 InClauseInfo *ininfo;
704 * The sublink type must be "= ANY" --- that is, an IN operator. We
705 * expect that the test expression will be either a single OpExpr, or an
706 * AND-clause containing OpExprs. (If it's anything else then the parser
707 * must have determined that the operators have non-equality-like
708 * semantics. In the OpExpr case we can't be sure what the operator's
709 * semantics are like, and must check for ourselves.)
711 if (sublink->subLinkType != ANY_SUBLINK)
713 if (sublink->testexpr && IsA(sublink->testexpr, OpExpr))
715 Oid opno = ((OpExpr *) sublink->testexpr)->opno;
719 get_op_btree_interpretation(opno, &opfamilies, &opstrats);
720 if (!list_member_int(opstrats, ROWCOMPARE_EQ))
722 in_operators = list_make1_oid(opno);
724 else if (and_clause(sublink->testexpr))
728 /* OK, but we need to extract the per-column operator OIDs */
730 foreach(lc, ((BoolExpr *) sublink->testexpr)->args)
732 OpExpr *op = (OpExpr *) lfirst(lc);
734 if (!IsA(op, OpExpr)) /* probably shouldn't happen */
736 in_operators = lappend_oid(in_operators, op->opno);
743 * The sub-select must not refer to any Vars of the parent query. (Vars of
744 * higher levels should be okay, though.)
746 if (contain_vars_of_level((Node *) subselect, 1))
750 * The left-hand expressions must contain some Vars of the current query,
751 * else it's not gonna be a join.
753 left_varnos = pull_varnos(sublink->testexpr);
754 if (bms_is_empty(left_varnos))
758 * The combining operators and left-hand expressions mustn't be volatile.
760 if (contain_volatile_functions(sublink->testexpr))
764 * Okay, pull up the sub-select into top range table and jointree.
766 * We rely here on the assumption that the outer query has no references
767 * to the inner (necessarily true, other than the Vars that we build
768 * below). Therefore this is a lot easier than what pull_up_subqueries has
771 rte = addRangeTableEntryForSubquery(NULL,
773 makeAlias("IN_subquery", NIL),
775 parse->rtable = lappend(parse->rtable, rte);
776 rtindex = list_length(parse->rtable);
777 rtr = makeNode(RangeTblRef);
778 rtr->rtindex = rtindex;
779 parse->jointree->fromlist = lappend(parse->jointree->fromlist, rtr);
782 * Now build the InClauseInfo node.
784 ininfo = makeNode(InClauseInfo);
785 ininfo->lefthand = left_varnos;
786 ininfo->righthand = bms_make_singleton(rtindex);
787 ininfo->in_operators = in_operators;
790 * Build the result qual expression. As a side effect,
791 * ininfo->sub_targetlist is filled with a list of Vars representing the
794 result = convert_testexpr(root,
797 &ininfo->sub_targetlist);
799 Assert(list_length(in_operators) == list_length(ininfo->sub_targetlist));
801 /* Add the completed node to the query's list */
802 root->in_info_list = lappend(root->in_info_list, ininfo);
808 * Replace correlation vars (uplevel vars) with Params.
810 * Uplevel aggregates are replaced, too.
812 * Note: it is critical that this runs immediately after SS_process_sublinks.
813 * Since we do not recurse into the arguments of uplevel aggregates, they will
814 * get copied to the appropriate subplan args list in the parent query with
815 * uplevel vars not replaced by Params, but only adjusted in level (see
816 * replace_outer_agg). That's exactly what we want for the vars of the parent
817 * level --- but if an aggregate's argument contains any further-up variables,
818 * they have to be replaced with Params in their turn. That will happen when
819 * the parent level runs SS_replace_correlation_vars. Therefore it must do
820 * so after expanding its sublinks to subplans. And we don't want any steps
821 * in between, else those steps would never get applied to the aggregate
822 * argument expressions, either in the parent or the child level.
825 SS_replace_correlation_vars(PlannerInfo *root, Node *expr)
827 /* No setup needed for tree walk, so away we go */
828 return replace_correlation_vars_mutator(expr, root);
832 replace_correlation_vars_mutator(Node *node, PlannerInfo *root)
838 if (((Var *) node)->varlevelsup > 0)
839 return (Node *) replace_outer_var(root, (Var *) node);
841 if (IsA(node, Aggref))
843 if (((Aggref *) node)->agglevelsup > 0)
844 return (Node *) replace_outer_agg(root, (Aggref *) node);
846 return expression_tree_mutator(node,
847 replace_correlation_vars_mutator,
852 * Expand SubLinks to SubPlans in the given expression.
854 * The isQual argument tells whether or not this expression is a WHERE/HAVING
855 * qualifier expression. If it is, any sublinks appearing at top level need
856 * not distinguish FALSE from UNKNOWN return values.
859 SS_process_sublinks(PlannerInfo *root, Node *expr, bool isQual)
861 process_sublinks_context context;
864 context.isTopQual = isQual;
865 return process_sublinks_mutator(expr, &context);
869 process_sublinks_mutator(Node *node, process_sublinks_context *context)
871 process_sublinks_context locContext;
873 locContext.root = context->root;
877 if (IsA(node, SubLink))
879 SubLink *sublink = (SubLink *) node;
883 * First, recursively process the lefthand-side expressions, if any.
884 * They're not top-level anymore.
886 locContext.isTopQual = false;
887 testexpr = process_sublinks_mutator(sublink->testexpr, &locContext);
890 * Now build the SubPlan node and make the expr to return.
892 return make_subplan(context->root,
899 * We should never see a SubPlan expression in the input (since this is
900 * the very routine that creates 'em to begin with). We shouldn't find
901 * ourselves invoked directly on a Query, either.
903 Assert(!is_subplan(node));
904 Assert(!IsA(node, Query));
907 * Because make_subplan() could return an AND or OR clause, we have to
908 * take steps to preserve AND/OR flatness of a qual. We assume the input
909 * has been AND/OR flattened and so we need no recursion here.
911 * If we recurse down through anything other than an AND node, we are
912 * definitely not at top qual level anymore. (Due to the coding here, we
913 * will not get called on the List subnodes of an AND, so no check is
916 if (and_clause(node))
921 /* Still at qual top-level */
922 locContext.isTopQual = context->isTopQual;
924 foreach(l, ((BoolExpr *) node)->args)
928 newarg = process_sublinks_mutator(lfirst(l), &locContext);
929 if (and_clause(newarg))
930 newargs = list_concat(newargs, ((BoolExpr *) newarg)->args);
932 newargs = lappend(newargs, newarg);
934 return (Node *) make_andclause(newargs);
937 /* otherwise not at qual top-level */
938 locContext.isTopQual = false;
945 foreach(l, ((BoolExpr *) node)->args)
949 newarg = process_sublinks_mutator(lfirst(l), &locContext);
950 if (or_clause(newarg))
951 newargs = list_concat(newargs, ((BoolExpr *) newarg)->args);
953 newargs = lappend(newargs, newarg);
955 return (Node *) make_orclause(newargs);
958 return expression_tree_mutator(node,
959 process_sublinks_mutator,
960 (void *) &locContext);
964 * SS_finalize_plan - do final sublink processing for a completed Plan.
966 * This recursively computes the extParam and allParam sets for every Plan
967 * node in the given plan tree. It also attaches any generated InitPlans
968 * to the top plan node.
971 SS_finalize_plan(PlannerInfo *root, Plan *plan)
973 Bitmapset *outer_params,
982 * First, scan the param list to discover the sets of params that are
983 * available from outer query levels and my own query level. We do this
984 * once to save time in the per-plan recursion steps.
986 outer_params = valid_params = NULL;
988 foreach(l, root->glob->paramlist)
990 PlannerParamItem *pitem = (PlannerParamItem *) lfirst(l);
992 if (pitem->abslevel < root->query_level)
994 /* valid outer-level parameter */
995 outer_params = bms_add_member(outer_params, paramid);
996 valid_params = bms_add_member(valid_params, paramid);
998 else if (pitem->abslevel == root->query_level &&
999 IsA(pitem->item, Param))
1001 /* valid local parameter (i.e., a setParam of my child) */
1002 valid_params = bms_add_member(valid_params, paramid);
1009 * Now recurse through plan tree.
1011 (void) finalize_plan(root, plan, outer_params, valid_params);
1013 bms_free(outer_params);
1014 bms_free(valid_params);
1017 * Finally, attach any initPlans to the topmost plan node, and add their
1018 * extParams to the topmost node's, too. However, any setParams of the
1019 * initPlans should not be present in the topmost node's extParams, only
1020 * in its allParams. (As of PG 8.1, it's possible that some initPlans
1021 * have extParams that are setParams of other initPlans, so we have to
1022 * take care of this situation explicitly.)
1024 * We also add the total_cost of each initPlan to the startup cost of the
1025 * top node. This is a conservative overestimate, since in fact each
1026 * initPlan might be executed later than plan startup, or even not at all.
1028 plan->initPlan = root->init_plans;
1029 root->init_plans = NIL; /* make sure they're not attached twice */
1031 initExtParam = initSetParam = NULL;
1033 foreach(l, plan->initPlan)
1035 SubPlan *initsubplan = (SubPlan *) lfirst(l);
1036 Plan *initplan = planner_subplan_get_plan(root, initsubplan);
1039 initExtParam = bms_add_members(initExtParam, initplan->extParam);
1040 foreach(l2, initsubplan->setParam)
1042 initSetParam = bms_add_member(initSetParam, lfirst_int(l2));
1044 initplan_cost += initplan->total_cost;
1046 /* allParam must include all these params */
1047 plan->allParam = bms_add_members(plan->allParam, initExtParam);
1048 plan->allParam = bms_add_members(plan->allParam, initSetParam);
1049 /* but extParam shouldn't include any setParams */
1050 initExtParam = bms_del_members(initExtParam, initSetParam);
1051 /* empty test ensures extParam is exactly NULL if it's empty */
1052 if (!bms_is_empty(initExtParam))
1053 plan->extParam = bms_join(plan->extParam, initExtParam);
1055 plan->startup_cost += initplan_cost;
1056 plan->total_cost += initplan_cost;
1060 * Recursive processing of all nodes in the plan tree
1062 * The return value is the computed allParam set for the given Plan node.
1063 * This is just an internal notational convenience.
1066 finalize_plan(PlannerInfo *root, Plan *plan,
1067 Bitmapset *outer_params, Bitmapset *valid_params)
1069 finalize_primnode_context context;
1074 context.root = root;
1075 context.paramids = NULL; /* initialize set to empty */
1076 context.outer_params = outer_params;
1079 * When we call finalize_primnode, context.paramids sets are automatically
1080 * merged together. But when recursing to self, we have to do it the hard
1081 * way. We want the paramids set to include params in subplans as well as
1085 /* Find params in targetlist and qual */
1086 finalize_primnode((Node *) plan->targetlist, &context);
1087 finalize_primnode((Node *) plan->qual, &context);
1089 /* Check additional node-type-specific fields */
1090 switch (nodeTag(plan))
1093 finalize_primnode(((Result *) plan)->resconstantqual,
1098 finalize_primnode((Node *) ((IndexScan *) plan)->indexqual,
1102 * we need not look at indexqualorig, since it will have the same
1103 * param references as indexqual.
1107 case T_BitmapIndexScan:
1108 finalize_primnode((Node *) ((BitmapIndexScan *) plan)->indexqual,
1112 * we need not look at indexqualorig, since it will have the same
1113 * param references as indexqual.
1117 case T_BitmapHeapScan:
1118 finalize_primnode((Node *) ((BitmapHeapScan *) plan)->bitmapqualorig,
1123 finalize_primnode((Node *) ((TidScan *) plan)->tidquals,
1127 case T_SubqueryScan:
1130 * In a SubqueryScan, SS_finalize_plan has already been run on the
1131 * subplan by the inner invocation of subquery_planner, so there's
1132 * no need to do it again. Instead, just pull out the subplan's
1133 * extParams list, which represents the params it needs from my
1134 * level and higher levels.
1136 context.paramids = bms_add_members(context.paramids,
1137 ((SubqueryScan *) plan)->subplan->extParam);
1140 case T_FunctionScan:
1141 finalize_primnode(((FunctionScan *) plan)->funcexpr,
1146 finalize_primnode((Node *) ((ValuesScan *) plan)->values_lists,
1154 foreach(l, ((Append *) plan)->appendplans)
1157 bms_add_members(context.paramids,
1170 foreach(l, ((BitmapAnd *) plan)->bitmapplans)
1173 bms_add_members(context.paramids,
1186 foreach(l, ((BitmapOr *) plan)->bitmapplans)
1189 bms_add_members(context.paramids,
1199 finalize_primnode((Node *) ((Join *) plan)->joinqual,
1204 finalize_primnode((Node *) ((Join *) plan)->joinqual,
1206 finalize_primnode((Node *) ((MergeJoin *) plan)->mergeclauses,
1211 finalize_primnode((Node *) ((Join *) plan)->joinqual,
1213 finalize_primnode((Node *) ((HashJoin *) plan)->hashclauses,
1218 finalize_primnode(((Limit *) plan)->limitOffset,
1220 finalize_primnode(((Limit *) plan)->limitCount,
1235 elog(ERROR, "unrecognized node type: %d",
1236 (int) nodeTag(plan));
1239 /* Process left and right child plans, if any */
1240 context.paramids = bms_add_members(context.paramids,
1246 context.paramids = bms_add_members(context.paramids,
1252 /* Now we have all the paramids */
1254 if (!bms_is_subset(context.paramids, valid_params))
1255 elog(ERROR, "plan should not reference subplan's variable");
1257 plan->extParam = bms_intersect(context.paramids, outer_params);
1258 plan->allParam = context.paramids;
1261 * For speed at execution time, make sure extParam/allParam are actually
1262 * NULL if they are empty sets.
1264 if (bms_is_empty(plan->extParam))
1266 bms_free(plan->extParam);
1267 plan->extParam = NULL;
1269 if (bms_is_empty(plan->allParam))
1271 bms_free(plan->allParam);
1272 plan->allParam = NULL;
1275 return plan->allParam;
1279 * finalize_primnode: add IDs of all PARAM_EXEC params appearing in the given
1280 * expression tree to the result set.
1283 finalize_primnode(Node *node, finalize_primnode_context *context)
1287 if (IsA(node, Param))
1289 if (((Param *) node)->paramkind == PARAM_EXEC)
1291 int paramid = ((Param *) node)->paramid;
1293 context->paramids = bms_add_member(context->paramids, paramid);
1295 return false; /* no more to do here */
1297 if (is_subplan(node))
1299 SubPlan *subplan = (SubPlan *) node;
1300 Plan *plan = planner_subplan_get_plan(context->root, subplan);
1302 /* Add outer-level params needed by the subplan to paramids */
1303 context->paramids = bms_join(context->paramids,
1304 bms_intersect(plan->extParam,
1305 context->outer_params));
1306 /* fall through to recurse into subplan args */
1308 return expression_tree_walker(node, finalize_primnode,
1313 * SS_make_initplan_from_plan - given a plan tree, make it an InitPlan
1315 * The plan is expected to return a scalar value of the indicated type.
1316 * We build an EXPR_SUBLINK SubPlan node and put it into the initplan
1317 * list for the current query level. A Param that represents the initplan's
1318 * output is returned.
1320 * We assume the plan hasn't been put through SS_finalize_plan.
1323 SS_make_initplan_from_plan(PlannerInfo *root, Plan *plan,
1324 Oid resulttype, int32 resulttypmod)
1326 List *saved_init_plans;
1331 * We must run SS_finalize_plan(), since that's normally done before a
1332 * subplan gets put into the initplan list. However it will try to attach
1333 * any pre-existing initplans to this one, which we don't want (they are
1334 * siblings not children of this initplan). So, a quick kluge to hide
1335 * them. (This is something else that could perhaps be cleaner if we did
1336 * extParam/allParam processing in setrefs.c instead of here? See notes
1337 * for materialize_finished_plan.)
1339 saved_init_plans = root->init_plans;
1340 root->init_plans = NIL;
1343 * Build extParam/allParam sets for plan nodes.
1345 SS_finalize_plan(root, plan);
1347 /* Restore outer initplan list */
1348 root->init_plans = saved_init_plans;
1351 * Add the subplan and its rtable to the global lists.
1353 root->glob->subplans = lappend(root->glob->subplans,
1355 root->glob->subrtables = lappend(root->glob->subrtables,
1356 root->parse->rtable);
1359 * Create a SubPlan node and add it to the outer list of InitPlans.
1361 node = makeNode(SubPlan);
1362 node->subLinkType = EXPR_SUBLINK;
1363 node->firstColType = get_first_col_type(plan);
1364 node->plan_id = list_length(root->glob->subplans);
1366 root->init_plans = lappend(root->init_plans, node);
1369 * The node can't have any inputs (since it's an initplan), so the
1370 * parParam and args lists remain empty.
1374 * Make a Param that will be the subplan's output.
1376 prm = generate_new_param(root, resulttype, resulttypmod);
1377 node->setParam = list_make1_int(prm->paramid);