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