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