]> granicus.if.org Git - postgresql/blob - src/backend/optimizer/plan/subselect.c
Change the planner-to-executor API so that the planner tells the executor
[postgresql] / src / backend / optimizer / plan / subselect.c
1 /*-------------------------------------------------------------------------
2  *
3  * subselect.c
4  *        Planning routines for subselects and parameters.
5  *
6  * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
7  * Portions Copyright (c) 1994, Regents of the University of California
8  *
9  * IDENTIFICATION
10  *        $PostgreSQL: pgsql/src/backend/optimizer/plan/subselect.c,v 1.117 2007/01/10 18:06:03 tgl Exp $
11  *
12  *-------------------------------------------------------------------------
13  */
14 #include "postgres.h"
15
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"
32
33
34 Index           PlannerQueryLevel;      /* level of current query */
35 List       *PlannerInitPlan;    /* init subplans for current query */
36 List       *PlannerParamList;   /* to keep track of cross-level Params */
37
38 int                     PlannerPlanId = 0;      /* to assign unique ID to subquery plans */
39
40 /*
41  * PlannerParamList keeps track of the PARAM_EXEC slots that we have decided
42  * we need for the query.  At runtime these slots are used to pass values
43  * either down into subqueries (for outer references in subqueries) or up out
44  * of subqueries (for the results of a subplan).  The n'th entry in the list
45  * (n counts from 0) corresponds to Param->paramid = n.
46  *
47  * Each ParamList item shows the absolute query level it is associated with,
48  * where the outermost query is level 1 and nested subqueries have higher
49  * numbers.  The item the parameter slot represents can be one of three kinds:
50  *
51  * A Var: the slot represents a variable of that level that must be passed
52  * down because subqueries have outer references to it.  The varlevelsup
53  * value in the Var will always be zero.
54  *
55  * An Aggref (with an expression tree representing its argument): the slot
56  * represents an aggregate expression that is an outer reference for some
57  * subquery.  The Aggref itself has agglevelsup = 0, and its argument tree
58  * is adjusted to match in level.
59  *
60  * A Param: the slot holds the result of a subplan (it is a setParam item
61  * for that subplan).  The absolute level shown for such items corresponds
62  * to the parent query of the subplan.
63  *
64  * Note: we detect duplicate Var parameters and coalesce them into one slot,
65  * but we do not do this for Aggref or Param slots.
66  */
67 typedef struct PlannerParamItem
68 {
69         Node       *item;                       /* the Var, Aggref, or Param */
70         Index           abslevel;               /* its absolute query level */
71 } PlannerParamItem;
72
73
74 typedef struct convert_testexpr_context
75 {
76         int                     rtindex;                /* RT index for Vars, or 0 for Params */
77         List       *righthandIds;       /* accumulated list of Vars or Param IDs */
78 } convert_testexpr_context;
79
80 typedef struct finalize_primnode_context
81 {
82         Bitmapset  *paramids;           /* Set of PARAM_EXEC paramids found */
83         Bitmapset  *outer_params;       /* Set of accessible outer paramids */
84 } finalize_primnode_context;
85
86
87 static Node *convert_testexpr(Node *testexpr,
88                                  int rtindex,
89                                  List **righthandIds);
90 static Node *convert_testexpr_mutator(Node *node,
91                                                  convert_testexpr_context *context);
92 static bool subplan_is_hashable(SubLink *slink, SubPlan *node);
93 static bool hash_ok_operator(OpExpr *expr);
94 static Node *replace_correlation_vars_mutator(Node *node, void *context);
95 static Node *process_sublinks_mutator(Node *node, bool *isTopQual);
96 static Bitmapset *finalize_plan(Plan *plan, List *rtable,
97                           Bitmapset *outer_params,
98                           Bitmapset *valid_params);
99 static bool finalize_primnode(Node *node, finalize_primnode_context *context);
100
101
102 /*
103  * Generate a Param node to replace the given Var,
104  * which is expected to have varlevelsup > 0 (ie, it is not local).
105  */
106 static Param *
107 replace_outer_var(Var *var)
108 {
109         Param      *retval;
110         ListCell   *ppl;
111         PlannerParamItem *pitem;
112         Index           abslevel;
113         int                     i;
114
115         Assert(var->varlevelsup > 0 && var->varlevelsup < PlannerQueryLevel);
116         abslevel = PlannerQueryLevel - var->varlevelsup;
117
118         /*
119          * If there's already a PlannerParamList entry for this same Var, just use
120          * it.  NOTE: in sufficiently complex querytrees, it is possible for the
121          * same varno/abslevel to refer to different RTEs in different parts of
122          * the parsetree, so that different fields might end up sharing the same
123          * Param number.  As long as we check the vartype as well, I believe that
124          * this sort of aliasing will cause no trouble. The correct field should
125          * get stored into the Param slot at execution in each part of the tree.
126          *
127          * We also need to demand a match on vartypmod.  This does not matter for
128          * the Param itself, since those are not typmod-dependent, but it does
129          * matter when make_subplan() instantiates a modified copy of the Var for
130          * a subplan's args list.
131          */
132         i = 0;
133         foreach(ppl, PlannerParamList)
134         {
135                 pitem = (PlannerParamItem *) lfirst(ppl);
136                 if (pitem->abslevel == abslevel && IsA(pitem->item, Var))
137                 {
138                         Var                *pvar = (Var *) pitem->item;
139
140                         if (pvar->varno == var->varno &&
141                                 pvar->varattno == var->varattno &&
142                                 pvar->vartype == var->vartype &&
143                                 pvar->vartypmod == var->vartypmod)
144                                 break;
145                 }
146                 i++;
147         }
148
149         if (!ppl)
150         {
151                 /* Nope, so make a new one */
152                 var = (Var *) copyObject(var);
153                 var->varlevelsup = 0;
154
155                 pitem = (PlannerParamItem *) palloc(sizeof(PlannerParamItem));
156                 pitem->item = (Node *) var;
157                 pitem->abslevel = abslevel;
158
159                 PlannerParamList = lappend(PlannerParamList, pitem);
160                 /* i is already the correct index for the new item */
161         }
162
163         retval = makeNode(Param);
164         retval->paramkind = PARAM_EXEC;
165         retval->paramid = i;
166         retval->paramtype = var->vartype;
167         retval->paramtypmod = var->vartypmod;
168
169         return retval;
170 }
171
172 /*
173  * Generate a Param node to replace the given Aggref
174  * which is expected to have agglevelsup > 0 (ie, it is not local).
175  */
176 static Param *
177 replace_outer_agg(Aggref *agg)
178 {
179         Param      *retval;
180         PlannerParamItem *pitem;
181         Index           abslevel;
182         int                     i;
183
184         Assert(agg->agglevelsup > 0 && agg->agglevelsup < PlannerQueryLevel);
185         abslevel = PlannerQueryLevel - agg->agglevelsup;
186
187         /*
188          * It does not seem worthwhile to try to match duplicate outer aggs. Just
189          * make a new slot every time.
190          */
191         agg = (Aggref *) copyObject(agg);
192         IncrementVarSublevelsUp((Node *) agg, -((int) agg->agglevelsup), 0);
193         Assert(agg->agglevelsup == 0);
194
195         pitem = (PlannerParamItem *) palloc(sizeof(PlannerParamItem));
196         pitem->item = (Node *) agg;
197         pitem->abslevel = abslevel;
198
199         PlannerParamList = lappend(PlannerParamList, pitem);
200         i = list_length(PlannerParamList) - 1;
201
202         retval = makeNode(Param);
203         retval->paramkind = PARAM_EXEC;
204         retval->paramid = i;
205         retval->paramtype = agg->aggtype;
206         retval->paramtypmod = -1;
207
208         return retval;
209 }
210
211 /*
212  * Generate a new Param node that will not conflict with any other.
213  *
214  * This is used to allocate PARAM_EXEC slots for subplan outputs.
215  */
216 static Param *
217 generate_new_param(Oid paramtype, int32 paramtypmod)
218 {
219         Param      *retval;
220         PlannerParamItem *pitem;
221
222         retval = makeNode(Param);
223         retval->paramkind = PARAM_EXEC;
224         retval->paramid = list_length(PlannerParamList);
225         retval->paramtype = paramtype;
226         retval->paramtypmod = paramtypmod;
227
228         pitem = (PlannerParamItem *) palloc(sizeof(PlannerParamItem));
229         pitem->item = (Node *) retval;
230         pitem->abslevel = PlannerQueryLevel;
231
232         PlannerParamList = lappend(PlannerParamList, pitem);
233
234         return retval;
235 }
236
237 /*
238  * Convert a SubLink (as created by the parser) into a SubPlan.
239  *
240  * We are given the original SubLink and the already-processed testexpr
241  * (use this instead of the SubLink's own field).  We are also told if
242  * this expression appears at top level of a WHERE/HAVING qual.
243  *
244  * The result is whatever we need to substitute in place of the SubLink
245  * node in the executable expression.  This will be either the SubPlan
246  * node (if we have to do the subplan as a subplan), or a Param node
247  * representing the result of an InitPlan, or a row comparison expression
248  * tree containing InitPlan Param nodes.
249  */
250 static Node *
251 make_subplan(SubLink *slink, Node *testexpr, bool isTopQual)
252 {
253         SubPlan    *node = makeNode(SubPlan);
254         Query      *subquery = (Query *) (slink->subselect);
255         double          tuple_fraction;
256         Plan       *plan;
257         Bitmapset  *tmpset;
258         int                     paramid;
259         Node       *result;
260
261         /*
262          * Copy the source Query node.  This is a quick and dirty kluge to resolve
263          * the fact that the parser can generate trees with multiple links to the
264          * same sub-Query node, but the planner wants to scribble on the Query.
265          * Try to clean this up when we do querytree redesign...
266          */
267         subquery = (Query *) copyObject(subquery);
268
269         /*
270          * For an EXISTS subplan, tell lower-level planner to expect that only the
271          * first tuple will be retrieved.  For ALL and ANY subplans, we will be
272          * able to stop evaluating if the test condition fails, so very often not
273          * all the tuples will be retrieved; for lack of a better idea, specify
274          * 50% retrieval.  For EXPR and ROWCOMPARE subplans, use default behavior
275          * (we're only expecting one row out, anyway).
276          *
277          * NOTE: if you change these numbers, also change cost_qual_eval_walker()
278          * in path/costsize.c.
279          *
280          * XXX If an ALL/ANY subplan is uncorrelated, we may decide to hash or
281          * materialize its result below.  In that case it would've been better to
282          * specify full retrieval.      At present, however, we can only detect
283          * correlation or lack of it after we've made the subplan :-(. Perhaps
284          * detection of correlation should be done as a separate step. Meanwhile,
285          * we don't want to be too optimistic about the percentage of tuples
286          * retrieved, for fear of selecting a plan that's bad for the
287          * materialization case.
288          */
289         if (slink->subLinkType == EXISTS_SUBLINK)
290                 tuple_fraction = 1.0;   /* just like a LIMIT 1 */
291         else if (slink->subLinkType == ALL_SUBLINK ||
292                          slink->subLinkType == ANY_SUBLINK)
293                 tuple_fraction = 0.5;   /* 50% */
294         else
295                 tuple_fraction = 0.0;   /* default behavior */
296
297         /*
298          * Generate the plan for the subquery.
299          */
300         node->plan = plan = subquery_planner(subquery, tuple_fraction, NULL);
301
302         node->plan_id = PlannerPlanId++;        /* Assign unique ID to this SubPlan */
303
304         node->rtable = subquery->rtable;
305
306         /*
307          * Initialize other fields of the SubPlan node.
308          */
309         node->subLinkType = slink->subLinkType;
310         node->testexpr = NULL;
311         node->paramIds = NIL;
312         node->useHashTable = false;
313         /* At top level of a qual, can treat UNKNOWN the same as FALSE */
314         node->unknownEqFalse = isTopQual;
315         node->setParam = NIL;
316         node->parParam = NIL;
317         node->args = NIL;
318
319         /*
320          * Make parParam list of params that current query level will pass to this
321          * child plan.
322          */
323         tmpset = bms_copy(plan->extParam);
324         while ((paramid = bms_first_member(tmpset)) >= 0)
325         {
326                 PlannerParamItem *pitem = list_nth(PlannerParamList, paramid);
327
328                 if (pitem->abslevel == PlannerQueryLevel)
329                         node->parParam = lappend_int(node->parParam, paramid);
330         }
331         bms_free(tmpset);
332
333         /*
334          * Un-correlated or undirect correlated plans of EXISTS, EXPR, ARRAY, or
335          * ROWCOMPARE types can be used as initPlans.  For EXISTS, EXPR, or ARRAY,
336          * we just produce a Param referring to the result of evaluating the
337          * initPlan.  For ROWCOMPARE, we must modify the testexpr tree to contain
338          * PARAM_EXEC Params instead of the PARAM_SUBLINK Params emitted by the
339          * parser.
340          */
341         if (node->parParam == NIL && slink->subLinkType == EXISTS_SUBLINK)
342         {
343                 Param      *prm;
344
345                 prm = generate_new_param(BOOLOID, -1);
346                 node->setParam = list_make1_int(prm->paramid);
347                 PlannerInitPlan = lappend(PlannerInitPlan, node);
348                 result = (Node *) prm;
349         }
350         else if (node->parParam == NIL && slink->subLinkType == EXPR_SUBLINK)
351         {
352                 TargetEntry *te = linitial(plan->targetlist);
353                 Param      *prm;
354
355                 Assert(!te->resjunk);
356                 prm = generate_new_param(exprType((Node *) te->expr),
357                                                                  exprTypmod((Node *) te->expr));
358                 node->setParam = list_make1_int(prm->paramid);
359                 PlannerInitPlan = lappend(PlannerInitPlan, node);
360                 result = (Node *) prm;
361         }
362         else if (node->parParam == NIL && slink->subLinkType == ARRAY_SUBLINK)
363         {
364                 TargetEntry *te = linitial(plan->targetlist);
365                 Oid                     arraytype;
366                 Param      *prm;
367
368                 Assert(!te->resjunk);
369                 arraytype = get_array_type(exprType((Node *) te->expr));
370                 if (!OidIsValid(arraytype))
371                         elog(ERROR, "could not find array type for datatype %s",
372                                  format_type_be(exprType((Node *) te->expr)));
373                 prm = generate_new_param(arraytype, exprTypmod((Node *) te->expr));
374                 node->setParam = list_make1_int(prm->paramid);
375                 PlannerInitPlan = lappend(PlannerInitPlan, node);
376                 result = (Node *) prm;
377         }
378         else if (node->parParam == NIL && slink->subLinkType == ROWCOMPARE_SUBLINK)
379         {
380                 /* Adjust the Params */
381                 result = convert_testexpr(testexpr,
382                                                                   0,
383                                                                   &node->paramIds);
384                 node->setParam = list_copy(node->paramIds);
385                 PlannerInitPlan = lappend(PlannerInitPlan, node);
386
387                 /*
388                  * The executable expression is returned to become part of the outer
389                  * plan's expression tree; it is not kept in the initplan node.
390                  */
391         }
392         else
393         {
394                 List       *args;
395                 ListCell   *l;
396
397                 /* Adjust the Params */
398                 node->testexpr = convert_testexpr(testexpr,
399                                                                                   0,
400                                                                                   &node->paramIds);
401
402                 /*
403                  * We can't convert subplans of ALL_SUBLINK or ANY_SUBLINK types to
404                  * initPlans, even when they are uncorrelated or undirect correlated,
405                  * because we need to scan the output of the subplan for each outer
406                  * tuple.  But if it's an IN (= ANY) test, we might be able to use a
407                  * hashtable to avoid comparing all the tuples.
408                  */
409                 if (subplan_is_hashable(slink, node))
410                         node->useHashTable = true;
411
412                 /*
413                  * Otherwise, we have the option to tack a MATERIAL node onto the top
414                  * of the subplan, to reduce the cost of reading it repeatedly.  This
415                  * is pointless for a direct-correlated subplan, since we'd have to
416                  * recompute its results each time anyway.      For uncorrelated/undirect
417                  * correlated subplans, we add MATERIAL unless the subplan's top plan
418                  * node would materialize its output anyway.
419                  */
420                 else if (node->parParam == NIL)
421                 {
422                         bool            use_material;
423
424                         switch (nodeTag(plan))
425                         {
426                                 case T_Material:
427                                 case T_FunctionScan:
428                                 case T_Sort:
429                                         use_material = false;
430                                         break;
431                                 default:
432                                         use_material = true;
433                                         break;
434                         }
435                         if (use_material)
436                                 node->plan = plan = materialize_finished_plan(plan);
437                 }
438
439                 /*
440                  * Make node->args from parParam.
441                  */
442                 args = NIL;
443                 foreach(l, node->parParam)
444                 {
445                         PlannerParamItem *pitem = list_nth(PlannerParamList, lfirst_int(l));
446
447                         /*
448                          * The Var or Aggref has already been adjusted to have the correct
449                          * varlevelsup or agglevelsup.  We probably don't even need to
450                          * copy it again, but be safe.
451                          */
452                         args = lappend(args, copyObject(pitem->item));
453                 }
454                 node->args = args;
455
456                 result = (Node *) node;
457         }
458
459         return result;
460 }
461
462 /*
463  * convert_testexpr: convert the testexpr given by the parser into
464  * actually executable form.  This entails replacing PARAM_SUBLINK Params
465  * with Params or Vars representing the results of the sub-select:
466  *
467  * If rtindex is 0, we build Params to represent the sub-select outputs.
468  * The paramids of the Params created are returned in the *righthandIds list.
469  *
470  * If rtindex is not 0, we build Vars using that rtindex as varno.      Copies
471  * of the Var nodes are returned in *righthandIds (this is a bit of a type
472  * cheat, but we can get away with it).
473  *
474  * The given testexpr has already been recursively processed by
475  * process_sublinks_mutator.  Hence it can no longer contain any
476  * PARAM_SUBLINK Params for lower SubLink nodes; we can safely assume that
477  * any we find are for our own level of SubLink.
478  */
479 static Node *
480 convert_testexpr(Node *testexpr,
481                                  int rtindex,
482                                  List **righthandIds)
483 {
484         Node       *result;
485         convert_testexpr_context context;
486
487         context.rtindex = rtindex;
488         context.righthandIds = NIL;
489         result = convert_testexpr_mutator(testexpr, &context);
490         *righthandIds = context.righthandIds;
491         return result;
492 }
493
494 static Node *
495 convert_testexpr_mutator(Node *node,
496                                                  convert_testexpr_context *context)
497 {
498         if (node == NULL)
499                 return NULL;
500         if (IsA(node, Param))
501         {
502                 Param      *param = (Param *) node;
503
504                 if (param->paramkind == PARAM_SUBLINK)
505                 {
506                         /*
507                          * We expect to encounter the Params in column-number sequence. We
508                          * could handle non-sequential order if necessary, but for now
509                          * there's no need.  (This is also a useful cross-check that we
510                          * aren't finding any unexpected Params.)
511                          */
512                         if (param->paramid != list_length(context->righthandIds) + 1)
513                                 elog(ERROR, "unexpected PARAM_SUBLINK ID: %d", param->paramid);
514
515                         if (context->rtindex)
516                         {
517                                 /* Make the Var node representing the subplan's result */
518                                 Var                *newvar;
519
520                                 newvar = makeVar(context->rtindex,
521                                                                  param->paramid,
522                                                                  param->paramtype,
523                                                                  param->paramtypmod,
524                                                                  0);
525
526                                 /*
527                                  * Copy it for caller.  NB: we need a copy to avoid having
528                                  * doubly-linked substructure in the modified parse tree.
529                                  */
530                                 context->righthandIds = lappend(context->righthandIds,
531                                                                                                 copyObject(newvar));
532                                 return (Node *) newvar;
533                         }
534                         else
535                         {
536                                 /* Make the Param node representing the subplan's result */
537                                 Param      *newparam;
538
539                                 newparam = generate_new_param(param->paramtype,
540                                                                                           param->paramtypmod);
541                                 /* Record its ID */
542                                 context->righthandIds = lappend_int(context->righthandIds,
543                                                                                                         newparam->paramid);
544                                 return (Node *) newparam;
545                         }
546                 }
547         }
548         return expression_tree_mutator(node,
549                                                                    convert_testexpr_mutator,
550                                                                    (void *) context);
551 }
552
553 /*
554  * subplan_is_hashable: decide whether we can implement a subplan by hashing
555  *
556  * Caution: the SubPlan node is not completely filled in yet.  We can rely
557  * on its plan and parParam fields, however.
558  */
559 static bool
560 subplan_is_hashable(SubLink *slink, SubPlan *node)
561 {
562         double          subquery_size;
563         ListCell   *l;
564
565         /*
566          * The sublink type must be "= ANY" --- that is, an IN operator.  We
567          * expect that the test expression will be either a single OpExpr, or an
568          * AND-clause containing OpExprs.  (If it's anything else then the parser
569          * must have determined that the operators have non-equality-like
570          * semantics.  In the OpExpr case we can't be sure what the operator's
571          * semantics are like, but the test below for hashability will reject
572          * anything that's not equality.)
573          */
574         if (slink->subLinkType != ANY_SUBLINK)
575                 return false;
576         if (slink->testexpr == NULL ||
577                 (!IsA(slink->testexpr, OpExpr) &&
578                  !and_clause(slink->testexpr)))
579                 return false;
580
581         /*
582          * The subplan must not have any direct correlation vars --- else we'd
583          * have to recompute its output each time, so that the hashtable wouldn't
584          * gain anything.
585          */
586         if (node->parParam != NIL)
587                 return false;
588
589         /*
590          * The estimated size of the subquery result must fit in work_mem. (Note:
591          * we use sizeof(HeapTupleHeaderData) here even though the tuples will
592          * actually be stored as MinimalTuples; this provides some fudge factor
593          * for hashtable overhead.)
594          */
595         subquery_size = node->plan->plan_rows *
596                 (MAXALIGN(node->plan->plan_width) + MAXALIGN(sizeof(HeapTupleHeaderData)));
597         if (subquery_size > work_mem * 1024L)
598                 return false;
599
600         /*
601          * The combining operators must be hashable, strict, and self-commutative.
602          * The need for hashability is obvious, since we want to use hashing.
603          * Without strictness, behavior in the presence of nulls is too
604          * unpredictable.  (We actually must assume even more than plain
605          * strictness, see nodeSubplan.c for details.)  And commutativity ensures
606          * that the left and right datatypes are the same; this allows us to
607          * assume that the combining operators are equality for the righthand
608          * datatype, so that they can be used to compare righthand tuples as well
609          * as comparing lefthand to righthand tuples.  (This last restriction
610          * could be relaxed by using two different sets of operators with the hash
611          * table, but there is no obvious usefulness to that at present.)
612          */
613         if (IsA(slink->testexpr, OpExpr))
614         {
615                 if (!hash_ok_operator((OpExpr *) slink->testexpr))
616                         return false;
617         }
618         else
619         {
620                 foreach(l, ((BoolExpr *) slink->testexpr)->args)
621                 {
622                         Node       *andarg = (Node *) lfirst(l);
623
624                         if (!IsA(andarg, OpExpr))
625                                 return false;   /* probably can't happen */
626                         if (!hash_ok_operator((OpExpr *) andarg))
627                                 return false;
628                 }
629         }
630
631         return true;
632 }
633
634 static bool
635 hash_ok_operator(OpExpr *expr)
636 {
637         Oid                     opid = expr->opno;
638         HeapTuple       tup;
639         Form_pg_operator optup;
640
641         tup = SearchSysCache(OPEROID,
642                                                  ObjectIdGetDatum(opid),
643                                                  0, 0, 0);
644         if (!HeapTupleIsValid(tup))
645                 elog(ERROR, "cache lookup failed for operator %u", opid);
646         optup = (Form_pg_operator) GETSTRUCT(tup);
647         if (!optup->oprcanhash || optup->oprcom != opid ||
648                 !func_strict(optup->oprcode))
649         {
650                 ReleaseSysCache(tup);
651                 return false;
652         }
653         ReleaseSysCache(tup);
654         return true;
655 }
656
657 /*
658  * convert_IN_to_join: can we convert an IN SubLink to join style?
659  *
660  * The caller has found a SubLink at the top level of WHERE, but has not
661  * checked the properties of the SubLink at all.  Decide whether it is
662  * appropriate to process this SubLink in join style.  If not, return NULL.
663  * If so, build the qual clause(s) to replace the SubLink, and return them.
664  *
665  * Side effects of a successful conversion include adding the SubLink's
666  * subselect to the query's rangetable and adding an InClauseInfo node to
667  * its in_info_list.
668  */
669 Node *
670 convert_IN_to_join(PlannerInfo *root, SubLink *sublink)
671 {
672         Query      *parse = root->parse;
673         Query      *subselect = (Query *) sublink->subselect;
674         List       *in_operators;
675         Relids          left_varnos;
676         int                     rtindex;
677         RangeTblEntry *rte;
678         RangeTblRef *rtr;
679         InClauseInfo *ininfo;
680         Node       *result;
681
682         /*
683          * The sublink type must be "= ANY" --- that is, an IN operator.  We
684          * expect that the test expression will be either a single OpExpr, or an
685          * AND-clause containing OpExprs.  (If it's anything else then the parser
686          * must have determined that the operators have non-equality-like
687          * semantics.  In the OpExpr case we can't be sure what the operator's
688          * semantics are like, and must check for ourselves.)
689          */
690         if (sublink->subLinkType != ANY_SUBLINK)
691                 return NULL;
692         if (sublink->testexpr && IsA(sublink->testexpr, OpExpr))
693         {
694                 Oid                     opno = ((OpExpr *) sublink->testexpr)->opno;
695                 List       *opfamilies;
696                 List       *opstrats;
697
698                 get_op_btree_interpretation(opno, &opfamilies, &opstrats);
699                 if (!list_member_int(opstrats, ROWCOMPARE_EQ))
700                         return NULL;
701                 in_operators = list_make1_oid(opno);
702         }
703         else if (and_clause(sublink->testexpr))
704         {
705                 ListCell   *lc;
706
707                 /* OK, but we need to extract the per-column operator OIDs */
708                 in_operators = NIL;
709                 foreach(lc, ((BoolExpr *) sublink->testexpr)->args)
710                 {
711                         OpExpr *op = (OpExpr *) lfirst(lc);
712
713                         if (!IsA(op, OpExpr))           /* probably shouldn't happen */
714                                 return NULL;
715                         in_operators = lappend_oid(in_operators, op->opno);
716                 }
717         }
718         else
719                 return NULL;
720
721         /*
722          * The sub-select must not refer to any Vars of the parent query. (Vars of
723          * higher levels should be okay, though.)
724          */
725         if (contain_vars_of_level((Node *) subselect, 1))
726                 return NULL;
727
728         /*
729          * The left-hand expressions must contain some Vars of the current query,
730          * else it's not gonna be a join.
731          */
732         left_varnos = pull_varnos(sublink->testexpr);
733         if (bms_is_empty(left_varnos))
734                 return NULL;
735
736         /*
737          * The combining operators and left-hand expressions mustn't be volatile.
738          */
739         if (contain_volatile_functions(sublink->testexpr))
740                 return NULL;
741
742         /*
743          * Okay, pull up the sub-select into top range table and jointree.
744          *
745          * We rely here on the assumption that the outer query has no references
746          * to the inner (necessarily true, other than the Vars that we build
747          * below). Therefore this is a lot easier than what pull_up_subqueries has
748          * to go through.
749          */
750         rte = addRangeTableEntryForSubquery(NULL,
751                                                                                 subselect,
752                                                                                 makeAlias("IN_subquery", NIL),
753                                                                                 false);
754         parse->rtable = lappend(parse->rtable, rte);
755         rtindex = list_length(parse->rtable);
756         rtr = makeNode(RangeTblRef);
757         rtr->rtindex = rtindex;
758         parse->jointree->fromlist = lappend(parse->jointree->fromlist, rtr);
759
760         /*
761          * Now build the InClauseInfo node.
762          */
763         ininfo = makeNode(InClauseInfo);
764         ininfo->lefthand = left_varnos;
765         ininfo->righthand = bms_make_singleton(rtindex);
766         ininfo->in_operators = in_operators;
767
768         /*
769          * Build the result qual expression.  As a side effect,
770          * ininfo->sub_targetlist is filled with a list of Vars representing the
771          * subselect outputs.
772          */
773         result = convert_testexpr(sublink->testexpr,
774                                                           rtindex,
775                                                           &ininfo->sub_targetlist);
776
777         Assert(list_length(in_operators) == list_length(ininfo->sub_targetlist));
778
779         /* Add the completed node to the query's list */
780         root->in_info_list = lappend(root->in_info_list, ininfo);
781
782         return result;
783 }
784
785 /*
786  * Replace correlation vars (uplevel vars) with Params.
787  *
788  * Uplevel aggregates are replaced, too.
789  *
790  * Note: it is critical that this runs immediately after SS_process_sublinks.
791  * Since we do not recurse into the arguments of uplevel aggregates, they will
792  * get copied to the appropriate subplan args list in the parent query with
793  * uplevel vars not replaced by Params, but only adjusted in level (see
794  * replace_outer_agg).  That's exactly what we want for the vars of the parent
795  * level --- but if an aggregate's argument contains any further-up variables,
796  * they have to be replaced with Params in their turn.  That will happen when
797  * the parent level runs SS_replace_correlation_vars.  Therefore it must do
798  * so after expanding its sublinks to subplans.  And we don't want any steps
799  * in between, else those steps would never get applied to the aggregate
800  * argument expressions, either in the parent or the child level.
801  */
802 Node *
803 SS_replace_correlation_vars(Node *expr)
804 {
805         /* No setup needed for tree walk, so away we go */
806         return replace_correlation_vars_mutator(expr, NULL);
807 }
808
809 static Node *
810 replace_correlation_vars_mutator(Node *node, void *context)
811 {
812         if (node == NULL)
813                 return NULL;
814         if (IsA(node, Var))
815         {
816                 if (((Var *) node)->varlevelsup > 0)
817                         return (Node *) replace_outer_var((Var *) node);
818         }
819         if (IsA(node, Aggref))
820         {
821                 if (((Aggref *) node)->agglevelsup > 0)
822                         return (Node *) replace_outer_agg((Aggref *) node);
823         }
824         return expression_tree_mutator(node,
825                                                                    replace_correlation_vars_mutator,
826                                                                    context);
827 }
828
829 /*
830  * Expand SubLinks to SubPlans in the given expression.
831  *
832  * The isQual argument tells whether or not this expression is a WHERE/HAVING
833  * qualifier expression.  If it is, any sublinks appearing at top level need
834  * not distinguish FALSE from UNKNOWN return values.
835  */
836 Node *
837 SS_process_sublinks(Node *expr, bool isQual)
838 {
839         /* The only context needed is the initial are-we-in-a-qual flag */
840         return process_sublinks_mutator(expr, &isQual);
841 }
842
843 static Node *
844 process_sublinks_mutator(Node *node, bool *isTopQual)
845 {
846         bool            locTopQual;
847
848         if (node == NULL)
849                 return NULL;
850         if (IsA(node, SubLink))
851         {
852                 SubLink    *sublink = (SubLink *) node;
853                 Node       *testexpr;
854
855                 /*
856                  * First, recursively process the lefthand-side expressions, if any.
857                  */
858                 locTopQual = false;
859                 testexpr = process_sublinks_mutator(sublink->testexpr, &locTopQual);
860
861                 /*
862                  * Now build the SubPlan node and make the expr to return.
863                  */
864                 return make_subplan(sublink, testexpr, *isTopQual);
865         }
866
867         /*
868          * We should never see a SubPlan expression in the input (since this is
869          * the very routine that creates 'em to begin with).  We shouldn't find
870          * ourselves invoked directly on a Query, either.
871          */
872         Assert(!is_subplan(node));
873         Assert(!IsA(node, Query));
874
875         /*
876          * Because make_subplan() could return an AND or OR clause, we have to
877          * take steps to preserve AND/OR flatness of a qual.  We assume the input
878          * has been AND/OR flattened and so we need no recursion here.
879          *
880          * If we recurse down through anything other than an AND node, we are
881          * definitely not at top qual level anymore.  (Due to the coding here, we
882          * will not get called on the List subnodes of an AND, so no check is
883          * needed for List.)
884          */
885         if (and_clause(node))
886         {
887                 List       *newargs = NIL;
888                 ListCell   *l;
889
890                 /* Still at qual top-level */
891                 locTopQual = *isTopQual;
892
893                 foreach(l, ((BoolExpr *) node)->args)
894                 {
895                         Node       *newarg;
896
897                         newarg = process_sublinks_mutator(lfirst(l),
898                                                                                           (void *) &locTopQual);
899                         if (and_clause(newarg))
900                                 newargs = list_concat(newargs, ((BoolExpr *) newarg)->args);
901                         else
902                                 newargs = lappend(newargs, newarg);
903                 }
904                 return (Node *) make_andclause(newargs);
905         }
906
907         /* otherwise not at qual top-level */
908         locTopQual = false;
909
910         if (or_clause(node))
911         {
912                 List       *newargs = NIL;
913                 ListCell   *l;
914
915                 foreach(l, ((BoolExpr *) node)->args)
916                 {
917                         Node       *newarg;
918
919                         newarg = process_sublinks_mutator(lfirst(l),
920                                                                                           (void *) &locTopQual);
921                         if (or_clause(newarg))
922                                 newargs = list_concat(newargs, ((BoolExpr *) newarg)->args);
923                         else
924                                 newargs = lappend(newargs, newarg);
925                 }
926                 return (Node *) make_orclause(newargs);
927         }
928
929         return expression_tree_mutator(node,
930                                                                    process_sublinks_mutator,
931                                                                    (void *) &locTopQual);
932 }
933
934 /*
935  * SS_finalize_plan - do final sublink processing for a completed Plan.
936  *
937  * This recursively computes the extParam and allParam sets for every Plan
938  * node in the given plan tree.  It also attaches any generated InitPlans
939  * to the top plan node.
940  */
941 void
942 SS_finalize_plan(Plan *plan, List *rtable)
943 {
944         Bitmapset  *outer_params,
945                            *valid_params,
946                            *initExtParam,
947                            *initSetParam;
948         Cost            initplan_cost;
949         int                     paramid;
950         ListCell   *l;
951
952         /*
953          * First, scan the param list to discover the sets of params that are
954          * available from outer query levels and my own query level. We do this
955          * once to save time in the per-plan recursion steps.
956          */
957         outer_params = valid_params = NULL;
958         paramid = 0;
959         foreach(l, PlannerParamList)
960         {
961                 PlannerParamItem *pitem = (PlannerParamItem *) lfirst(l);
962
963                 if (pitem->abslevel < PlannerQueryLevel)
964                 {
965                         /* valid outer-level parameter */
966                         outer_params = bms_add_member(outer_params, paramid);
967                         valid_params = bms_add_member(valid_params, paramid);
968                 }
969                 else if (pitem->abslevel == PlannerQueryLevel &&
970                                  IsA(pitem->item, Param))
971                 {
972                         /* valid local parameter (i.e., a setParam of my child) */
973                         valid_params = bms_add_member(valid_params, paramid);
974                 }
975
976                 paramid++;
977         }
978
979         /*
980          * Now recurse through plan tree.
981          */
982         (void) finalize_plan(plan, rtable, outer_params, valid_params);
983
984         bms_free(outer_params);
985         bms_free(valid_params);
986
987         /*
988          * Finally, attach any initPlans to the topmost plan node, and add their
989          * extParams to the topmost node's, too.  However, any setParams of the
990          * initPlans should not be present in the topmost node's extParams, only
991          * in its allParams.  (As of PG 8.1, it's possible that some initPlans
992          * have extParams that are setParams of other initPlans, so we have to
993          * take care of this situation explicitly.)
994          *
995          * We also add the total_cost of each initPlan to the startup cost of the
996          * top node.  This is a conservative overestimate, since in fact each
997          * initPlan might be executed later than plan startup, or even not at all.
998          */
999         plan->initPlan = PlannerInitPlan;
1000         PlannerInitPlan = NIL;          /* make sure they're not attached twice */
1001
1002         initExtParam = initSetParam = NULL;
1003         initplan_cost = 0;
1004         foreach(l, plan->initPlan)
1005         {
1006                 SubPlan    *initplan = (SubPlan *) lfirst(l);
1007                 ListCell   *l2;
1008
1009                 initExtParam = bms_add_members(initExtParam,
1010                                                                            initplan->plan->extParam);
1011                 foreach(l2, initplan->setParam)
1012                 {
1013                         initSetParam = bms_add_member(initSetParam, lfirst_int(l2));
1014                 }
1015                 initplan_cost += initplan->plan->total_cost;
1016         }
1017         /* allParam must include all these params */
1018         plan->allParam = bms_add_members(plan->allParam, initExtParam);
1019         plan->allParam = bms_add_members(plan->allParam, initSetParam);
1020         /* but extParam shouldn't include any setParams */
1021         initExtParam = bms_del_members(initExtParam, initSetParam);
1022         /* empty test ensures extParam is exactly NULL if it's empty */
1023         if (!bms_is_empty(initExtParam))
1024                 plan->extParam = bms_join(plan->extParam, initExtParam);
1025
1026         plan->startup_cost += initplan_cost;
1027         plan->total_cost += initplan_cost;
1028 }
1029
1030 /*
1031  * Recursive processing of all nodes in the plan tree
1032  *
1033  * The return value is the computed allParam set for the given Plan node.
1034  * This is just an internal notational convenience.
1035  */
1036 static Bitmapset *
1037 finalize_plan(Plan *plan, List *rtable,
1038                           Bitmapset *outer_params, Bitmapset *valid_params)
1039 {
1040         finalize_primnode_context context;
1041
1042         if (plan == NULL)
1043                 return NULL;
1044
1045         context.paramids = NULL;        /* initialize set to empty */
1046         context.outer_params = outer_params;
1047
1048         /*
1049          * When we call finalize_primnode, context.paramids sets are automatically
1050          * merged together.  But when recursing to self, we have to do it the hard
1051          * way.  We want the paramids set to include params in subplans as well as
1052          * at this level.
1053          */
1054
1055         /* Find params in targetlist and qual */
1056         finalize_primnode((Node *) plan->targetlist, &context);
1057         finalize_primnode((Node *) plan->qual, &context);
1058
1059         /* Check additional node-type-specific fields */
1060         switch (nodeTag(plan))
1061         {
1062                 case T_Result:
1063                         finalize_primnode(((Result *) plan)->resconstantqual,
1064                                                           &context);
1065                         break;
1066
1067                 case T_IndexScan:
1068                         finalize_primnode((Node *) ((IndexScan *) plan)->indexqual,
1069                                                           &context);
1070
1071                         /*
1072                          * we need not look at indexqualorig, since it will have the same
1073                          * param references as indexqual.
1074                          */
1075                         break;
1076
1077                 case T_BitmapIndexScan:
1078                         finalize_primnode((Node *) ((BitmapIndexScan *) plan)->indexqual,
1079                                                           &context);
1080
1081                         /*
1082                          * we need not look at indexqualorig, since it will have the same
1083                          * param references as indexqual.
1084                          */
1085                         break;
1086
1087                 case T_BitmapHeapScan:
1088                         finalize_primnode((Node *) ((BitmapHeapScan *) plan)->bitmapqualorig,
1089                                                           &context);
1090                         break;
1091
1092                 case T_TidScan:
1093                         finalize_primnode((Node *) ((TidScan *) plan)->tidquals,
1094                                                           &context);
1095                         break;
1096
1097                 case T_SubqueryScan:
1098
1099                         /*
1100                          * In a SubqueryScan, SS_finalize_plan has already been run on the
1101                          * subplan by the inner invocation of subquery_planner, so there's
1102                          * no need to do it again.      Instead, just pull out the subplan's
1103                          * extParams list, which represents the params it needs from my
1104                          * level and higher levels.
1105                          */
1106                         context.paramids = bms_add_members(context.paramids,
1107                                                                  ((SubqueryScan *) plan)->subplan->extParam);
1108                         break;
1109
1110                 case T_FunctionScan:
1111                         {
1112                                 RangeTblEntry *rte;
1113
1114                                 rte = rt_fetch(((FunctionScan *) plan)->scan.scanrelid,
1115                                                            rtable);
1116                                 Assert(rte->rtekind == RTE_FUNCTION);
1117                                 finalize_primnode(rte->funcexpr, &context);
1118                         }
1119                         break;
1120
1121                 case T_ValuesScan:
1122                         {
1123                                 RangeTblEntry *rte;
1124
1125                                 rte = rt_fetch(((ValuesScan *) plan)->scan.scanrelid,
1126                                                            rtable);
1127                                 Assert(rte->rtekind == RTE_VALUES);
1128                                 finalize_primnode((Node *) rte->values_lists, &context);
1129                         }
1130                         break;
1131
1132                 case T_Append:
1133                         {
1134                                 ListCell   *l;
1135
1136                                 foreach(l, ((Append *) plan)->appendplans)
1137                                 {
1138                                         context.paramids =
1139                                                 bms_add_members(context.paramids,
1140                                                                                 finalize_plan((Plan *) lfirst(l),
1141                                                                                                           rtable,
1142                                                                                                           outer_params,
1143                                                                                                           valid_params));
1144                                 }
1145                         }
1146                         break;
1147
1148                 case T_BitmapAnd:
1149                         {
1150                                 ListCell   *l;
1151
1152                                 foreach(l, ((BitmapAnd *) plan)->bitmapplans)
1153                                 {
1154                                         context.paramids =
1155                                                 bms_add_members(context.paramids,
1156                                                                                 finalize_plan((Plan *) lfirst(l),
1157                                                                                                           rtable,
1158                                                                                                           outer_params,
1159                                                                                                           valid_params));
1160                                 }
1161                         }
1162                         break;
1163
1164                 case T_BitmapOr:
1165                         {
1166                                 ListCell   *l;
1167
1168                                 foreach(l, ((BitmapOr *) plan)->bitmapplans)
1169                                 {
1170                                         context.paramids =
1171                                                 bms_add_members(context.paramids,
1172                                                                                 finalize_plan((Plan *) lfirst(l),
1173                                                                                                           rtable,
1174                                                                                                           outer_params,
1175                                                                                                           valid_params));
1176                                 }
1177                         }
1178                         break;
1179
1180                 case T_NestLoop:
1181                         finalize_primnode((Node *) ((Join *) plan)->joinqual,
1182                                                           &context);
1183                         break;
1184
1185                 case T_MergeJoin:
1186                         finalize_primnode((Node *) ((Join *) plan)->joinqual,
1187                                                           &context);
1188                         finalize_primnode((Node *) ((MergeJoin *) plan)->mergeclauses,
1189                                                           &context);
1190                         break;
1191
1192                 case T_HashJoin:
1193                         finalize_primnode((Node *) ((Join *) plan)->joinqual,
1194                                                           &context);
1195                         finalize_primnode((Node *) ((HashJoin *) plan)->hashclauses,
1196                                                           &context);
1197                         break;
1198
1199                 case T_Limit:
1200                         finalize_primnode(((Limit *) plan)->limitOffset,
1201                                                           &context);
1202                         finalize_primnode(((Limit *) plan)->limitCount,
1203                                                           &context);
1204                         break;
1205
1206                 case T_Hash:
1207                 case T_Agg:
1208                 case T_SeqScan:
1209                 case T_Material:
1210                 case T_Sort:
1211                 case T_Unique:
1212                 case T_SetOp:
1213                 case T_Group:
1214                         break;
1215
1216                 default:
1217                         elog(ERROR, "unrecognized node type: %d",
1218                                  (int) nodeTag(plan));
1219         }
1220
1221         /* Process left and right child plans, if any */
1222         context.paramids = bms_add_members(context.paramids,
1223                                                                            finalize_plan(plan->lefttree,
1224                                                                                                          rtable,
1225                                                                                                          outer_params,
1226                                                                                                          valid_params));
1227
1228         context.paramids = bms_add_members(context.paramids,
1229                                                                            finalize_plan(plan->righttree,
1230                                                                                                          rtable,
1231                                                                                                          outer_params,
1232                                                                                                          valid_params));
1233
1234         /* Now we have all the paramids */
1235
1236         if (!bms_is_subset(context.paramids, valid_params))
1237                 elog(ERROR, "plan should not reference subplan's variable");
1238
1239         plan->extParam = bms_intersect(context.paramids, outer_params);
1240         plan->allParam = context.paramids;
1241
1242         /*
1243          * For speed at execution time, make sure extParam/allParam are actually
1244          * NULL if they are empty sets.
1245          */
1246         if (bms_is_empty(plan->extParam))
1247         {
1248                 bms_free(plan->extParam);
1249                 plan->extParam = NULL;
1250         }
1251         if (bms_is_empty(plan->allParam))
1252         {
1253                 bms_free(plan->allParam);
1254                 plan->allParam = NULL;
1255         }
1256
1257         return plan->allParam;
1258 }
1259
1260 /*
1261  * finalize_primnode: add IDs of all PARAM_EXEC params appearing in the given
1262  * expression tree to the result set.
1263  */
1264 static bool
1265 finalize_primnode(Node *node, finalize_primnode_context *context)
1266 {
1267         if (node == NULL)
1268                 return false;
1269         if (IsA(node, Param))
1270         {
1271                 if (((Param *) node)->paramkind == PARAM_EXEC)
1272                 {
1273                         int                     paramid = ((Param *) node)->paramid;
1274
1275                         context->paramids = bms_add_member(context->paramids, paramid);
1276                 }
1277                 return false;                   /* no more to do here */
1278         }
1279         if (is_subplan(node))
1280         {
1281                 SubPlan    *subplan = (SubPlan *) node;
1282
1283                 /* Add outer-level params needed by the subplan to paramids */
1284                 context->paramids = bms_join(context->paramids,
1285                                                                          bms_intersect(subplan->plan->extParam,
1286                                                                                                    context->outer_params));
1287                 /* fall through to recurse into subplan args */
1288         }
1289         return expression_tree_walker(node, finalize_primnode,
1290                                                                   (void *) context);
1291 }
1292
1293 /*
1294  * SS_make_initplan_from_plan - given a plan tree, make it an InitPlan
1295  *
1296  * The plan is expected to return a scalar value of the indicated type.
1297  * We build an EXPR_SUBLINK SubPlan node and put it into the initplan
1298  * list for the current query level.  A Param that represents the initplan's
1299  * output is returned.
1300  *
1301  * We assume the plan hasn't been put through SS_finalize_plan.
1302  */
1303 Param *
1304 SS_make_initplan_from_plan(PlannerInfo *root, Plan *plan,
1305                                                    Oid resulttype, int32 resulttypmod)
1306 {
1307         List       *saved_initplan = PlannerInitPlan;
1308         SubPlan    *node;
1309         Param      *prm;
1310
1311         /*
1312          * Set up for a new level of subquery.  This is just to keep
1313          * SS_finalize_plan from becoming confused.
1314          */
1315         PlannerQueryLevel++;
1316         PlannerInitPlan = NIL;
1317
1318         /*
1319          * Build extParam/allParam sets for plan nodes.
1320          */
1321         SS_finalize_plan(plan, root->parse->rtable);
1322
1323         /* Return to outer subquery context */
1324         PlannerQueryLevel--;
1325         PlannerInitPlan = saved_initplan;
1326
1327         /*
1328          * Create a SubPlan node and add it to the outer list of InitPlans.
1329          */
1330         node = makeNode(SubPlan);
1331         node->subLinkType = EXPR_SUBLINK;
1332         node->plan = plan;
1333         node->plan_id = PlannerPlanId++;        /* Assign unique ID to this SubPlan */
1334
1335         node->rtable = root->parse->rtable;
1336
1337         PlannerInitPlan = lappend(PlannerInitPlan, node);
1338
1339         /*
1340          * The node can't have any inputs (since it's an initplan), so the
1341          * parParam and args lists remain empty.
1342          */
1343
1344         /*
1345          * Make a Param that will be the subplan's output.
1346          */
1347         prm = generate_new_param(resulttype, resulttypmod);
1348         node->setParam = list_make1_int(prm->paramid);
1349
1350         return prm;
1351 }