Header And Logo

PostgreSQL
| The world's most advanced open source database.

subselect.c

Go to the documentation of this file.
00001 /*-------------------------------------------------------------------------
00002  *
00003  * subselect.c
00004  *    Planning routines for subselects and parameters.
00005  *
00006  * Portions Copyright (c) 1996-2013, PostgreSQL Global Development Group
00007  * Portions Copyright (c) 1994, Regents of the University of California
00008  *
00009  * IDENTIFICATION
00010  *    src/backend/optimizer/plan/subselect.c
00011  *
00012  *-------------------------------------------------------------------------
00013  */
00014 #include "postgres.h"
00015 
00016 #include "access/htup_details.h"
00017 #include "catalog/pg_operator.h"
00018 #include "catalog/pg_type.h"
00019 #include "executor/executor.h"
00020 #include "miscadmin.h"
00021 #include "nodes/makefuncs.h"
00022 #include "nodes/nodeFuncs.h"
00023 #include "optimizer/clauses.h"
00024 #include "optimizer/cost.h"
00025 #include "optimizer/planmain.h"
00026 #include "optimizer/planner.h"
00027 #include "optimizer/prep.h"
00028 #include "optimizer/subselect.h"
00029 #include "optimizer/var.h"
00030 #include "parser/parse_relation.h"
00031 #include "rewrite/rewriteManip.h"
00032 #include "utils/builtins.h"
00033 #include "utils/lsyscache.h"
00034 #include "utils/syscache.h"
00035 
00036 
00037 typedef struct convert_testexpr_context
00038 {
00039     PlannerInfo *root;
00040     List       *subst_nodes;    /* Nodes to substitute for Params */
00041 } convert_testexpr_context;
00042 
00043 typedef struct process_sublinks_context
00044 {
00045     PlannerInfo *root;
00046     bool        isTopQual;
00047 } process_sublinks_context;
00048 
00049 typedef struct finalize_primnode_context
00050 {
00051     PlannerInfo *root;
00052     Bitmapset  *paramids;       /* Non-local PARAM_EXEC paramids found */
00053 } finalize_primnode_context;
00054 
00055 
00056 static Node *build_subplan(PlannerInfo *root, Plan *plan, PlannerInfo *subroot,
00057               List *plan_params,
00058               SubLinkType subLinkType, Node *testexpr,
00059               bool adjust_testexpr, bool unknownEqFalse);
00060 static List *generate_subquery_params(PlannerInfo *root, List *tlist,
00061                          List **paramIds);
00062 static List *generate_subquery_vars(PlannerInfo *root, List *tlist,
00063                        Index varno);
00064 static Node *convert_testexpr(PlannerInfo *root,
00065                  Node *testexpr,
00066                  List *subst_nodes);
00067 static Node *convert_testexpr_mutator(Node *node,
00068                          convert_testexpr_context *context);
00069 static bool subplan_is_hashable(Plan *plan);
00070 static bool testexpr_is_hashable(Node *testexpr);
00071 static bool hash_ok_operator(OpExpr *expr);
00072 static bool simplify_EXISTS_query(Query *query);
00073 static Query *convert_EXISTS_to_ANY(PlannerInfo *root, Query *subselect,
00074                       Node **testexpr, List **paramIds);
00075 static Node *replace_correlation_vars_mutator(Node *node, PlannerInfo *root);
00076 static Node *process_sublinks_mutator(Node *node,
00077                          process_sublinks_context *context);
00078 static Bitmapset *finalize_plan(PlannerInfo *root,
00079               Plan *plan,
00080               Bitmapset *valid_params,
00081               Bitmapset *scan_params);
00082 static bool finalize_primnode(Node *node, finalize_primnode_context *context);
00083 
00084 
00085 /*
00086  * Select a PARAM_EXEC number to identify the given Var as a parameter for
00087  * the current subquery, or for a nestloop's inner scan.
00088  * If the Var already has a param in the current context, return that one.
00089  */
00090 static int
00091 assign_param_for_var(PlannerInfo *root, Var *var)
00092 {
00093     ListCell   *ppl;
00094     PlannerParamItem *pitem;
00095     Index       levelsup;
00096 
00097     /* Find the query level the Var belongs to */
00098     for (levelsup = var->varlevelsup; levelsup > 0; levelsup--)
00099         root = root->parent_root;
00100 
00101     /* If there's already a matching PlannerParamItem there, just use it */
00102     foreach(ppl, root->plan_params)
00103     {
00104         pitem = (PlannerParamItem *) lfirst(ppl);
00105         if (IsA(pitem->item, Var))
00106         {
00107             Var        *pvar = (Var *) pitem->item;
00108 
00109             /*
00110              * This comparison must match _equalVar(), except for ignoring
00111              * varlevelsup.  Note that _equalVar() ignores the location.
00112              */
00113             if (pvar->varno == var->varno &&
00114                 pvar->varattno == var->varattno &&
00115                 pvar->vartype == var->vartype &&
00116                 pvar->vartypmod == var->vartypmod &&
00117                 pvar->varcollid == var->varcollid &&
00118                 pvar->varnoold == var->varnoold &&
00119                 pvar->varoattno == var->varoattno)
00120                 return pitem->paramId;
00121         }
00122     }
00123 
00124     /* Nope, so make a new one */
00125     var = (Var *) copyObject(var);
00126     var->varlevelsup = 0;
00127 
00128     pitem = makeNode(PlannerParamItem);
00129     pitem->item = (Node *) var;
00130     pitem->paramId = root->glob->nParamExec++;
00131 
00132     root->plan_params = lappend(root->plan_params, pitem);
00133 
00134     return pitem->paramId;
00135 }
00136 
00137 /*
00138  * Generate a Param node to replace the given Var,
00139  * which is expected to have varlevelsup > 0 (ie, it is not local).
00140  */
00141 static Param *
00142 replace_outer_var(PlannerInfo *root, Var *var)
00143 {
00144     Param      *retval;
00145     int         i;
00146 
00147     Assert(var->varlevelsup > 0 && var->varlevelsup < root->query_level);
00148 
00149     /* Find the Var in the appropriate plan_params, or add it if not present */
00150     i = assign_param_for_var(root, var);
00151 
00152     retval = makeNode(Param);
00153     retval->paramkind = PARAM_EXEC;
00154     retval->paramid = i;
00155     retval->paramtype = var->vartype;
00156     retval->paramtypmod = var->vartypmod;
00157     retval->paramcollid = var->varcollid;
00158     retval->location = var->location;
00159 
00160     return retval;
00161 }
00162 
00163 /*
00164  * Generate a Param node to replace the given Var, which will be supplied
00165  * from an upper NestLoop join node.
00166  *
00167  * This is effectively the same as replace_outer_var, except that we expect
00168  * the Var to be local to the current query level.
00169  */
00170 Param *
00171 assign_nestloop_param_var(PlannerInfo *root, Var *var)
00172 {
00173     Param      *retval;
00174     int         i;
00175 
00176     Assert(var->varlevelsup == 0);
00177 
00178     i = assign_param_for_var(root, var);
00179 
00180     retval = makeNode(Param);
00181     retval->paramkind = PARAM_EXEC;
00182     retval->paramid = i;
00183     retval->paramtype = var->vartype;
00184     retval->paramtypmod = var->vartypmod;
00185     retval->paramcollid = var->varcollid;
00186     retval->location = var->location;
00187 
00188     return retval;
00189 }
00190 
00191 /*
00192  * Select a PARAM_EXEC number to identify the given PlaceHolderVar as a
00193  * parameter for the current subquery, or for a nestloop's inner scan.
00194  * If the PHV already has a param in the current context, return that one.
00195  *
00196  * This is just like assign_param_for_var, except for PlaceHolderVars.
00197  */
00198 static int
00199 assign_param_for_placeholdervar(PlannerInfo *root, PlaceHolderVar *phv)
00200 {
00201     ListCell   *ppl;
00202     PlannerParamItem *pitem;
00203     Index       levelsup;
00204 
00205     /* Find the query level the PHV belongs to */
00206     for (levelsup = phv->phlevelsup; levelsup > 0; levelsup--)
00207         root = root->parent_root;
00208 
00209     /* If there's already a matching PlannerParamItem there, just use it */
00210     foreach(ppl, root->plan_params)
00211     {
00212         pitem = (PlannerParamItem *) lfirst(ppl);
00213         if (IsA(pitem->item, PlaceHolderVar))
00214         {
00215             PlaceHolderVar *pphv = (PlaceHolderVar *) pitem->item;
00216 
00217             /* We assume comparing the PHIDs is sufficient */
00218             if (pphv->phid == phv->phid)
00219                 return pitem->paramId;
00220         }
00221     }
00222 
00223     /* Nope, so make a new one */
00224     phv = (PlaceHolderVar *) copyObject(phv);
00225     if (phv->phlevelsup != 0)
00226     {
00227         IncrementVarSublevelsUp((Node *) phv, -((int) phv->phlevelsup), 0);
00228         Assert(phv->phlevelsup == 0);
00229     }
00230 
00231     pitem = makeNode(PlannerParamItem);
00232     pitem->item = (Node *) phv;
00233     pitem->paramId = root->glob->nParamExec++;
00234 
00235     root->plan_params = lappend(root->plan_params, pitem);
00236 
00237     return pitem->paramId;
00238 }
00239 
00240 /*
00241  * Generate a Param node to replace the given PlaceHolderVar,
00242  * which is expected to have phlevelsup > 0 (ie, it is not local).
00243  *
00244  * This is just like replace_outer_var, except for PlaceHolderVars.
00245  */
00246 static Param *
00247 replace_outer_placeholdervar(PlannerInfo *root, PlaceHolderVar *phv)
00248 {
00249     Param      *retval;
00250     int         i;
00251 
00252     Assert(phv->phlevelsup > 0 && phv->phlevelsup < root->query_level);
00253 
00254     /* Find the PHV in the appropriate plan_params, or add it if not present */
00255     i = assign_param_for_placeholdervar(root, phv);
00256 
00257     retval = makeNode(Param);
00258     retval->paramkind = PARAM_EXEC;
00259     retval->paramid = i;
00260     retval->paramtype = exprType((Node *) phv->phexpr);
00261     retval->paramtypmod = exprTypmod((Node *) phv->phexpr);
00262     retval->paramcollid = exprCollation((Node *) phv->phexpr);
00263     retval->location = -1;
00264 
00265     return retval;
00266 }
00267 
00268 /*
00269  * Generate a Param node to replace the given PlaceHolderVar, which will be
00270  * supplied from an upper NestLoop join node.
00271  *
00272  * This is just like assign_nestloop_param_var, except for PlaceHolderVars.
00273  */
00274 Param *
00275 assign_nestloop_param_placeholdervar(PlannerInfo *root, PlaceHolderVar *phv)
00276 {
00277     Param      *retval;
00278     int         i;
00279 
00280     Assert(phv->phlevelsup == 0);
00281 
00282     i = assign_param_for_placeholdervar(root, phv);
00283 
00284     retval = makeNode(Param);
00285     retval->paramkind = PARAM_EXEC;
00286     retval->paramid = i;
00287     retval->paramtype = exprType((Node *) phv->phexpr);
00288     retval->paramtypmod = exprTypmod((Node *) phv->phexpr);
00289     retval->paramcollid = exprCollation((Node *) phv->phexpr);
00290     retval->location = -1;
00291 
00292     return retval;
00293 }
00294 
00295 /*
00296  * Generate a Param node to replace the given Aggref
00297  * which is expected to have agglevelsup > 0 (ie, it is not local).
00298  */
00299 static Param *
00300 replace_outer_agg(PlannerInfo *root, Aggref *agg)
00301 {
00302     Param      *retval;
00303     PlannerParamItem *pitem;
00304     Index       levelsup;
00305 
00306     Assert(agg->agglevelsup > 0 && agg->agglevelsup < root->query_level);
00307 
00308     /* Find the query level the Aggref belongs to */
00309     for (levelsup = agg->agglevelsup; levelsup > 0; levelsup--)
00310         root = root->parent_root;
00311 
00312     /*
00313      * It does not seem worthwhile to try to match duplicate outer aggs. Just
00314      * make a new slot every time.
00315      */
00316     agg = (Aggref *) copyObject(agg);
00317     IncrementVarSublevelsUp((Node *) agg, -((int) agg->agglevelsup), 0);
00318     Assert(agg->agglevelsup == 0);
00319 
00320     pitem = makeNode(PlannerParamItem);
00321     pitem->item = (Node *) agg;
00322     pitem->paramId = root->glob->nParamExec++;
00323 
00324     root->plan_params = lappend(root->plan_params, pitem);
00325 
00326     retval = makeNode(Param);
00327     retval->paramkind = PARAM_EXEC;
00328     retval->paramid = pitem->paramId;
00329     retval->paramtype = agg->aggtype;
00330     retval->paramtypmod = -1;
00331     retval->paramcollid = agg->aggcollid;
00332     retval->location = agg->location;
00333 
00334     return retval;
00335 }
00336 
00337 /*
00338  * Generate a new Param node that will not conflict with any other.
00339  *
00340  * This is used to create Params representing subplan outputs.
00341  * We don't need to build a PlannerParamItem for such a Param, but we do
00342  * need to record the PARAM_EXEC slot number as being allocated.
00343  */
00344 static Param *
00345 generate_new_param(PlannerInfo *root, Oid paramtype, int32 paramtypmod,
00346                    Oid paramcollation)
00347 {
00348     Param      *retval;
00349 
00350     retval = makeNode(Param);
00351     retval->paramkind = PARAM_EXEC;
00352     retval->paramid = root->glob->nParamExec++;
00353     retval->paramtype = paramtype;
00354     retval->paramtypmod = paramtypmod;
00355     retval->paramcollid = paramcollation;
00356     retval->location = -1;
00357 
00358     return retval;
00359 }
00360 
00361 /*
00362  * Assign a (nonnegative) PARAM_EXEC ID for a special parameter (one that
00363  * is not actually used to carry a value at runtime).  Such parameters are
00364  * used for special runtime signaling purposes, such as connecting a
00365  * recursive union node to its worktable scan node or forcing plan
00366  * re-evaluation within the EvalPlanQual mechanism.  No actual Param node
00367  * exists with this ID, however.
00368  */
00369 int
00370 SS_assign_special_param(PlannerInfo *root)
00371 {
00372     return root->glob->nParamExec++;
00373 }
00374 
00375 /*
00376  * Get the datatype/typmod/collation of the first column of the plan's output.
00377  *
00378  * This information is stored for ARRAY_SUBLINK execution and for
00379  * exprType()/exprTypmod()/exprCollation(), which have no way to get at the
00380  * plan associated with a SubPlan node.  We really only need the info for
00381  * EXPR_SUBLINK and ARRAY_SUBLINK subplans, but for consistency we save it
00382  * always.
00383  */
00384 static void
00385 get_first_col_type(Plan *plan, Oid *coltype, int32 *coltypmod,
00386                    Oid *colcollation)
00387 {
00388     /* In cases such as EXISTS, tlist might be empty; arbitrarily use VOID */
00389     if (plan->targetlist)
00390     {
00391         TargetEntry *tent = (TargetEntry *) linitial(plan->targetlist);
00392 
00393         Assert(IsA(tent, TargetEntry));
00394         if (!tent->resjunk)
00395         {
00396             *coltype = exprType((Node *) tent->expr);
00397             *coltypmod = exprTypmod((Node *) tent->expr);
00398             *colcollation = exprCollation((Node *) tent->expr);
00399             return;
00400         }
00401     }
00402     *coltype = VOIDOID;
00403     *coltypmod = -1;
00404     *colcollation = InvalidOid;
00405 }
00406 
00407 /*
00408  * Convert a SubLink (as created by the parser) into a SubPlan.
00409  *
00410  * We are given the SubLink's contained query, type, and testexpr.  We are
00411  * also told if this expression appears at top level of a WHERE/HAVING qual.
00412  *
00413  * Note: we assume that the testexpr has been AND/OR flattened (actually,
00414  * it's been through eval_const_expressions), but not converted to
00415  * implicit-AND form; and any SubLinks in it should already have been
00416  * converted to SubPlans.  The subquery is as yet untouched, however.
00417  *
00418  * The result is whatever we need to substitute in place of the SubLink
00419  * node in the executable expression.  This will be either the SubPlan
00420  * node (if we have to do the subplan as a subplan), or a Param node
00421  * representing the result of an InitPlan, or a row comparison expression
00422  * tree containing InitPlan Param nodes.
00423  */
00424 static Node *
00425 make_subplan(PlannerInfo *root, Query *orig_subquery, SubLinkType subLinkType,
00426              Node *testexpr, bool isTopQual)
00427 {
00428     Query      *subquery;
00429     bool        simple_exists = false;
00430     double      tuple_fraction;
00431     Plan       *plan;
00432     PlannerInfo *subroot;
00433     List       *plan_params;
00434     Node       *result;
00435 
00436     /*
00437      * Copy the source Query node.  This is a quick and dirty kluge to resolve
00438      * the fact that the parser can generate trees with multiple links to the
00439      * same sub-Query node, but the planner wants to scribble on the Query.
00440      * Try to clean this up when we do querytree redesign...
00441      */
00442     subquery = (Query *) copyObject(orig_subquery);
00443 
00444     /*
00445      * If it's an EXISTS subplan, we might be able to simplify it.
00446      */
00447     if (subLinkType == EXISTS_SUBLINK)
00448         simple_exists = simplify_EXISTS_query(subquery);
00449 
00450     /*
00451      * For an EXISTS subplan, tell lower-level planner to expect that only the
00452      * first tuple will be retrieved.  For ALL and ANY subplans, we will be
00453      * able to stop evaluating if the test condition fails or matches, so very
00454      * often not all the tuples will be retrieved; for lack of a better idea,
00455      * specify 50% retrieval.  For EXPR and ROWCOMPARE subplans, use default
00456      * behavior (we're only expecting one row out, anyway).
00457      *
00458      * NOTE: if you change these numbers, also change cost_subplan() in
00459      * path/costsize.c.
00460      *
00461      * XXX If an ANY subplan is uncorrelated, build_subplan may decide to hash
00462      * its output.  In that case it would've been better to specify full
00463      * retrieval.  At present, however, we can only check hashability after
00464      * we've made the subplan :-(.  (Determining whether it'll fit in work_mem
00465      * is the really hard part.)  Therefore, we don't want to be too
00466      * optimistic about the percentage of tuples retrieved, for fear of
00467      * selecting a plan that's bad for the materialization case.
00468      */
00469     if (subLinkType == EXISTS_SUBLINK)
00470         tuple_fraction = 1.0;   /* just like a LIMIT 1 */
00471     else if (subLinkType == ALL_SUBLINK ||
00472              subLinkType == ANY_SUBLINK)
00473         tuple_fraction = 0.5;   /* 50% */
00474     else
00475         tuple_fraction = 0.0;   /* default behavior */
00476 
00477     /* plan_params should not be in use in current query level */
00478     Assert(root->plan_params == NIL);
00479 
00480     /*
00481      * Generate the plan for the subquery.
00482      */
00483     plan = subquery_planner(root->glob, subquery,
00484                             root,
00485                             false, tuple_fraction,
00486                             &subroot);
00487 
00488     /* Isolate the params needed by this specific subplan */
00489     plan_params = root->plan_params;
00490     root->plan_params = NIL;
00491 
00492     /* And convert to SubPlan or InitPlan format. */
00493     result = build_subplan(root, plan, subroot, plan_params,
00494                            subLinkType, testexpr, true, isTopQual);
00495 
00496     /*
00497      * If it's a correlated EXISTS with an unimportant targetlist, we might be
00498      * able to transform it to the equivalent of an IN and then implement it
00499      * by hashing.  We don't have enough information yet to tell which way is
00500      * likely to be better (it depends on the expected number of executions of
00501      * the EXISTS qual, and we are much too early in planning the outer query
00502      * to be able to guess that).  So we generate both plans, if possible, and
00503      * leave it to the executor to decide which to use.
00504      */
00505     if (simple_exists && IsA(result, SubPlan))
00506     {
00507         Node       *newtestexpr;
00508         List       *paramIds;
00509 
00510         /* Make a second copy of the original subquery */
00511         subquery = (Query *) copyObject(orig_subquery);
00512         /* and re-simplify */
00513         simple_exists = simplify_EXISTS_query(subquery);
00514         Assert(simple_exists);
00515         /* See if it can be converted to an ANY query */
00516         subquery = convert_EXISTS_to_ANY(root, subquery,
00517                                          &newtestexpr, &paramIds);
00518         if (subquery)
00519         {
00520             /* Generate the plan for the ANY subquery; we'll need all rows */
00521             plan = subquery_planner(root->glob, subquery,
00522                                     root,
00523                                     false, 0.0,
00524                                     &subroot);
00525 
00526             /* Isolate the params needed by this specific subplan */
00527             plan_params = root->plan_params;
00528             root->plan_params = NIL;
00529 
00530             /* Now we can check if it'll fit in work_mem */
00531             if (subplan_is_hashable(plan))
00532             {
00533                 SubPlan    *hashplan;
00534                 AlternativeSubPlan *asplan;
00535 
00536                 /* OK, convert to SubPlan format. */
00537                 hashplan = (SubPlan *) build_subplan(root, plan, subroot,
00538                                                      plan_params,
00539                                                      ANY_SUBLINK, newtestexpr,
00540                                                      false, true);
00541                 /* Check we got what we expected */
00542                 Assert(IsA(hashplan, SubPlan));
00543                 Assert(hashplan->parParam == NIL);
00544                 Assert(hashplan->useHashTable);
00545                 /* build_subplan won't have filled in paramIds */
00546                 hashplan->paramIds = paramIds;
00547 
00548                 /* Leave it to the executor to decide which plan to use */
00549                 asplan = makeNode(AlternativeSubPlan);
00550                 asplan->subplans = list_make2(result, hashplan);
00551                 result = (Node *) asplan;
00552             }
00553         }
00554     }
00555 
00556     return result;
00557 }
00558 
00559 /*
00560  * Build a SubPlan node given the raw inputs --- subroutine for make_subplan
00561  *
00562  * Returns either the SubPlan, or an expression using initplan output Params,
00563  * as explained in the comments for make_subplan.
00564  */
00565 static Node *
00566 build_subplan(PlannerInfo *root, Plan *plan, PlannerInfo *subroot,
00567               List *plan_params,
00568               SubLinkType subLinkType, Node *testexpr,
00569               bool adjust_testexpr, bool unknownEqFalse)
00570 {
00571     Node       *result;
00572     SubPlan    *splan;
00573     bool        isInitPlan;
00574     ListCell   *lc;
00575 
00576     /*
00577      * Initialize the SubPlan node.  Note plan_id, plan_name, and cost fields
00578      * are set further down.
00579      */
00580     splan = makeNode(SubPlan);
00581     splan->subLinkType = subLinkType;
00582     splan->testexpr = NULL;
00583     splan->paramIds = NIL;
00584     get_first_col_type(plan, &splan->firstColType, &splan->firstColTypmod,
00585                        &splan->firstColCollation);
00586     splan->useHashTable = false;
00587     splan->unknownEqFalse = unknownEqFalse;
00588     splan->setParam = NIL;
00589     splan->parParam = NIL;
00590     splan->args = NIL;
00591 
00592     /*
00593      * Make parParam and args lists of param IDs and expressions that current
00594      * query level will pass to this child plan.
00595      */
00596     foreach(lc, plan_params)
00597     {
00598         PlannerParamItem *pitem = (PlannerParamItem *) lfirst(lc);
00599         Node       *arg = pitem->item;
00600 
00601         /*
00602          * The Var, PlaceHolderVar, or Aggref has already been adjusted to
00603          * have the correct varlevelsup, phlevelsup, or agglevelsup.
00604          *
00605          * If it's a PlaceHolderVar or Aggref, its arguments might contain
00606          * SubLinks, which have not yet been processed (see the comments for
00607          * SS_replace_correlation_vars).  Do that now.
00608          */
00609         if (IsA(arg, PlaceHolderVar) ||
00610             IsA(arg, Aggref))
00611             arg = SS_process_sublinks(root, arg, false);
00612 
00613         splan->parParam = lappend_int(splan->parParam, pitem->paramId);
00614         splan->args = lappend(splan->args, arg);
00615     }
00616 
00617     /*
00618      * Un-correlated or undirect correlated plans of EXISTS, EXPR, ARRAY, or
00619      * ROWCOMPARE types can be used as initPlans.  For EXISTS, EXPR, or ARRAY,
00620      * we just produce a Param referring to the result of evaluating the
00621      * initPlan.  For ROWCOMPARE, we must modify the testexpr tree to contain
00622      * PARAM_EXEC Params instead of the PARAM_SUBLINK Params emitted by the
00623      * parser.
00624      */
00625     if (splan->parParam == NIL && subLinkType == EXISTS_SUBLINK)
00626     {
00627         Param      *prm;
00628 
00629         Assert(testexpr == NULL);
00630         prm = generate_new_param(root, BOOLOID, -1, InvalidOid);
00631         splan->setParam = list_make1_int(prm->paramid);
00632         isInitPlan = true;
00633         result = (Node *) prm;
00634     }
00635     else if (splan->parParam == NIL && subLinkType == EXPR_SUBLINK)
00636     {
00637         TargetEntry *te = linitial(plan->targetlist);
00638         Param      *prm;
00639 
00640         Assert(!te->resjunk);
00641         Assert(testexpr == NULL);
00642         prm = generate_new_param(root,
00643                                  exprType((Node *) te->expr),
00644                                  exprTypmod((Node *) te->expr),
00645                                  exprCollation((Node *) te->expr));
00646         splan->setParam = list_make1_int(prm->paramid);
00647         isInitPlan = true;
00648         result = (Node *) prm;
00649     }
00650     else if (splan->parParam == NIL && subLinkType == ARRAY_SUBLINK)
00651     {
00652         TargetEntry *te = linitial(plan->targetlist);
00653         Oid         arraytype;
00654         Param      *prm;
00655 
00656         Assert(!te->resjunk);
00657         Assert(testexpr == NULL);
00658         arraytype = get_array_type(exprType((Node *) te->expr));
00659         if (!OidIsValid(arraytype))
00660             elog(ERROR, "could not find array type for datatype %s",
00661                  format_type_be(exprType((Node *) te->expr)));
00662         prm = generate_new_param(root,
00663                                  arraytype,
00664                                  exprTypmod((Node *) te->expr),
00665                                  exprCollation((Node *) te->expr));
00666         splan->setParam = list_make1_int(prm->paramid);
00667         isInitPlan = true;
00668         result = (Node *) prm;
00669     }
00670     else if (splan->parParam == NIL && subLinkType == ROWCOMPARE_SUBLINK)
00671     {
00672         /* Adjust the Params */
00673         List       *params;
00674 
00675         Assert(testexpr != NULL);
00676         params = generate_subquery_params(root,
00677                                           plan->targetlist,
00678                                           &splan->paramIds);
00679         result = convert_testexpr(root,
00680                                   testexpr,
00681                                   params);
00682         splan->setParam = list_copy(splan->paramIds);
00683         isInitPlan = true;
00684 
00685         /*
00686          * The executable expression is returned to become part of the outer
00687          * plan's expression tree; it is not kept in the initplan node.
00688          */
00689     }
00690     else
00691     {
00692         /*
00693          * Adjust the Params in the testexpr, unless caller said it's not
00694          * needed.
00695          */
00696         if (testexpr && adjust_testexpr)
00697         {
00698             List       *params;
00699 
00700             params = generate_subquery_params(root,
00701                                               plan->targetlist,
00702                                               &splan->paramIds);
00703             splan->testexpr = convert_testexpr(root,
00704                                                testexpr,
00705                                                params);
00706         }
00707         else
00708             splan->testexpr = testexpr;
00709 
00710         /*
00711          * We can't convert subplans of ALL_SUBLINK or ANY_SUBLINK types to
00712          * initPlans, even when they are uncorrelated or undirect correlated,
00713          * because we need to scan the output of the subplan for each outer
00714          * tuple.  But if it's a not-direct-correlated IN (= ANY) test, we
00715          * might be able to use a hashtable to avoid comparing all the tuples.
00716          */
00717         if (subLinkType == ANY_SUBLINK &&
00718             splan->parParam == NIL &&
00719             subplan_is_hashable(plan) &&
00720             testexpr_is_hashable(splan->testexpr))
00721             splan->useHashTable = true;
00722 
00723         /*
00724          * Otherwise, we have the option to tack a Material node onto the top
00725          * of the subplan, to reduce the cost of reading it repeatedly.  This
00726          * is pointless for a direct-correlated subplan, since we'd have to
00727          * recompute its results each time anyway.  For uncorrelated/undirect
00728          * correlated subplans, we add Material unless the subplan's top plan
00729          * node would materialize its output anyway.  Also, if enable_material
00730          * is false, then the user does not want us to materialize anything
00731          * unnecessarily, so we don't.
00732          */
00733         else if (splan->parParam == NIL && enable_material &&
00734                  !ExecMaterializesOutput(nodeTag(plan)))
00735             plan = materialize_finished_plan(plan);
00736 
00737         result = (Node *) splan;
00738         isInitPlan = false;
00739     }
00740 
00741     /*
00742      * Add the subplan and its PlannerInfo to the global lists.
00743      */
00744     root->glob->subplans = lappend(root->glob->subplans, plan);
00745     root->glob->subroots = lappend(root->glob->subroots, subroot);
00746     splan->plan_id = list_length(root->glob->subplans);
00747 
00748     if (isInitPlan)
00749         root->init_plans = lappend(root->init_plans, splan);
00750 
00751     /*
00752      * A parameterless subplan (not initplan) should be prepared to handle
00753      * REWIND efficiently.  If it has direct parameters then there's no point
00754      * since it'll be reset on each scan anyway; and if it's an initplan then
00755      * there's no point since it won't get re-run without parameter changes
00756      * anyway.  The input of a hashed subplan doesn't need REWIND either.
00757      */
00758     if (splan->parParam == NIL && !isInitPlan && !splan->useHashTable)
00759         root->glob->rewindPlanIDs = bms_add_member(root->glob->rewindPlanIDs,
00760                                                    splan->plan_id);
00761 
00762     /* Label the subplan for EXPLAIN purposes */
00763     if (isInitPlan)
00764     {
00765         ListCell   *lc;
00766         int         offset;
00767 
00768         splan->plan_name = palloc(32 + 12 * list_length(splan->setParam));
00769         sprintf(splan->plan_name, "InitPlan %d (returns ", splan->plan_id);
00770         offset = strlen(splan->plan_name);
00771         foreach(lc, splan->setParam)
00772         {
00773             sprintf(splan->plan_name + offset, "$%d%s",
00774                     lfirst_int(lc),
00775                     lnext(lc) ? "," : "");
00776             offset += strlen(splan->plan_name + offset);
00777         }
00778         sprintf(splan->plan_name + offset, ")");
00779     }
00780     else
00781     {
00782         splan->plan_name = palloc(32);
00783         sprintf(splan->plan_name, "SubPlan %d", splan->plan_id);
00784     }
00785 
00786     /* Lastly, fill in the cost estimates for use later */
00787     cost_subplan(root, splan, plan);
00788 
00789     return result;
00790 }
00791 
00792 /*
00793  * generate_subquery_params: build a list of Params representing the output
00794  * columns of a sublink's sub-select, given the sub-select's targetlist.
00795  *
00796  * We also return an integer list of the paramids of the Params.
00797  */
00798 static List *
00799 generate_subquery_params(PlannerInfo *root, List *tlist, List **paramIds)
00800 {
00801     List       *result;
00802     List       *ids;
00803     ListCell   *lc;
00804 
00805     result = ids = NIL;
00806     foreach(lc, tlist)
00807     {
00808         TargetEntry *tent = (TargetEntry *) lfirst(lc);
00809         Param      *param;
00810 
00811         if (tent->resjunk)
00812             continue;
00813 
00814         param = generate_new_param(root,
00815                                    exprType((Node *) tent->expr),
00816                                    exprTypmod((Node *) tent->expr),
00817                                    exprCollation((Node *) tent->expr));
00818         result = lappend(result, param);
00819         ids = lappend_int(ids, param->paramid);
00820     }
00821 
00822     *paramIds = ids;
00823     return result;
00824 }
00825 
00826 /*
00827  * generate_subquery_vars: build a list of Vars representing the output
00828  * columns of a sublink's sub-select, given the sub-select's targetlist.
00829  * The Vars have the specified varno (RTE index).
00830  */
00831 static List *
00832 generate_subquery_vars(PlannerInfo *root, List *tlist, Index varno)
00833 {
00834     List       *result;
00835     ListCell   *lc;
00836 
00837     result = NIL;
00838     foreach(lc, tlist)
00839     {
00840         TargetEntry *tent = (TargetEntry *) lfirst(lc);
00841         Var        *var;
00842 
00843         if (tent->resjunk)
00844             continue;
00845 
00846         var = makeVarFromTargetEntry(varno, tent);
00847         result = lappend(result, var);
00848     }
00849 
00850     return result;
00851 }
00852 
00853 /*
00854  * convert_testexpr: convert the testexpr given by the parser into
00855  * actually executable form.  This entails replacing PARAM_SUBLINK Params
00856  * with Params or Vars representing the results of the sub-select.  The
00857  * nodes to be substituted are passed in as the List result from
00858  * generate_subquery_params or generate_subquery_vars.
00859  *
00860  * The given testexpr has already been recursively processed by
00861  * process_sublinks_mutator.  Hence it can no longer contain any
00862  * PARAM_SUBLINK Params for lower SubLink nodes; we can safely assume that
00863  * any we find are for our own level of SubLink.
00864  */
00865 static Node *
00866 convert_testexpr(PlannerInfo *root,
00867                  Node *testexpr,
00868                  List *subst_nodes)
00869 {
00870     convert_testexpr_context context;
00871 
00872     context.root = root;
00873     context.subst_nodes = subst_nodes;
00874     return convert_testexpr_mutator(testexpr, &context);
00875 }
00876 
00877 static Node *
00878 convert_testexpr_mutator(Node *node,
00879                          convert_testexpr_context *context)
00880 {
00881     if (node == NULL)
00882         return NULL;
00883     if (IsA(node, Param))
00884     {
00885         Param      *param = (Param *) node;
00886 
00887         if (param->paramkind == PARAM_SUBLINK)
00888         {
00889             if (param->paramid <= 0 ||
00890                 param->paramid > list_length(context->subst_nodes))
00891                 elog(ERROR, "unexpected PARAM_SUBLINK ID: %d", param->paramid);
00892 
00893             /*
00894              * We copy the list item to avoid having doubly-linked
00895              * substructure in the modified parse tree.  This is probably
00896              * unnecessary when it's a Param, but be safe.
00897              */
00898             return (Node *) copyObject(list_nth(context->subst_nodes,
00899                                                 param->paramid - 1));
00900         }
00901     }
00902     return expression_tree_mutator(node,
00903                                    convert_testexpr_mutator,
00904                                    (void *) context);
00905 }
00906 
00907 /*
00908  * subplan_is_hashable: can we implement an ANY subplan by hashing?
00909  */
00910 static bool
00911 subplan_is_hashable(Plan *plan)
00912 {
00913     double      subquery_size;
00914 
00915     /*
00916      * The estimated size of the subquery result must fit in work_mem. (Note:
00917      * we use sizeof(HeapTupleHeaderData) here even though the tuples will
00918      * actually be stored as MinimalTuples; this provides some fudge factor
00919      * for hashtable overhead.)
00920      */
00921     subquery_size = plan->plan_rows *
00922         (MAXALIGN(plan->plan_width) + MAXALIGN(sizeof(HeapTupleHeaderData)));
00923     if (subquery_size > work_mem * 1024L)
00924         return false;
00925 
00926     return true;
00927 }
00928 
00929 /*
00930  * testexpr_is_hashable: is an ANY SubLink's test expression hashable?
00931  */
00932 static bool
00933 testexpr_is_hashable(Node *testexpr)
00934 {
00935     /*
00936      * The testexpr must be a single OpExpr, or an AND-clause containing only
00937      * OpExprs.
00938      *
00939      * The combining operators must be hashable and strict. The need for
00940      * hashability is obvious, since we want to use hashing. Without
00941      * strictness, behavior in the presence of nulls is too unpredictable.  We
00942      * actually must assume even more than plain strictness: they can't yield
00943      * NULL for non-null inputs, either (see nodeSubplan.c).  However, hash
00944      * indexes and hash joins assume that too.
00945      */
00946     if (testexpr && IsA(testexpr, OpExpr))
00947     {
00948         if (hash_ok_operator((OpExpr *) testexpr))
00949             return true;
00950     }
00951     else if (and_clause(testexpr))
00952     {
00953         ListCell   *l;
00954 
00955         foreach(l, ((BoolExpr *) testexpr)->args)
00956         {
00957             Node       *andarg = (Node *) lfirst(l);
00958 
00959             if (!IsA(andarg, OpExpr))
00960                 return false;
00961             if (!hash_ok_operator((OpExpr *) andarg))
00962                 return false;
00963         }
00964         return true;
00965     }
00966 
00967     return false;
00968 }
00969 
00970 /*
00971  * Check expression is hashable + strict
00972  *
00973  * We could use op_hashjoinable() and op_strict(), but do it like this to
00974  * avoid a redundant cache lookup.
00975  */
00976 static bool
00977 hash_ok_operator(OpExpr *expr)
00978 {
00979     Oid         opid = expr->opno;
00980 
00981     /* quick out if not a binary operator */
00982     if (list_length(expr->args) != 2)
00983         return false;
00984     if (opid == ARRAY_EQ_OP)
00985     {
00986         /* array_eq is strict, but must check input type to ensure hashable */
00987         /* XXX record_eq will need same treatment when it becomes hashable */
00988         Node       *leftarg = linitial(expr->args);
00989 
00990         return op_hashjoinable(opid, exprType(leftarg));
00991     }
00992     else
00993     {
00994         /* else must look up the operator properties */
00995         HeapTuple   tup;
00996         Form_pg_operator optup;
00997 
00998         tup = SearchSysCache1(OPEROID, ObjectIdGetDatum(opid));
00999         if (!HeapTupleIsValid(tup))
01000             elog(ERROR, "cache lookup failed for operator %u", opid);
01001         optup = (Form_pg_operator) GETSTRUCT(tup);
01002         if (!optup->oprcanhash || !func_strict(optup->oprcode))
01003         {
01004             ReleaseSysCache(tup);
01005             return false;
01006         }
01007         ReleaseSysCache(tup);
01008         return true;
01009     }
01010 }
01011 
01012 
01013 /*
01014  * SS_process_ctes: process a query's WITH list
01015  *
01016  * We plan each interesting WITH item and convert it to an initplan.
01017  * A side effect is to fill in root->cte_plan_ids with a list that
01018  * parallels root->parse->cteList and provides the subplan ID for
01019  * each CTE's initplan.
01020  */
01021 void
01022 SS_process_ctes(PlannerInfo *root)
01023 {
01024     ListCell   *lc;
01025 
01026     Assert(root->cte_plan_ids == NIL);
01027 
01028     foreach(lc, root->parse->cteList)
01029     {
01030         CommonTableExpr *cte = (CommonTableExpr *) lfirst(lc);
01031         CmdType     cmdType = ((Query *) cte->ctequery)->commandType;
01032         Query      *subquery;
01033         Plan       *plan;
01034         PlannerInfo *subroot;
01035         SubPlan    *splan;
01036         int         paramid;
01037 
01038         /*
01039          * Ignore SELECT CTEs that are not actually referenced anywhere.
01040          */
01041         if (cte->cterefcount == 0 && cmdType == CMD_SELECT)
01042         {
01043             /* Make a dummy entry in cte_plan_ids */
01044             root->cte_plan_ids = lappend_int(root->cte_plan_ids, -1);
01045             continue;
01046         }
01047 
01048         /*
01049          * Copy the source Query node.  Probably not necessary, but let's keep
01050          * this similar to make_subplan.
01051          */
01052         subquery = (Query *) copyObject(cte->ctequery);
01053 
01054         /* plan_params should not be in use in current query level */
01055         Assert(root->plan_params == NIL);
01056 
01057         /*
01058          * Generate the plan for the CTE query.  Always plan for full
01059          * retrieval --- we don't have enough info to predict otherwise.
01060          */
01061         plan = subquery_planner(root->glob, subquery,
01062                                 root,
01063                                 cte->cterecursive, 0.0,
01064                                 &subroot);
01065 
01066         /*
01067          * Since the current query level doesn't yet contain any RTEs, it
01068          * should not be possible for the CTE to have requested parameters of
01069          * this level.
01070          */
01071         if (root->plan_params)
01072             elog(ERROR, "unexpected outer reference in CTE query");
01073 
01074         /*
01075          * Make a SubPlan node for it.  This is just enough unlike
01076          * build_subplan that we can't share code.
01077          *
01078          * Note plan_id, plan_name, and cost fields are set further down.
01079          */
01080         splan = makeNode(SubPlan);
01081         splan->subLinkType = CTE_SUBLINK;
01082         splan->testexpr = NULL;
01083         splan->paramIds = NIL;
01084         get_first_col_type(plan, &splan->firstColType, &splan->firstColTypmod,
01085                            &splan->firstColCollation);
01086         splan->useHashTable = false;
01087         splan->unknownEqFalse = false;
01088         splan->setParam = NIL;
01089         splan->parParam = NIL;
01090         splan->args = NIL;
01091 
01092         /*
01093          * The node can't have any inputs (since it's an initplan), so the
01094          * parParam and args lists remain empty.  (It could contain references
01095          * to earlier CTEs' output param IDs, but CTE outputs are not
01096          * propagated via the args list.)
01097          */
01098 
01099         /*
01100          * Assign a param ID to represent the CTE's output.  No ordinary
01101          * "evaluation" of this param slot ever happens, but we use the param
01102          * ID for setParam/chgParam signaling just as if the CTE plan were
01103          * returning a simple scalar output.  (Also, the executor abuses the
01104          * ParamExecData slot for this param ID for communication among
01105          * multiple CteScan nodes that might be scanning this CTE.)
01106          */
01107         paramid = SS_assign_special_param(root);
01108         splan->setParam = list_make1_int(paramid);
01109 
01110         /*
01111          * Add the subplan and its PlannerInfo to the global lists.
01112          */
01113         root->glob->subplans = lappend(root->glob->subplans, plan);
01114         root->glob->subroots = lappend(root->glob->subroots, subroot);
01115         splan->plan_id = list_length(root->glob->subplans);
01116 
01117         root->init_plans = lappend(root->init_plans, splan);
01118 
01119         root->cte_plan_ids = lappend_int(root->cte_plan_ids, splan->plan_id);
01120 
01121         /* Label the subplan for EXPLAIN purposes */
01122         splan->plan_name = palloc(4 + strlen(cte->ctename) + 1);
01123         sprintf(splan->plan_name, "CTE %s", cte->ctename);
01124 
01125         /* Lastly, fill in the cost estimates for use later */
01126         cost_subplan(root, splan, plan);
01127     }
01128 }
01129 
01130 /*
01131  * convert_ANY_sublink_to_join: try to convert an ANY SubLink to a join
01132  *
01133  * The caller has found an ANY SubLink at the top level of one of the query's
01134  * qual clauses, but has not checked the properties of the SubLink further.
01135  * Decide whether it is appropriate to process this SubLink in join style.
01136  * If so, form a JoinExpr and return it.  Return NULL if the SubLink cannot
01137  * be converted to a join.
01138  *
01139  * The only non-obvious input parameter is available_rels: this is the set
01140  * of query rels that can safely be referenced in the sublink expression.
01141  * (We must restrict this to avoid changing the semantics when a sublink
01142  * is present in an outer join's ON qual.)  The conversion must fail if
01143  * the converted qual would reference any but these parent-query relids.
01144  *
01145  * On success, the returned JoinExpr has larg = NULL and rarg = the jointree
01146  * item representing the pulled-up subquery.  The caller must set larg to
01147  * represent the relation(s) on the lefthand side of the new join, and insert
01148  * the JoinExpr into the upper query's jointree at an appropriate place
01149  * (typically, where the lefthand relation(s) had been).  Note that the
01150  * passed-in SubLink must also be removed from its original position in the
01151  * query quals, since the quals of the returned JoinExpr replace it.
01152  * (Notionally, we replace the SubLink with a constant TRUE, then elide the
01153  * redundant constant from the qual.)
01154  *
01155  * On success, the caller is also responsible for recursively applying
01156  * pull_up_sublinks processing to the rarg and quals of the returned JoinExpr.
01157  * (On failure, there is no need to do anything, since pull_up_sublinks will
01158  * be applied when we recursively plan the sub-select.)
01159  *
01160  * Side effects of a successful conversion include adding the SubLink's
01161  * subselect to the query's rangetable, so that it can be referenced in
01162  * the JoinExpr's rarg.
01163  */
01164 JoinExpr *
01165 convert_ANY_sublink_to_join(PlannerInfo *root, SubLink *sublink,
01166                             Relids available_rels)
01167 {
01168     JoinExpr   *result;
01169     Query      *parse = root->parse;
01170     Query      *subselect = (Query *) sublink->subselect;
01171     Relids      upper_varnos;
01172     int         rtindex;
01173     RangeTblEntry *rte;
01174     RangeTblRef *rtr;
01175     List       *subquery_vars;
01176     Node       *quals;
01177 
01178     Assert(sublink->subLinkType == ANY_SUBLINK);
01179 
01180     /*
01181      * The sub-select must not refer to any Vars of the parent query. (Vars of
01182      * higher levels should be okay, though.)
01183      */
01184     if (contain_vars_of_level((Node *) subselect, 1))
01185         return NULL;
01186 
01187     /*
01188      * The test expression must contain some Vars of the parent query, else
01189      * it's not gonna be a join.  (Note that it won't have Vars referring to
01190      * the subquery, rather Params.)
01191      */
01192     upper_varnos = pull_varnos(sublink->testexpr);
01193     if (bms_is_empty(upper_varnos))
01194         return NULL;
01195 
01196     /*
01197      * However, it can't refer to anything outside available_rels.
01198      */
01199     if (!bms_is_subset(upper_varnos, available_rels))
01200         return NULL;
01201 
01202     /*
01203      * The combining operators and left-hand expressions mustn't be volatile.
01204      */
01205     if (contain_volatile_functions(sublink->testexpr))
01206         return NULL;
01207 
01208     /*
01209      * Okay, pull up the sub-select into upper range table.
01210      *
01211      * We rely here on the assumption that the outer query has no references
01212      * to the inner (necessarily true, other than the Vars that we build
01213      * below). Therefore this is a lot easier than what pull_up_subqueries has
01214      * to go through.
01215      */
01216     rte = addRangeTableEntryForSubquery(NULL,
01217                                         subselect,
01218                                         makeAlias("ANY_subquery", NIL),
01219                                         false,
01220                                         false);
01221     parse->rtable = lappend(parse->rtable, rte);
01222     rtindex = list_length(parse->rtable);
01223 
01224     /*
01225      * Form a RangeTblRef for the pulled-up sub-select.
01226      */
01227     rtr = makeNode(RangeTblRef);
01228     rtr->rtindex = rtindex;
01229 
01230     /*
01231      * Build a list of Vars representing the subselect outputs.
01232      */
01233     subquery_vars = generate_subquery_vars(root,
01234                                            subselect->targetList,
01235                                            rtindex);
01236 
01237     /*
01238      * Build the new join's qual expression, replacing Params with these Vars.
01239      */
01240     quals = convert_testexpr(root, sublink->testexpr, subquery_vars);
01241 
01242     /*
01243      * And finally, build the JoinExpr node.
01244      */
01245     result = makeNode(JoinExpr);
01246     result->jointype = JOIN_SEMI;
01247     result->isNatural = false;
01248     result->larg = NULL;        /* caller must fill this in */
01249     result->rarg = (Node *) rtr;
01250     result->usingClause = NIL;
01251     result->quals = quals;
01252     result->alias = NULL;
01253     result->rtindex = 0;        /* we don't need an RTE for it */
01254 
01255     return result;
01256 }
01257 
01258 /*
01259  * convert_EXISTS_sublink_to_join: try to convert an EXISTS SubLink to a join
01260  *
01261  * The API of this function is identical to convert_ANY_sublink_to_join's,
01262  * except that we also support the case where the caller has found NOT EXISTS,
01263  * so we need an additional input parameter "under_not".
01264  */
01265 JoinExpr *
01266 convert_EXISTS_sublink_to_join(PlannerInfo *root, SubLink *sublink,
01267                                bool under_not, Relids available_rels)
01268 {
01269     JoinExpr   *result;
01270     Query      *parse = root->parse;
01271     Query      *subselect = (Query *) sublink->subselect;
01272     Node       *whereClause;
01273     int         rtoffset;
01274     int         varno;
01275     Relids      clause_varnos;
01276     Relids      upper_varnos;
01277 
01278     Assert(sublink->subLinkType == EXISTS_SUBLINK);
01279 
01280     /*
01281      * Can't flatten if it contains WITH.  (We could arrange to pull up the
01282      * WITH into the parent query's cteList, but that risks changing the
01283      * semantics, since a WITH ought to be executed once per associated query
01284      * call.)  Note that convert_ANY_sublink_to_join doesn't have to reject
01285      * this case, since it just produces a subquery RTE that doesn't have to
01286      * get flattened into the parent query.
01287      */
01288     if (subselect->cteList)
01289         return NULL;
01290 
01291     /*
01292      * Copy the subquery so we can modify it safely (see comments in
01293      * make_subplan).
01294      */
01295     subselect = (Query *) copyObject(subselect);
01296 
01297     /*
01298      * See if the subquery can be simplified based on the knowledge that it's
01299      * being used in EXISTS().  If we aren't able to get rid of its
01300      * targetlist, we have to fail, because the pullup operation leaves us
01301      * with noplace to evaluate the targetlist.
01302      */
01303     if (!simplify_EXISTS_query(subselect))
01304         return NULL;
01305 
01306     /*
01307      * The subquery must have a nonempty jointree, else we won't have a join.
01308      */
01309     if (subselect->jointree->fromlist == NIL)
01310         return NULL;
01311 
01312     /*
01313      * Separate out the WHERE clause.  (We could theoretically also remove
01314      * top-level plain JOIN/ON clauses, but it's probably not worth the
01315      * trouble.)
01316      */
01317     whereClause = subselect->jointree->quals;
01318     subselect->jointree->quals = NULL;
01319 
01320     /*
01321      * The rest of the sub-select must not refer to any Vars of the parent
01322      * query.  (Vars of higher levels should be okay, though.)
01323      */
01324     if (contain_vars_of_level((Node *) subselect, 1))
01325         return NULL;
01326 
01327     /*
01328      * On the other hand, the WHERE clause must contain some Vars of the
01329      * parent query, else it's not gonna be a join.
01330      */
01331     if (!contain_vars_of_level(whereClause, 1))
01332         return NULL;
01333 
01334     /*
01335      * We don't risk optimizing if the WHERE clause is volatile, either.
01336      */
01337     if (contain_volatile_functions(whereClause))
01338         return NULL;
01339 
01340     /*
01341      * Prepare to pull up the sub-select into top range table.
01342      *
01343      * We rely here on the assumption that the outer query has no references
01344      * to the inner (necessarily true). Therefore this is a lot easier than
01345      * what pull_up_subqueries has to go through.
01346      *
01347      * In fact, it's even easier than what convert_ANY_sublink_to_join has to
01348      * do.  The machinations of simplify_EXISTS_query ensured that there is
01349      * nothing interesting in the subquery except an rtable and jointree, and
01350      * even the jointree FromExpr no longer has quals.  So we can just append
01351      * the rtable to our own and use the FromExpr in our jointree. But first,
01352      * adjust all level-zero varnos in the subquery to account for the rtable
01353      * merger.
01354      */
01355     rtoffset = list_length(parse->rtable);
01356     OffsetVarNodes((Node *) subselect, rtoffset, 0);
01357     OffsetVarNodes(whereClause, rtoffset, 0);
01358 
01359     /*
01360      * Upper-level vars in subquery will now be one level closer to their
01361      * parent than before; in particular, anything that had been level 1
01362      * becomes level zero.
01363      */
01364     IncrementVarSublevelsUp((Node *) subselect, -1, 1);
01365     IncrementVarSublevelsUp(whereClause, -1, 1);
01366 
01367     /*
01368      * Now that the WHERE clause is adjusted to match the parent query
01369      * environment, we can easily identify all the level-zero rels it uses.
01370      * The ones <= rtoffset belong to the upper query; the ones > rtoffset do
01371      * not.
01372      */
01373     clause_varnos = pull_varnos(whereClause);
01374     upper_varnos = NULL;
01375     while ((varno = bms_first_member(clause_varnos)) >= 0)
01376     {
01377         if (varno <= rtoffset)
01378             upper_varnos = bms_add_member(upper_varnos, varno);
01379     }
01380     bms_free(clause_varnos);
01381     Assert(!bms_is_empty(upper_varnos));
01382 
01383     /*
01384      * Now that we've got the set of upper-level varnos, we can make the last
01385      * check: only available_rels can be referenced.
01386      */
01387     if (!bms_is_subset(upper_varnos, available_rels))
01388         return NULL;
01389 
01390     /* Now we can attach the modified subquery rtable to the parent */
01391     parse->rtable = list_concat(parse->rtable, subselect->rtable);
01392 
01393     /*
01394      * And finally, build the JoinExpr node.
01395      */
01396     result = makeNode(JoinExpr);
01397     result->jointype = under_not ? JOIN_ANTI : JOIN_SEMI;
01398     result->isNatural = false;
01399     result->larg = NULL;        /* caller must fill this in */
01400     /* flatten out the FromExpr node if it's useless */
01401     if (list_length(subselect->jointree->fromlist) == 1)
01402         result->rarg = (Node *) linitial(subselect->jointree->fromlist);
01403     else
01404         result->rarg = (Node *) subselect->jointree;
01405     result->usingClause = NIL;
01406     result->quals = whereClause;
01407     result->alias = NULL;
01408     result->rtindex = 0;        /* we don't need an RTE for it */
01409 
01410     return result;
01411 }
01412 
01413 /*
01414  * simplify_EXISTS_query: remove any useless stuff in an EXISTS's subquery
01415  *
01416  * The only thing that matters about an EXISTS query is whether it returns
01417  * zero or more than zero rows.  Therefore, we can remove certain SQL features
01418  * that won't affect that.  The only part that is really likely to matter in
01419  * typical usage is simplifying the targetlist: it's a common habit to write
01420  * "SELECT * FROM" even though there is no need to evaluate any columns.
01421  *
01422  * Note: by suppressing the targetlist we could cause an observable behavioral
01423  * change, namely that any errors that might occur in evaluating the tlist
01424  * won't occur, nor will other side-effects of volatile functions.  This seems
01425  * unlikely to bother anyone in practice.
01426  *
01427  * Returns TRUE if was able to discard the targetlist, else FALSE.
01428  */
01429 static bool
01430 simplify_EXISTS_query(Query *query)
01431 {
01432     /*
01433      * We don't try to simplify at all if the query uses set operations,
01434      * aggregates, modifying CTEs, HAVING, LIMIT/OFFSET, or FOR UPDATE/SHARE;
01435      * none of these seem likely in normal usage and their possible effects
01436      * are complex.
01437      */
01438     if (query->commandType != CMD_SELECT ||
01439         query->setOperations ||
01440         query->hasAggs ||
01441         query->hasWindowFuncs ||
01442         query->hasModifyingCTE ||
01443         query->havingQual ||
01444         query->limitOffset ||
01445         query->limitCount ||
01446         query->rowMarks)
01447         return false;
01448 
01449     /*
01450      * Mustn't throw away the targetlist if it contains set-returning
01451      * functions; those could affect whether zero rows are returned!
01452      */
01453     if (expression_returns_set((Node *) query->targetList))
01454         return false;
01455 
01456     /*
01457      * Otherwise, we can throw away the targetlist, as well as any GROUP,
01458      * WINDOW, DISTINCT, and ORDER BY clauses; none of those clauses will
01459      * change a nonzero-rows result to zero rows or vice versa.  (Furthermore,
01460      * since our parsetree representation of these clauses depends on the
01461      * targetlist, we'd better throw them away if we drop the targetlist.)
01462      */
01463     query->targetList = NIL;
01464     query->groupClause = NIL;
01465     query->windowClause = NIL;
01466     query->distinctClause = NIL;
01467     query->sortClause = NIL;
01468     query->hasDistinctOn = false;
01469 
01470     return true;
01471 }
01472 
01473 /*
01474  * convert_EXISTS_to_ANY: try to convert EXISTS to a hashable ANY sublink
01475  *
01476  * The subselect is expected to be a fresh copy that we can munge up,
01477  * and to have been successfully passed through simplify_EXISTS_query.
01478  *
01479  * On success, the modified subselect is returned, and we store a suitable
01480  * upper-level test expression at *testexpr, plus a list of the subselect's
01481  * output Params at *paramIds.  (The test expression is already Param-ified
01482  * and hence need not go through convert_testexpr, which is why we have to
01483  * deal with the Param IDs specially.)
01484  *
01485  * On failure, returns NULL.
01486  */
01487 static Query *
01488 convert_EXISTS_to_ANY(PlannerInfo *root, Query *subselect,
01489                       Node **testexpr, List **paramIds)
01490 {
01491     Node       *whereClause;
01492     List       *leftargs,
01493                *rightargs,
01494                *opids,
01495                *opcollations,
01496                *newWhere,
01497                *tlist,
01498                *testlist,
01499                *paramids;
01500     ListCell   *lc,
01501                *rc,
01502                *oc,
01503                *cc;
01504     AttrNumber  resno;
01505 
01506     /*
01507      * Query must not require a targetlist, since we have to insert a new one.
01508      * Caller should have dealt with the case already.
01509      */
01510     Assert(subselect->targetList == NIL);
01511 
01512     /*
01513      * Separate out the WHERE clause.  (We could theoretically also remove
01514      * top-level plain JOIN/ON clauses, but it's probably not worth the
01515      * trouble.)
01516      */
01517     whereClause = subselect->jointree->quals;
01518     subselect->jointree->quals = NULL;
01519 
01520     /*
01521      * The rest of the sub-select must not refer to any Vars of the parent
01522      * query.  (Vars of higher levels should be okay, though.)
01523      *
01524      * Note: we need not check for Aggrefs separately because we know the
01525      * sub-select is as yet unoptimized; any uplevel Aggref must therefore
01526      * contain an uplevel Var reference.  This is not the case below ...
01527      */
01528     if (contain_vars_of_level((Node *) subselect, 1))
01529         return NULL;
01530 
01531     /*
01532      * We don't risk optimizing if the WHERE clause is volatile, either.
01533      */
01534     if (contain_volatile_functions(whereClause))
01535         return NULL;
01536 
01537     /*
01538      * Clean up the WHERE clause by doing const-simplification etc on it.
01539      * Aside from simplifying the processing we're about to do, this is
01540      * important for being able to pull chunks of the WHERE clause up into the
01541      * parent query.  Since we are invoked partway through the parent's
01542      * preprocess_expression() work, earlier steps of preprocess_expression()
01543      * wouldn't get applied to the pulled-up stuff unless we do them here. For
01544      * the parts of the WHERE clause that get put back into the child query,
01545      * this work is partially duplicative, but it shouldn't hurt.
01546      *
01547      * Note: we do not run flatten_join_alias_vars.  This is OK because any
01548      * parent aliases were flattened already, and we're not going to pull any
01549      * child Vars (of any description) into the parent.
01550      *
01551      * Note: passing the parent's root to eval_const_expressions is
01552      * technically wrong, but we can get away with it since only the
01553      * boundParams (if any) are used, and those would be the same in a
01554      * subroot.
01555      */
01556     whereClause = eval_const_expressions(root, whereClause);
01557     whereClause = (Node *) canonicalize_qual((Expr *) whereClause);
01558     whereClause = (Node *) make_ands_implicit((Expr *) whereClause);
01559 
01560     /*
01561      * We now have a flattened implicit-AND list of clauses, which we try to
01562      * break apart into "outervar = innervar" hash clauses. Anything that
01563      * can't be broken apart just goes back into the newWhere list.  Note that
01564      * we aren't trying hard yet to ensure that we have only outer or only
01565      * inner on each side; we'll check that if we get to the end.
01566      */
01567     leftargs = rightargs = opids = opcollations = newWhere = NIL;
01568     foreach(lc, (List *) whereClause)
01569     {
01570         OpExpr     *expr = (OpExpr *) lfirst(lc);
01571 
01572         if (IsA(expr, OpExpr) &&
01573             hash_ok_operator(expr))
01574         {
01575             Node       *leftarg = (Node *) linitial(expr->args);
01576             Node       *rightarg = (Node *) lsecond(expr->args);
01577 
01578             if (contain_vars_of_level(leftarg, 1))
01579             {
01580                 leftargs = lappend(leftargs, leftarg);
01581                 rightargs = lappend(rightargs, rightarg);
01582                 opids = lappend_oid(opids, expr->opno);
01583                 opcollations = lappend_oid(opcollations, expr->inputcollid);
01584                 continue;
01585             }
01586             if (contain_vars_of_level(rightarg, 1))
01587             {
01588                 /*
01589                  * We must commute the clause to put the outer var on the
01590                  * left, because the hashing code in nodeSubplan.c expects
01591                  * that.  This probably shouldn't ever fail, since hashable
01592                  * operators ought to have commutators, but be paranoid.
01593                  */
01594                 expr->opno = get_commutator(expr->opno);
01595                 if (OidIsValid(expr->opno) && hash_ok_operator(expr))
01596                 {
01597                     leftargs = lappend(leftargs, rightarg);
01598                     rightargs = lappend(rightargs, leftarg);
01599                     opids = lappend_oid(opids, expr->opno);
01600                     opcollations = lappend_oid(opcollations, expr->inputcollid);
01601                     continue;
01602                 }
01603                 /* If no commutator, no chance to optimize the WHERE clause */
01604                 return NULL;
01605             }
01606         }
01607         /* Couldn't handle it as a hash clause */
01608         newWhere = lappend(newWhere, expr);
01609     }
01610 
01611     /*
01612      * If we didn't find anything we could convert, fail.
01613      */
01614     if (leftargs == NIL)
01615         return NULL;
01616 
01617     /*
01618      * There mustn't be any parent Vars or Aggs in the stuff that we intend to
01619      * put back into the child query.  Note: you might think we don't need to
01620      * check for Aggs separately, because an uplevel Agg must contain an
01621      * uplevel Var in its argument.  But it is possible that the uplevel Var
01622      * got optimized away by eval_const_expressions.  Consider
01623      *
01624      * SUM(CASE WHEN false THEN uplevelvar ELSE 0 END)
01625      */
01626     if (contain_vars_of_level((Node *) newWhere, 1) ||
01627         contain_vars_of_level((Node *) rightargs, 1))
01628         return NULL;
01629     if (root->parse->hasAggs &&
01630         (contain_aggs_of_level((Node *) newWhere, 1) ||
01631          contain_aggs_of_level((Node *) rightargs, 1)))
01632         return NULL;
01633 
01634     /*
01635      * And there can't be any child Vars in the stuff we intend to pull up.
01636      * (Note: we'd need to check for child Aggs too, except we know the child
01637      * has no aggs at all because of simplify_EXISTS_query's check. The same
01638      * goes for window functions.)
01639      */
01640     if (contain_vars_of_level((Node *) leftargs, 0))
01641         return NULL;
01642 
01643     /*
01644      * Also reject sublinks in the stuff we intend to pull up.  (It might be
01645      * possible to support this, but doesn't seem worth the complication.)
01646      */
01647     if (contain_subplans((Node *) leftargs))
01648         return NULL;
01649 
01650     /*
01651      * Okay, adjust the sublevelsup in the stuff we're pulling up.
01652      */
01653     IncrementVarSublevelsUp((Node *) leftargs, -1, 1);
01654 
01655     /*
01656      * Put back any child-level-only WHERE clauses.
01657      */
01658     if (newWhere)
01659         subselect->jointree->quals = (Node *) make_ands_explicit(newWhere);
01660 
01661     /*
01662      * Build a new targetlist for the child that emits the expressions we
01663      * need.  Concurrently, build a testexpr for the parent using Params to
01664      * reference the child outputs.  (Since we generate Params directly here,
01665      * there will be no need to convert the testexpr in build_subplan.)
01666      */
01667     tlist = testlist = paramids = NIL;
01668     resno = 1;
01669     /* there's no "forfour" so we have to chase one of the lists manually */
01670     cc = list_head(opcollations);
01671     forthree(lc, leftargs, rc, rightargs, oc, opids)
01672     {
01673         Node       *leftarg = (Node *) lfirst(lc);
01674         Node       *rightarg = (Node *) lfirst(rc);
01675         Oid         opid = lfirst_oid(oc);
01676         Oid         opcollation = lfirst_oid(cc);
01677         Param      *param;
01678 
01679         cc = lnext(cc);
01680         param = generate_new_param(root,
01681                                    exprType(rightarg),
01682                                    exprTypmod(rightarg),
01683                                    exprCollation(rightarg));
01684         tlist = lappend(tlist,
01685                         makeTargetEntry((Expr *) rightarg,
01686                                         resno++,
01687                                         NULL,
01688                                         false));
01689         testlist = lappend(testlist,
01690                            make_opclause(opid, BOOLOID, false,
01691                                          (Expr *) leftarg, (Expr *) param,
01692                                          InvalidOid, opcollation));
01693         paramids = lappend_int(paramids, param->paramid);
01694     }
01695 
01696     /* Put everything where it should go, and we're done */
01697     subselect->targetList = tlist;
01698     *testexpr = (Node *) make_ands_explicit(testlist);
01699     *paramIds = paramids;
01700 
01701     return subselect;
01702 }
01703 
01704 
01705 /*
01706  * Replace correlation vars (uplevel vars) with Params.
01707  *
01708  * Uplevel PlaceHolderVars and aggregates are replaced, too.
01709  *
01710  * Note: it is critical that this runs immediately after SS_process_sublinks.
01711  * Since we do not recurse into the arguments of uplevel PHVs and aggregates,
01712  * they will get copied to the appropriate subplan args list in the parent
01713  * query with uplevel vars not replaced by Params, but only adjusted in level
01714  * (see replace_outer_placeholdervar and replace_outer_agg).  That's exactly
01715  * what we want for the vars of the parent level --- but if a PHV's or
01716  * aggregate's argument contains any further-up variables, they have to be
01717  * replaced with Params in their turn. That will happen when the parent level
01718  * runs SS_replace_correlation_vars.  Therefore it must do so after expanding
01719  * its sublinks to subplans.  And we don't want any steps in between, else
01720  * those steps would never get applied to the argument expressions, either in
01721  * the parent or the child level.
01722  *
01723  * Another fairly tricky thing going on here is the handling of SubLinks in
01724  * the arguments of uplevel PHVs/aggregates.  Those are not touched inside the
01725  * intermediate query level, either.  Instead, SS_process_sublinks recurses on
01726  * them after copying the PHV or Aggref expression into the parent plan level
01727  * (this is actually taken care of in build_subplan).
01728  */
01729 Node *
01730 SS_replace_correlation_vars(PlannerInfo *root, Node *expr)
01731 {
01732     /* No setup needed for tree walk, so away we go */
01733     return replace_correlation_vars_mutator(expr, root);
01734 }
01735 
01736 static Node *
01737 replace_correlation_vars_mutator(Node *node, PlannerInfo *root)
01738 {
01739     if (node == NULL)
01740         return NULL;
01741     if (IsA(node, Var))
01742     {
01743         if (((Var *) node)->varlevelsup > 0)
01744             return (Node *) replace_outer_var(root, (Var *) node);
01745     }
01746     if (IsA(node, PlaceHolderVar))
01747     {
01748         if (((PlaceHolderVar *) node)->phlevelsup > 0)
01749             return (Node *) replace_outer_placeholdervar(root,
01750                                                     (PlaceHolderVar *) node);
01751     }
01752     if (IsA(node, Aggref))
01753     {
01754         if (((Aggref *) node)->agglevelsup > 0)
01755             return (Node *) replace_outer_agg(root, (Aggref *) node);
01756     }
01757     return expression_tree_mutator(node,
01758                                    replace_correlation_vars_mutator,
01759                                    (void *) root);
01760 }
01761 
01762 /*
01763  * Expand SubLinks to SubPlans in the given expression.
01764  *
01765  * The isQual argument tells whether or not this expression is a WHERE/HAVING
01766  * qualifier expression.  If it is, any sublinks appearing at top level need
01767  * not distinguish FALSE from UNKNOWN return values.
01768  */
01769 Node *
01770 SS_process_sublinks(PlannerInfo *root, Node *expr, bool isQual)
01771 {
01772     process_sublinks_context context;
01773 
01774     context.root = root;
01775     context.isTopQual = isQual;
01776     return process_sublinks_mutator(expr, &context);
01777 }
01778 
01779 static Node *
01780 process_sublinks_mutator(Node *node, process_sublinks_context *context)
01781 {
01782     process_sublinks_context locContext;
01783 
01784     locContext.root = context->root;
01785 
01786     if (node == NULL)
01787         return NULL;
01788     if (IsA(node, SubLink))
01789     {
01790         SubLink    *sublink = (SubLink *) node;
01791         Node       *testexpr;
01792 
01793         /*
01794          * First, recursively process the lefthand-side expressions, if any.
01795          * They're not top-level anymore.
01796          */
01797         locContext.isTopQual = false;
01798         testexpr = process_sublinks_mutator(sublink->testexpr, &locContext);
01799 
01800         /*
01801          * Now build the SubPlan node and make the expr to return.
01802          */
01803         return make_subplan(context->root,
01804                             (Query *) sublink->subselect,
01805                             sublink->subLinkType,
01806                             testexpr,
01807                             context->isTopQual);
01808     }
01809 
01810     /*
01811      * Don't recurse into the arguments of an outer PHV or aggregate here. Any
01812      * SubLinks in the arguments have to be dealt with at the outer query
01813      * level; they'll be handled when build_subplan collects the PHV or Aggref
01814      * into the arguments to be passed down to the current subplan.
01815      */
01816     if (IsA(node, PlaceHolderVar))
01817     {
01818         if (((PlaceHolderVar *) node)->phlevelsup > 0)
01819             return node;
01820     }
01821     else if (IsA(node, Aggref))
01822     {
01823         if (((Aggref *) node)->agglevelsup > 0)
01824             return node;
01825     }
01826 
01827     /*
01828      * We should never see a SubPlan expression in the input (since this is
01829      * the very routine that creates 'em to begin with).  We shouldn't find
01830      * ourselves invoked directly on a Query, either.
01831      */
01832     Assert(!IsA(node, SubPlan));
01833     Assert(!IsA(node, AlternativeSubPlan));
01834     Assert(!IsA(node, Query));
01835 
01836     /*
01837      * Because make_subplan() could return an AND or OR clause, we have to
01838      * take steps to preserve AND/OR flatness of a qual.  We assume the input
01839      * has been AND/OR flattened and so we need no recursion here.
01840      *
01841      * (Due to the coding here, we will not get called on the List subnodes of
01842      * an AND; and the input is *not* yet in implicit-AND format.  So no check
01843      * is needed for a bare List.)
01844      *
01845      * Anywhere within the top-level AND/OR clause structure, we can tell
01846      * make_subplan() that NULL and FALSE are interchangeable.  So isTopQual
01847      * propagates down in both cases.  (Note that this is unlike the meaning
01848      * of "top level qual" used in most other places in Postgres.)
01849      */
01850     if (and_clause(node))
01851     {
01852         List       *newargs = NIL;
01853         ListCell   *l;
01854 
01855         /* Still at qual top-level */
01856         locContext.isTopQual = context->isTopQual;
01857 
01858         foreach(l, ((BoolExpr *) node)->args)
01859         {
01860             Node       *newarg;
01861 
01862             newarg = process_sublinks_mutator(lfirst(l), &locContext);
01863             if (and_clause(newarg))
01864                 newargs = list_concat(newargs, ((BoolExpr *) newarg)->args);
01865             else
01866                 newargs = lappend(newargs, newarg);
01867         }
01868         return (Node *) make_andclause(newargs);
01869     }
01870 
01871     if (or_clause(node))
01872     {
01873         List       *newargs = NIL;
01874         ListCell   *l;
01875 
01876         /* Still at qual top-level */
01877         locContext.isTopQual = context->isTopQual;
01878 
01879         foreach(l, ((BoolExpr *) node)->args)
01880         {
01881             Node       *newarg;
01882 
01883             newarg = process_sublinks_mutator(lfirst(l), &locContext);
01884             if (or_clause(newarg))
01885                 newargs = list_concat(newargs, ((BoolExpr *) newarg)->args);
01886             else
01887                 newargs = lappend(newargs, newarg);
01888         }
01889         return (Node *) make_orclause(newargs);
01890     }
01891 
01892     /*
01893      * If we recurse down through anything other than an AND or OR node, we
01894      * are definitely not at top qual level anymore.
01895      */
01896     locContext.isTopQual = false;
01897 
01898     return expression_tree_mutator(node,
01899                                    process_sublinks_mutator,
01900                                    (void *) &locContext);
01901 }
01902 
01903 /*
01904  * SS_finalize_plan - do final sublink and parameter processing for a
01905  * completed Plan.
01906  *
01907  * This recursively computes the extParam and allParam sets for every Plan
01908  * node in the given plan tree.  It also optionally attaches any previously
01909  * generated InitPlans to the top plan node.  (Any InitPlans should already
01910  * have been put through SS_finalize_plan.)
01911  */
01912 void
01913 SS_finalize_plan(PlannerInfo *root, Plan *plan, bool attach_initplans)
01914 {
01915     Bitmapset  *valid_params,
01916                *initExtParam,
01917                *initSetParam;
01918     Cost        initplan_cost;
01919     PlannerInfo *proot;
01920     ListCell   *l;
01921 
01922     /*
01923      * Examine any initPlans to determine the set of external params they
01924      * reference, the set of output params they supply, and their total cost.
01925      * We'll use at least some of this info below.  (Note we are assuming that
01926      * finalize_plan doesn't touch the initPlans.)
01927      *
01928      * In the case where attach_initplans is false, we are assuming that the
01929      * existing initPlans are siblings that might supply params needed by the
01930      * current plan.
01931      */
01932     initExtParam = initSetParam = NULL;
01933     initplan_cost = 0;
01934     foreach(l, root->init_plans)
01935     {
01936         SubPlan    *initsubplan = (SubPlan *) lfirst(l);
01937         Plan       *initplan = planner_subplan_get_plan(root, initsubplan);
01938         ListCell   *l2;
01939 
01940         initExtParam = bms_add_members(initExtParam, initplan->extParam);
01941         foreach(l2, initsubplan->setParam)
01942         {
01943             initSetParam = bms_add_member(initSetParam, lfirst_int(l2));
01944         }
01945         initplan_cost += initsubplan->startup_cost + initsubplan->per_call_cost;
01946     }
01947 
01948     /*
01949      * Now determine the set of params that are validly referenceable in this
01950      * query level; to wit, those available from outer query levels plus the
01951      * output parameters of any local initPlans.  (We do not include output
01952      * parameters of regular subplans.  Those should only appear within the
01953      * testexpr of SubPlan nodes, and are taken care of locally within
01954      * finalize_primnode.  Likewise, special parameters that are generated by
01955      * nodes such as ModifyTable are handled within finalize_plan.)
01956      */
01957     valid_params = bms_copy(initSetParam);
01958     for (proot = root->parent_root; proot != NULL; proot = proot->parent_root)
01959     {
01960         /* Include ordinary Var/PHV/Aggref params */
01961         foreach(l, proot->plan_params)
01962         {
01963             PlannerParamItem *pitem = (PlannerParamItem *) lfirst(l);
01964 
01965             valid_params = bms_add_member(valid_params, pitem->paramId);
01966         }
01967         /* Include any outputs of outer-level initPlans */
01968         foreach(l, proot->init_plans)
01969         {
01970             SubPlan    *initsubplan = (SubPlan *) lfirst(l);
01971             ListCell   *l2;
01972 
01973             foreach(l2, initsubplan->setParam)
01974             {
01975                 valid_params = bms_add_member(valid_params, lfirst_int(l2));
01976             }
01977         }
01978         /* Include worktable ID, if a recursive query is being planned */
01979         if (proot->wt_param_id >= 0)
01980             valid_params = bms_add_member(valid_params, proot->wt_param_id);
01981     }
01982 
01983     /*
01984      * Now recurse through plan tree.
01985      */
01986     (void) finalize_plan(root, plan, valid_params, NULL);
01987 
01988     bms_free(valid_params);
01989 
01990     /*
01991      * Finally, attach any initPlans to the topmost plan node, and add their
01992      * extParams to the topmost node's, too.  However, any setParams of the
01993      * initPlans should not be present in the topmost node's extParams, only
01994      * in its allParams.  (As of PG 8.1, it's possible that some initPlans
01995      * have extParams that are setParams of other initPlans, so we have to
01996      * take care of this situation explicitly.)
01997      *
01998      * We also add the eval cost of each initPlan to the startup cost of the
01999      * top node.  This is a conservative overestimate, since in fact each
02000      * initPlan might be executed later than plan startup, or even not at all.
02001      */
02002     if (attach_initplans)
02003     {
02004         plan->initPlan = root->init_plans;
02005         root->init_plans = NIL; /* make sure they're not attached twice */
02006 
02007         /* allParam must include all these params */
02008         plan->allParam = bms_add_members(plan->allParam, initExtParam);
02009         plan->allParam = bms_add_members(plan->allParam, initSetParam);
02010         /* extParam must include any child extParam */
02011         plan->extParam = bms_add_members(plan->extParam, initExtParam);
02012         /* but extParam shouldn't include any setParams */
02013         plan->extParam = bms_del_members(plan->extParam, initSetParam);
02014         /* ensure extParam is exactly NULL if it's empty */
02015         if (bms_is_empty(plan->extParam))
02016             plan->extParam = NULL;
02017 
02018         plan->startup_cost += initplan_cost;
02019         plan->total_cost += initplan_cost;
02020     }
02021 }
02022 
02023 /*
02024  * Recursive processing of all nodes in the plan tree
02025  *
02026  * valid_params is the set of param IDs considered valid to reference in
02027  * this plan node or its children.
02028  * scan_params is a set of param IDs to force scan plan nodes to reference.
02029  * This is for EvalPlanQual support, and is always NULL at the top of the
02030  * recursion.
02031  *
02032  * The return value is the computed allParam set for the given Plan node.
02033  * This is just an internal notational convenience.
02034  */
02035 static Bitmapset *
02036 finalize_plan(PlannerInfo *root, Plan *plan, Bitmapset *valid_params,
02037               Bitmapset *scan_params)
02038 {
02039     finalize_primnode_context context;
02040     int         locally_added_param;
02041     Bitmapset  *nestloop_params;
02042     Bitmapset  *child_params;
02043 
02044     if (plan == NULL)
02045         return NULL;
02046 
02047     context.root = root;
02048     context.paramids = NULL;    /* initialize set to empty */
02049     locally_added_param = -1;   /* there isn't one */
02050     nestloop_params = NULL;     /* there aren't any */
02051 
02052     /*
02053      * When we call finalize_primnode, context.paramids sets are automatically
02054      * merged together.  But when recursing to self, we have to do it the hard
02055      * way.  We want the paramids set to include params in subplans as well as
02056      * at this level.
02057      */
02058 
02059     /* Find params in targetlist and qual */
02060     finalize_primnode((Node *) plan->targetlist, &context);
02061     finalize_primnode((Node *) plan->qual, &context);
02062 
02063     /* Check additional node-type-specific fields */
02064     switch (nodeTag(plan))
02065     {
02066         case T_Result:
02067             finalize_primnode(((Result *) plan)->resconstantqual,
02068                               &context);
02069             break;
02070 
02071         case T_SeqScan:
02072             context.paramids = bms_add_members(context.paramids, scan_params);
02073             break;
02074 
02075         case T_IndexScan:
02076             finalize_primnode((Node *) ((IndexScan *) plan)->indexqual,
02077                               &context);
02078             finalize_primnode((Node *) ((IndexScan *) plan)->indexorderby,
02079                               &context);
02080 
02081             /*
02082              * we need not look at indexqualorig, since it will have the same
02083              * param references as indexqual.  Likewise, we can ignore
02084              * indexorderbyorig.
02085              */
02086             context.paramids = bms_add_members(context.paramids, scan_params);
02087             break;
02088 
02089         case T_IndexOnlyScan:
02090             finalize_primnode((Node *) ((IndexOnlyScan *) plan)->indexqual,
02091                               &context);
02092             finalize_primnode((Node *) ((IndexOnlyScan *) plan)->indexorderby,
02093                               &context);
02094 
02095             /*
02096              * we need not look at indextlist, since it cannot contain Params.
02097              */
02098             context.paramids = bms_add_members(context.paramids, scan_params);
02099             break;
02100 
02101         case T_BitmapIndexScan:
02102             finalize_primnode((Node *) ((BitmapIndexScan *) plan)->indexqual,
02103                               &context);
02104 
02105             /*
02106              * we need not look at indexqualorig, since it will have the same
02107              * param references as indexqual.
02108              */
02109             break;
02110 
02111         case T_BitmapHeapScan:
02112             finalize_primnode((Node *) ((BitmapHeapScan *) plan)->bitmapqualorig,
02113                               &context);
02114             context.paramids = bms_add_members(context.paramids, scan_params);
02115             break;
02116 
02117         case T_TidScan:
02118             finalize_primnode((Node *) ((TidScan *) plan)->tidquals,
02119                               &context);
02120             context.paramids = bms_add_members(context.paramids, scan_params);
02121             break;
02122 
02123         case T_SubqueryScan:
02124 
02125             /*
02126              * In a SubqueryScan, SS_finalize_plan has already been run on the
02127              * subplan by the inner invocation of subquery_planner, so there's
02128              * no need to do it again.  Instead, just pull out the subplan's
02129              * extParams list, which represents the params it needs from my
02130              * level and higher levels.
02131              */
02132             context.paramids = bms_add_members(context.paramids,
02133                                  ((SubqueryScan *) plan)->subplan->extParam);
02134             /* We need scan_params too, though */
02135             context.paramids = bms_add_members(context.paramids, scan_params);
02136             break;
02137 
02138         case T_FunctionScan:
02139             finalize_primnode(((FunctionScan *) plan)->funcexpr,
02140                               &context);
02141             context.paramids = bms_add_members(context.paramids, scan_params);
02142             break;
02143 
02144         case T_ValuesScan:
02145             finalize_primnode((Node *) ((ValuesScan *) plan)->values_lists,
02146                               &context);
02147             context.paramids = bms_add_members(context.paramids, scan_params);
02148             break;
02149 
02150         case T_CteScan:
02151             {
02152                 /*
02153                  * You might think we should add the node's cteParam to
02154                  * paramids, but we shouldn't because that param is just a
02155                  * linkage mechanism for multiple CteScan nodes for the same
02156                  * CTE; it is never used for changed-param signaling.  What we
02157                  * have to do instead is to find the referenced CTE plan and
02158                  * incorporate its external paramids, so that the correct
02159                  * things will happen if the CTE references outer-level
02160                  * variables.  See test cases for bug #4902.
02161                  */
02162                 int         plan_id = ((CteScan *) plan)->ctePlanId;
02163                 Plan       *cteplan;
02164 
02165                 /* so, do this ... */
02166                 if (plan_id < 1 || plan_id > list_length(root->glob->subplans))
02167                     elog(ERROR, "could not find plan for CteScan referencing plan ID %d",
02168                          plan_id);
02169                 cteplan = (Plan *) list_nth(root->glob->subplans, plan_id - 1);
02170                 context.paramids =
02171                     bms_add_members(context.paramids, cteplan->extParam);
02172 
02173 #ifdef NOT_USED
02174                 /* ... but not this */
02175                 context.paramids =
02176                     bms_add_member(context.paramids,
02177                                    ((CteScan *) plan)->cteParam);
02178 #endif
02179 
02180                 context.paramids = bms_add_members(context.paramids,
02181                                                    scan_params);
02182             }
02183             break;
02184 
02185         case T_WorkTableScan:
02186             context.paramids =
02187                 bms_add_member(context.paramids,
02188                                ((WorkTableScan *) plan)->wtParam);
02189             context.paramids = bms_add_members(context.paramids, scan_params);
02190             break;
02191 
02192         case T_ForeignScan:
02193             finalize_primnode((Node *) ((ForeignScan *) plan)->fdw_exprs,
02194                               &context);
02195             context.paramids = bms_add_members(context.paramids, scan_params);
02196             break;
02197 
02198         case T_ModifyTable:
02199             {
02200                 ModifyTable *mtplan = (ModifyTable *) plan;
02201                 ListCell   *l;
02202 
02203                 /* Force descendant scan nodes to reference epqParam */
02204                 locally_added_param = mtplan->epqParam;
02205                 valid_params = bms_add_member(bms_copy(valid_params),
02206                                               locally_added_param);
02207                 scan_params = bms_add_member(bms_copy(scan_params),
02208                                              locally_added_param);
02209                 finalize_primnode((Node *) mtplan->returningLists,
02210                                   &context);
02211                 foreach(l, mtplan->plans)
02212                 {
02213                     context.paramids =
02214                         bms_add_members(context.paramids,
02215                                         finalize_plan(root,
02216                                                       (Plan *) lfirst(l),
02217                                                       valid_params,
02218                                                       scan_params));
02219                 }
02220             }
02221             break;
02222 
02223         case T_Append:
02224             {
02225                 ListCell   *l;
02226 
02227                 foreach(l, ((Append *) plan)->appendplans)
02228                 {
02229                     context.paramids =
02230                         bms_add_members(context.paramids,
02231                                         finalize_plan(root,
02232                                                       (Plan *) lfirst(l),
02233                                                       valid_params,
02234                                                       scan_params));
02235                 }
02236             }
02237             break;
02238 
02239         case T_MergeAppend:
02240             {
02241                 ListCell   *l;
02242 
02243                 foreach(l, ((MergeAppend *) plan)->mergeplans)
02244                 {
02245                     context.paramids =
02246                         bms_add_members(context.paramids,
02247                                         finalize_plan(root,
02248                                                       (Plan *) lfirst(l),
02249                                                       valid_params,
02250                                                       scan_params));
02251                 }
02252             }
02253             break;
02254 
02255         case T_BitmapAnd:
02256             {
02257                 ListCell   *l;
02258 
02259                 foreach(l, ((BitmapAnd *) plan)->bitmapplans)
02260                 {
02261                     context.paramids =
02262                         bms_add_members(context.paramids,
02263                                         finalize_plan(root,
02264                                                       (Plan *) lfirst(l),
02265                                                       valid_params,
02266                                                       scan_params));
02267                 }
02268             }
02269             break;
02270 
02271         case T_BitmapOr:
02272             {
02273                 ListCell   *l;
02274 
02275                 foreach(l, ((BitmapOr *) plan)->bitmapplans)
02276                 {
02277                     context.paramids =
02278                         bms_add_members(context.paramids,
02279                                         finalize_plan(root,
02280                                                       (Plan *) lfirst(l),
02281                                                       valid_params,
02282                                                       scan_params));
02283                 }
02284             }
02285             break;
02286 
02287         case T_NestLoop:
02288             {
02289                 ListCell   *l;
02290 
02291                 finalize_primnode((Node *) ((Join *) plan)->joinqual,
02292                                   &context);
02293                 /* collect set of params that will be passed to right child */
02294                 foreach(l, ((NestLoop *) plan)->nestParams)
02295                 {
02296                     NestLoopParam *nlp = (NestLoopParam *) lfirst(l);
02297 
02298                     nestloop_params = bms_add_member(nestloop_params,
02299                                                      nlp->paramno);
02300                 }
02301             }
02302             break;
02303 
02304         case T_MergeJoin:
02305             finalize_primnode((Node *) ((Join *) plan)->joinqual,
02306                               &context);
02307             finalize_primnode((Node *) ((MergeJoin *) plan)->mergeclauses,
02308                               &context);
02309             break;
02310 
02311         case T_HashJoin:
02312             finalize_primnode((Node *) ((Join *) plan)->joinqual,
02313                               &context);
02314             finalize_primnode((Node *) ((HashJoin *) plan)->hashclauses,
02315                               &context);
02316             break;
02317 
02318         case T_Limit:
02319             finalize_primnode(((Limit *) plan)->limitOffset,
02320                               &context);
02321             finalize_primnode(((Limit *) plan)->limitCount,
02322                               &context);
02323             break;
02324 
02325         case T_RecursiveUnion:
02326             /* child nodes are allowed to reference wtParam */
02327             locally_added_param = ((RecursiveUnion *) plan)->wtParam;
02328             valid_params = bms_add_member(bms_copy(valid_params),
02329                                           locally_added_param);
02330             /* wtParam does *not* get added to scan_params */
02331             break;
02332 
02333         case T_LockRows:
02334             /* Force descendant scan nodes to reference epqParam */
02335             locally_added_param = ((LockRows *) plan)->epqParam;
02336             valid_params = bms_add_member(bms_copy(valid_params),
02337                                           locally_added_param);
02338             scan_params = bms_add_member(bms_copy(scan_params),
02339                                          locally_added_param);
02340             break;
02341 
02342         case T_WindowAgg:
02343             finalize_primnode(((WindowAgg *) plan)->startOffset,
02344                               &context);
02345             finalize_primnode(((WindowAgg *) plan)->endOffset,
02346                               &context);
02347             break;
02348 
02349         case T_Hash:
02350         case T_Agg:
02351         case T_Material:
02352         case T_Sort:
02353         case T_Unique:
02354         case T_SetOp:
02355         case T_Group:
02356             break;
02357 
02358         default:
02359             elog(ERROR, "unrecognized node type: %d",
02360                  (int) nodeTag(plan));
02361     }
02362 
02363     /* Process left and right child plans, if any */
02364     child_params = finalize_plan(root,
02365                                  plan->lefttree,
02366                                  valid_params,
02367                                  scan_params);
02368     context.paramids = bms_add_members(context.paramids, child_params);
02369 
02370     if (nestloop_params)
02371     {
02372         /* right child can reference nestloop_params as well as valid_params */
02373         child_params = finalize_plan(root,
02374                                      plan->righttree,
02375                                      bms_union(nestloop_params, valid_params),
02376                                      scan_params);
02377         /* ... and they don't count as parameters used at my level */
02378         child_params = bms_difference(child_params, nestloop_params);
02379         bms_free(nestloop_params);
02380     }
02381     else
02382     {
02383         /* easy case */
02384         child_params = finalize_plan(root,
02385                                      plan->righttree,
02386                                      valid_params,
02387                                      scan_params);
02388     }
02389     context.paramids = bms_add_members(context.paramids, child_params);
02390 
02391     /*
02392      * Any locally generated parameter doesn't count towards its generating
02393      * plan node's external dependencies.  (Note: if we changed valid_params
02394      * and/or scan_params, we leak those bitmapsets; not worth the notational
02395      * trouble to clean them up.)
02396      */
02397     if (locally_added_param >= 0)
02398     {
02399         context.paramids = bms_del_member(context.paramids,
02400                                           locally_added_param);
02401     }
02402 
02403     /* Now we have all the paramids */
02404 
02405     if (!bms_is_subset(context.paramids, valid_params))
02406         elog(ERROR, "plan should not reference subplan's variable");
02407 
02408     /*
02409      * Note: by definition, extParam and allParam should have the same value
02410      * in any plan node that doesn't have child initPlans.  We set them equal
02411      * here, and later SS_finalize_plan will update them properly in node(s)
02412      * that it attaches initPlans to.
02413      *
02414      * For speed at execution time, make sure extParam/allParam are actually
02415      * NULL if they are empty sets.
02416      */
02417     if (bms_is_empty(context.paramids))
02418     {
02419         plan->extParam = NULL;
02420         plan->allParam = NULL;
02421     }
02422     else
02423     {
02424         plan->extParam = context.paramids;
02425         plan->allParam = bms_copy(context.paramids);
02426     }
02427 
02428     return plan->allParam;
02429 }
02430 
02431 /*
02432  * finalize_primnode: add IDs of all PARAM_EXEC params appearing in the given
02433  * expression tree to the result set.
02434  */
02435 static bool
02436 finalize_primnode(Node *node, finalize_primnode_context *context)
02437 {
02438     if (node == NULL)
02439         return false;
02440     if (IsA(node, Param))
02441     {
02442         if (((Param *) node)->paramkind == PARAM_EXEC)
02443         {
02444             int         paramid = ((Param *) node)->paramid;
02445 
02446             context->paramids = bms_add_member(context->paramids, paramid);
02447         }
02448         return false;           /* no more to do here */
02449     }
02450     if (IsA(node, SubPlan))
02451     {
02452         SubPlan    *subplan = (SubPlan *) node;
02453         Plan       *plan = planner_subplan_get_plan(context->root, subplan);
02454         ListCell   *lc;
02455         Bitmapset  *subparamids;
02456 
02457         /* Recurse into the testexpr, but not into the Plan */
02458         finalize_primnode(subplan->testexpr, context);
02459 
02460         /*
02461          * Remove any param IDs of output parameters of the subplan that were
02462          * referenced in the testexpr.  These are not interesting for
02463          * parameter change signaling since we always re-evaluate the subplan.
02464          * Note that this wouldn't work too well if there might be uses of the
02465          * same param IDs elsewhere in the plan, but that can't happen because
02466          * generate_new_param never tries to merge params.
02467          */
02468         foreach(lc, subplan->paramIds)
02469         {
02470             context->paramids = bms_del_member(context->paramids,
02471                                                lfirst_int(lc));
02472         }
02473 
02474         /* Also examine args list */
02475         finalize_primnode((Node *) subplan->args, context);
02476 
02477         /*
02478          * Add params needed by the subplan to paramids, but excluding those
02479          * we will pass down to it.
02480          */
02481         subparamids = bms_copy(plan->extParam);
02482         foreach(lc, subplan->parParam)
02483         {
02484             subparamids = bms_del_member(subparamids, lfirst_int(lc));
02485         }
02486         context->paramids = bms_join(context->paramids, subparamids);
02487 
02488         return false;           /* no more to do here */
02489     }
02490     return expression_tree_walker(node, finalize_primnode,
02491                                   (void *) context);
02492 }
02493 
02494 /*
02495  * SS_make_initplan_from_plan - given a plan tree, make it an InitPlan
02496  *
02497  * The plan is expected to return a scalar value of the given type/collation.
02498  * We build an EXPR_SUBLINK SubPlan node and put it into the initplan
02499  * list for the current query level.  A Param that represents the initplan's
02500  * output is returned.
02501  *
02502  * We assume the plan hasn't been put through SS_finalize_plan.
02503  */
02504 Param *
02505 SS_make_initplan_from_plan(PlannerInfo *root, Plan *plan,
02506                            Oid resulttype, int32 resulttypmod,
02507                            Oid resultcollation)
02508 {
02509     SubPlan    *node;
02510     Param      *prm;
02511 
02512     /*
02513      * We must run SS_finalize_plan(), since that's normally done before a
02514      * subplan gets put into the initplan list.  Tell it not to attach any
02515      * pre-existing initplans to this one, since they are siblings not
02516      * children of this initplan.  (This is something else that could perhaps
02517      * be cleaner if we did extParam/allParam processing in setrefs.c instead
02518      * of here?  See notes for materialize_finished_plan.)
02519      */
02520 
02521     /*
02522      * Build extParam/allParam sets for plan nodes.
02523      */
02524     SS_finalize_plan(root, plan, false);
02525 
02526     /*
02527      * Add the subplan and its PlannerInfo to the global lists.
02528      */
02529     root->glob->subplans = lappend(root->glob->subplans, plan);
02530     root->glob->subroots = lappend(root->glob->subroots, root);
02531 
02532     /*
02533      * Create a SubPlan node and add it to the outer list of InitPlans. Note
02534      * it has to appear after any other InitPlans it might depend on (see
02535      * comments in ExecReScan).
02536      */
02537     node = makeNode(SubPlan);
02538     node->subLinkType = EXPR_SUBLINK;
02539     get_first_col_type(plan, &node->firstColType, &node->firstColTypmod,
02540                        &node->firstColCollation);
02541     node->plan_id = list_length(root->glob->subplans);
02542 
02543     root->init_plans = lappend(root->init_plans, node);
02544 
02545     /*
02546      * The node can't have any inputs (since it's an initplan), so the
02547      * parParam and args lists remain empty.
02548      */
02549 
02550     cost_subplan(root, node, plan);
02551 
02552     /*
02553      * Make a Param that will be the subplan's output.
02554      */
02555     prm = generate_new_param(root, resulttype, resulttypmod, resultcollation);
02556     node->setParam = list_make1_int(prm->paramid);
02557 
02558     /* Label the subplan for EXPLAIN purposes */
02559     node->plan_name = palloc(64);
02560     sprintf(node->plan_name, "InitPlan %d (returns $%d)",
02561             node->plan_id, prm->paramid);
02562 
02563     return prm;
02564 }