Header And Logo

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

createplan.c

Go to the documentation of this file.
00001 /*-------------------------------------------------------------------------
00002  *
00003  * createplan.c
00004  *    Routines to create the desired plan for processing a query.
00005  *    Planning is complete, we just need to convert the selected
00006  *    Path into a Plan.
00007  *
00008  * Portions Copyright (c) 1996-2013, PostgreSQL Global Development Group
00009  * Portions Copyright (c) 1994, Regents of the University of California
00010  *
00011  *
00012  * IDENTIFICATION
00013  *    src/backend/optimizer/plan/createplan.c
00014  *
00015  *-------------------------------------------------------------------------
00016  */
00017 #include "postgres.h"
00018 
00019 #include <limits.h>
00020 #include <math.h>
00021 
00022 #include "access/skey.h"
00023 #include "catalog/pg_class.h"
00024 #include "foreign/fdwapi.h"
00025 #include "miscadmin.h"
00026 #include "nodes/makefuncs.h"
00027 #include "nodes/nodeFuncs.h"
00028 #include "optimizer/clauses.h"
00029 #include "optimizer/cost.h"
00030 #include "optimizer/paths.h"
00031 #include "optimizer/placeholder.h"
00032 #include "optimizer/plancat.h"
00033 #include "optimizer/planmain.h"
00034 #include "optimizer/planner.h"
00035 #include "optimizer/predtest.h"
00036 #include "optimizer/restrictinfo.h"
00037 #include "optimizer/subselect.h"
00038 #include "optimizer/tlist.h"
00039 #include "optimizer/var.h"
00040 #include "parser/parse_clause.h"
00041 #include "parser/parsetree.h"
00042 #include "utils/lsyscache.h"
00043 
00044 
00045 static Plan *create_plan_recurse(PlannerInfo *root, Path *best_path);
00046 static Plan *create_scan_plan(PlannerInfo *root, Path *best_path);
00047 static List *build_relation_tlist(RelOptInfo *rel);
00048 static bool use_physical_tlist(PlannerInfo *root, RelOptInfo *rel);
00049 static void disuse_physical_tlist(Plan *plan, Path *path);
00050 static Plan *create_gating_plan(PlannerInfo *root, Plan *plan, List *quals);
00051 static Plan *create_join_plan(PlannerInfo *root, JoinPath *best_path);
00052 static Plan *create_append_plan(PlannerInfo *root, AppendPath *best_path);
00053 static Plan *create_merge_append_plan(PlannerInfo *root, MergeAppendPath *best_path);
00054 static Result *create_result_plan(PlannerInfo *root, ResultPath *best_path);
00055 static Material *create_material_plan(PlannerInfo *root, MaterialPath *best_path);
00056 static Plan *create_unique_plan(PlannerInfo *root, UniquePath *best_path);
00057 static SeqScan *create_seqscan_plan(PlannerInfo *root, Path *best_path,
00058                     List *tlist, List *scan_clauses);
00059 static Scan *create_indexscan_plan(PlannerInfo *root, IndexPath *best_path,
00060                       List *tlist, List *scan_clauses, bool indexonly);
00061 static BitmapHeapScan *create_bitmap_scan_plan(PlannerInfo *root,
00062                         BitmapHeapPath *best_path,
00063                         List *tlist, List *scan_clauses);
00064 static Plan *create_bitmap_subplan(PlannerInfo *root, Path *bitmapqual,
00065                       List **qual, List **indexqual, List **indexECs);
00066 static TidScan *create_tidscan_plan(PlannerInfo *root, TidPath *best_path,
00067                     List *tlist, List *scan_clauses);
00068 static SubqueryScan *create_subqueryscan_plan(PlannerInfo *root, Path *best_path,
00069                          List *tlist, List *scan_clauses);
00070 static FunctionScan *create_functionscan_plan(PlannerInfo *root, Path *best_path,
00071                          List *tlist, List *scan_clauses);
00072 static ValuesScan *create_valuesscan_plan(PlannerInfo *root, Path *best_path,
00073                        List *tlist, List *scan_clauses);
00074 static CteScan *create_ctescan_plan(PlannerInfo *root, Path *best_path,
00075                     List *tlist, List *scan_clauses);
00076 static WorkTableScan *create_worktablescan_plan(PlannerInfo *root, Path *best_path,
00077                           List *tlist, List *scan_clauses);
00078 static ForeignScan *create_foreignscan_plan(PlannerInfo *root, ForeignPath *best_path,
00079                         List *tlist, List *scan_clauses);
00080 static NestLoop *create_nestloop_plan(PlannerInfo *root, NestPath *best_path,
00081                      Plan *outer_plan, Plan *inner_plan);
00082 static MergeJoin *create_mergejoin_plan(PlannerInfo *root, MergePath *best_path,
00083                       Plan *outer_plan, Plan *inner_plan);
00084 static HashJoin *create_hashjoin_plan(PlannerInfo *root, HashPath *best_path,
00085                      Plan *outer_plan, Plan *inner_plan);
00086 static Node *replace_nestloop_params(PlannerInfo *root, Node *expr);
00087 static Node *replace_nestloop_params_mutator(Node *node, PlannerInfo *root);
00088 static void process_subquery_nestloop_params(PlannerInfo *root,
00089                                  List *subplan_params);
00090 static List *fix_indexqual_references(PlannerInfo *root, IndexPath *index_path);
00091 static List *fix_indexorderby_references(PlannerInfo *root, IndexPath *index_path);
00092 static Node *fix_indexqual_operand(Node *node, IndexOptInfo *index, int indexcol);
00093 static List *get_switched_clauses(List *clauses, Relids outerrelids);
00094 static List *order_qual_clauses(PlannerInfo *root, List *clauses);
00095 static void copy_path_costsize(Plan *dest, Path *src);
00096 static void copy_plan_costsize(Plan *dest, Plan *src);
00097 static SeqScan *make_seqscan(List *qptlist, List *qpqual, Index scanrelid);
00098 static IndexScan *make_indexscan(List *qptlist, List *qpqual, Index scanrelid,
00099                Oid indexid, List *indexqual, List *indexqualorig,
00100                List *indexorderby, List *indexorderbyorig,
00101                ScanDirection indexscandir);
00102 static IndexOnlyScan *make_indexonlyscan(List *qptlist, List *qpqual,
00103                    Index scanrelid, Oid indexid,
00104                    List *indexqual, List *indexorderby,
00105                    List *indextlist,
00106                    ScanDirection indexscandir);
00107 static BitmapIndexScan *make_bitmap_indexscan(Index scanrelid, Oid indexid,
00108                       List *indexqual,
00109                       List *indexqualorig);
00110 static BitmapHeapScan *make_bitmap_heapscan(List *qptlist,
00111                      List *qpqual,
00112                      Plan *lefttree,
00113                      List *bitmapqualorig,
00114                      Index scanrelid);
00115 static TidScan *make_tidscan(List *qptlist, List *qpqual, Index scanrelid,
00116              List *tidquals);
00117 static FunctionScan *make_functionscan(List *qptlist, List *qpqual,
00118                   Index scanrelid, Node *funcexpr, List *funccolnames,
00119                   List *funccoltypes, List *funccoltypmods,
00120                   List *funccolcollations);
00121 static ValuesScan *make_valuesscan(List *qptlist, List *qpqual,
00122                 Index scanrelid, List *values_lists);
00123 static CteScan *make_ctescan(List *qptlist, List *qpqual,
00124              Index scanrelid, int ctePlanId, int cteParam);
00125 static WorkTableScan *make_worktablescan(List *qptlist, List *qpqual,
00126                    Index scanrelid, int wtParam);
00127 static BitmapAnd *make_bitmap_and(List *bitmapplans);
00128 static BitmapOr *make_bitmap_or(List *bitmapplans);
00129 static NestLoop *make_nestloop(List *tlist,
00130               List *joinclauses, List *otherclauses, List *nestParams,
00131               Plan *lefttree, Plan *righttree,
00132               JoinType jointype);
00133 static HashJoin *make_hashjoin(List *tlist,
00134               List *joinclauses, List *otherclauses,
00135               List *hashclauses,
00136               Plan *lefttree, Plan *righttree,
00137               JoinType jointype);
00138 static Hash *make_hash(Plan *lefttree,
00139           Oid skewTable,
00140           AttrNumber skewColumn,
00141           bool skewInherit,
00142           Oid skewColType,
00143           int32 skewColTypmod);
00144 static MergeJoin *make_mergejoin(List *tlist,
00145                List *joinclauses, List *otherclauses,
00146                List *mergeclauses,
00147                Oid *mergefamilies,
00148                Oid *mergecollations,
00149                int *mergestrategies,
00150                bool *mergenullsfirst,
00151                Plan *lefttree, Plan *righttree,
00152                JoinType jointype);
00153 static Sort *make_sort(PlannerInfo *root, Plan *lefttree, int numCols,
00154           AttrNumber *sortColIdx, Oid *sortOperators,
00155           Oid *collations, bool *nullsFirst,
00156           double limit_tuples);
00157 static Plan *prepare_sort_from_pathkeys(PlannerInfo *root,
00158                            Plan *lefttree, List *pathkeys,
00159                            Relids relids,
00160                            const AttrNumber *reqColIdx,
00161                            bool adjust_tlist_in_place,
00162                            int *p_numsortkeys,
00163                            AttrNumber **p_sortColIdx,
00164                            Oid **p_sortOperators,
00165                            Oid **p_collations,
00166                            bool **p_nullsFirst);
00167 static EquivalenceMember *find_ec_member_for_tle(EquivalenceClass *ec,
00168                        TargetEntry *tle,
00169                        Relids relids);
00170 static Material *make_material(Plan *lefttree);
00171 
00172 
00173 /*
00174  * create_plan
00175  *    Creates the access plan for a query by recursively processing the
00176  *    desired tree of pathnodes, starting at the node 'best_path'.  For
00177  *    every pathnode found, we create a corresponding plan node containing
00178  *    appropriate id, target list, and qualification information.
00179  *
00180  *    The tlists and quals in the plan tree are still in planner format,
00181  *    ie, Vars still correspond to the parser's numbering.  This will be
00182  *    fixed later by setrefs.c.
00183  *
00184  *    best_path is the best access path
00185  *
00186  *    Returns a Plan tree.
00187  */
00188 Plan *
00189 create_plan(PlannerInfo *root, Path *best_path)
00190 {
00191     Plan       *plan;
00192 
00193     /* plan_params should not be in use in current query level */
00194     Assert(root->plan_params == NIL);
00195 
00196     /* Initialize this module's private workspace in PlannerInfo */
00197     root->curOuterRels = NULL;
00198     root->curOuterParams = NIL;
00199 
00200     /* Recursively process the path tree */
00201     plan = create_plan_recurse(root, best_path);
00202 
00203     /* Check we successfully assigned all NestLoopParams to plan nodes */
00204     if (root->curOuterParams != NIL)
00205         elog(ERROR, "failed to assign all NestLoopParams to plan nodes");
00206 
00207     /*
00208      * Reset plan_params to ensure param IDs used for nestloop params are not
00209      * re-used later
00210      */
00211     root->plan_params = NIL;
00212 
00213     return plan;
00214 }
00215 
00216 /*
00217  * create_plan_recurse
00218  *    Recursive guts of create_plan().
00219  */
00220 static Plan *
00221 create_plan_recurse(PlannerInfo *root, Path *best_path)
00222 {
00223     Plan       *plan;
00224 
00225     switch (best_path->pathtype)
00226     {
00227         case T_SeqScan:
00228         case T_IndexScan:
00229         case T_IndexOnlyScan:
00230         case T_BitmapHeapScan:
00231         case T_TidScan:
00232         case T_SubqueryScan:
00233         case T_FunctionScan:
00234         case T_ValuesScan:
00235         case T_CteScan:
00236         case T_WorkTableScan:
00237         case T_ForeignScan:
00238             plan = create_scan_plan(root, best_path);
00239             break;
00240         case T_HashJoin:
00241         case T_MergeJoin:
00242         case T_NestLoop:
00243             plan = create_join_plan(root,
00244                                     (JoinPath *) best_path);
00245             break;
00246         case T_Append:
00247             plan = create_append_plan(root,
00248                                       (AppendPath *) best_path);
00249             break;
00250         case T_MergeAppend:
00251             plan = create_merge_append_plan(root,
00252                                             (MergeAppendPath *) best_path);
00253             break;
00254         case T_Result:
00255             plan = (Plan *) create_result_plan(root,
00256                                                (ResultPath *) best_path);
00257             break;
00258         case T_Material:
00259             plan = (Plan *) create_material_plan(root,
00260                                                  (MaterialPath *) best_path);
00261             break;
00262         case T_Unique:
00263             plan = create_unique_plan(root,
00264                                       (UniquePath *) best_path);
00265             break;
00266         default:
00267             elog(ERROR, "unrecognized node type: %d",
00268                  (int) best_path->pathtype);
00269             plan = NULL;        /* keep compiler quiet */
00270             break;
00271     }
00272 
00273     return plan;
00274 }
00275 
00276 /*
00277  * create_scan_plan
00278  *   Create a scan plan for the parent relation of 'best_path'.
00279  */
00280 static Plan *
00281 create_scan_plan(PlannerInfo *root, Path *best_path)
00282 {
00283     RelOptInfo *rel = best_path->parent;
00284     List       *tlist;
00285     List       *scan_clauses;
00286     Plan       *plan;
00287 
00288     /*
00289      * For table scans, rather than using the relation targetlist (which is
00290      * only those Vars actually needed by the query), we prefer to generate a
00291      * tlist containing all Vars in order.  This will allow the executor to
00292      * optimize away projection of the table tuples, if possible.  (Note that
00293      * planner.c may replace the tlist we generate here, forcing projection to
00294      * occur.)
00295      */
00296     if (use_physical_tlist(root, rel))
00297     {
00298         if (best_path->pathtype == T_IndexOnlyScan)
00299         {
00300             /* For index-only scan, the preferred tlist is the index's */
00301             tlist = copyObject(((IndexPath *) best_path)->indexinfo->indextlist);
00302         }
00303         else
00304         {
00305             tlist = build_physical_tlist(root, rel);
00306             /* if fail because of dropped cols, use regular method */
00307             if (tlist == NIL)
00308                 tlist = build_relation_tlist(rel);
00309         }
00310     }
00311     else
00312     {
00313         tlist = build_relation_tlist(rel);
00314 
00315         /*
00316          * If it's a parameterized otherrel, there might be lateral references
00317          * in the tlist, which need to be replaced with Params.  This cannot
00318          * happen for regular baserels, though.  Note use_physical_tlist()
00319          * always fails for otherrels, so we don't need to check this above.
00320          */
00321         if (rel->reloptkind != RELOPT_BASEREL && best_path->param_info)
00322             tlist = (List *) replace_nestloop_params(root, (Node *) tlist);
00323     }
00324 
00325     /*
00326      * Extract the relevant restriction clauses from the parent relation. The
00327      * executor must apply all these restrictions during the scan, except for
00328      * pseudoconstants which we'll take care of below.
00329      */
00330     scan_clauses = rel->baserestrictinfo;
00331 
00332     /*
00333      * If this is a parameterized scan, we also need to enforce all the join
00334      * clauses available from the outer relation(s).
00335      *
00336      * For paranoia's sake, don't modify the stored baserestrictinfo list.
00337      */
00338     if (best_path->param_info)
00339         scan_clauses = list_concat(list_copy(scan_clauses),
00340                                    best_path->param_info->ppi_clauses);
00341 
00342     switch (best_path->pathtype)
00343     {
00344         case T_SeqScan:
00345             plan = (Plan *) create_seqscan_plan(root,
00346                                                 best_path,
00347                                                 tlist,
00348                                                 scan_clauses);
00349             break;
00350 
00351         case T_IndexScan:
00352             plan = (Plan *) create_indexscan_plan(root,
00353                                                   (IndexPath *) best_path,
00354                                                   tlist,
00355                                                   scan_clauses,
00356                                                   false);
00357             break;
00358 
00359         case T_IndexOnlyScan:
00360             plan = (Plan *) create_indexscan_plan(root,
00361                                                   (IndexPath *) best_path,
00362                                                   tlist,
00363                                                   scan_clauses,
00364                                                   true);
00365             break;
00366 
00367         case T_BitmapHeapScan:
00368             plan = (Plan *) create_bitmap_scan_plan(root,
00369                                                 (BitmapHeapPath *) best_path,
00370                                                     tlist,
00371                                                     scan_clauses);
00372             break;
00373 
00374         case T_TidScan:
00375             plan = (Plan *) create_tidscan_plan(root,
00376                                                 (TidPath *) best_path,
00377                                                 tlist,
00378                                                 scan_clauses);
00379             break;
00380 
00381         case T_SubqueryScan:
00382             plan = (Plan *) create_subqueryscan_plan(root,
00383                                                      best_path,
00384                                                      tlist,
00385                                                      scan_clauses);
00386             break;
00387 
00388         case T_FunctionScan:
00389             plan = (Plan *) create_functionscan_plan(root,
00390                                                      best_path,
00391                                                      tlist,
00392                                                      scan_clauses);
00393             break;
00394 
00395         case T_ValuesScan:
00396             plan = (Plan *) create_valuesscan_plan(root,
00397                                                    best_path,
00398                                                    tlist,
00399                                                    scan_clauses);
00400             break;
00401 
00402         case T_CteScan:
00403             plan = (Plan *) create_ctescan_plan(root,
00404                                                 best_path,
00405                                                 tlist,
00406                                                 scan_clauses);
00407             break;
00408 
00409         case T_WorkTableScan:
00410             plan = (Plan *) create_worktablescan_plan(root,
00411                                                       best_path,
00412                                                       tlist,
00413                                                       scan_clauses);
00414             break;
00415 
00416         case T_ForeignScan:
00417             plan = (Plan *) create_foreignscan_plan(root,
00418                                                     (ForeignPath *) best_path,
00419                                                     tlist,
00420                                                     scan_clauses);
00421             break;
00422 
00423         default:
00424             elog(ERROR, "unrecognized node type: %d",
00425                  (int) best_path->pathtype);
00426             plan = NULL;        /* keep compiler quiet */
00427             break;
00428     }
00429 
00430     /*
00431      * If there are any pseudoconstant clauses attached to this node, insert a
00432      * gating Result node that evaluates the pseudoconstants as one-time
00433      * quals.
00434      */
00435     if (root->hasPseudoConstantQuals)
00436         plan = create_gating_plan(root, plan, scan_clauses);
00437 
00438     return plan;
00439 }
00440 
00441 /*
00442  * Build a target list (ie, a list of TargetEntry) for a relation.
00443  */
00444 static List *
00445 build_relation_tlist(RelOptInfo *rel)
00446 {
00447     List       *tlist = NIL;
00448     int         resno = 1;
00449     ListCell   *v;
00450 
00451     foreach(v, rel->reltargetlist)
00452     {
00453         /* Do we really need to copy here?  Not sure */
00454         Node       *node = (Node *) copyObject(lfirst(v));
00455 
00456         tlist = lappend(tlist, makeTargetEntry((Expr *) node,
00457                                                resno,
00458                                                NULL,
00459                                                false));
00460         resno++;
00461     }
00462     return tlist;
00463 }
00464 
00465 /*
00466  * use_physical_tlist
00467  *      Decide whether to use a tlist matching relation structure,
00468  *      rather than only those Vars actually referenced.
00469  */
00470 static bool
00471 use_physical_tlist(PlannerInfo *root, RelOptInfo *rel)
00472 {
00473     int         i;
00474     ListCell   *lc;
00475 
00476     /*
00477      * We can do this for real relation scans, subquery scans, function scans,
00478      * values scans, and CTE scans (but not for, eg, joins).
00479      */
00480     if (rel->rtekind != RTE_RELATION &&
00481         rel->rtekind != RTE_SUBQUERY &&
00482         rel->rtekind != RTE_FUNCTION &&
00483         rel->rtekind != RTE_VALUES &&
00484         rel->rtekind != RTE_CTE)
00485         return false;
00486 
00487     /*
00488      * Can't do it with inheritance cases either (mainly because Append
00489      * doesn't project).
00490      */
00491     if (rel->reloptkind != RELOPT_BASEREL)
00492         return false;
00493 
00494     /*
00495      * Can't do it if any system columns or whole-row Vars are requested.
00496      * (This could possibly be fixed but would take some fragile assumptions
00497      * in setrefs.c, I think.)
00498      */
00499     for (i = rel->min_attr; i <= 0; i++)
00500     {
00501         if (!bms_is_empty(rel->attr_needed[i - rel->min_attr]))
00502             return false;
00503     }
00504 
00505     /*
00506      * Can't do it if the rel is required to emit any placeholder expressions,
00507      * either.
00508      */
00509     foreach(lc, root->placeholder_list)
00510     {
00511         PlaceHolderInfo *phinfo = (PlaceHolderInfo *) lfirst(lc);
00512 
00513         if (bms_nonempty_difference(phinfo->ph_needed, rel->relids) &&
00514             bms_is_subset(phinfo->ph_eval_at, rel->relids))
00515             return false;
00516     }
00517 
00518     return true;
00519 }
00520 
00521 /*
00522  * disuse_physical_tlist
00523  *      Switch a plan node back to emitting only Vars actually referenced.
00524  *
00525  * If the plan node immediately above a scan would prefer to get only
00526  * needed Vars and not a physical tlist, it must call this routine to
00527  * undo the decision made by use_physical_tlist().  Currently, Hash, Sort,
00528  * and Material nodes want this, so they don't have to store useless columns.
00529  */
00530 static void
00531 disuse_physical_tlist(Plan *plan, Path *path)
00532 {
00533     /* Only need to undo it for path types handled by create_scan_plan() */
00534     switch (path->pathtype)
00535     {
00536         case T_SeqScan:
00537         case T_IndexScan:
00538         case T_IndexOnlyScan:
00539         case T_BitmapHeapScan:
00540         case T_TidScan:
00541         case T_SubqueryScan:
00542         case T_FunctionScan:
00543         case T_ValuesScan:
00544         case T_CteScan:
00545         case T_WorkTableScan:
00546         case T_ForeignScan:
00547             plan->targetlist = build_relation_tlist(path->parent);
00548             break;
00549         default:
00550             break;
00551     }
00552 }
00553 
00554 /*
00555  * create_gating_plan
00556  *    Deal with pseudoconstant qual clauses
00557  *
00558  * If the node's quals list includes any pseudoconstant quals, put them
00559  * into a gating Result node atop the already-built plan.  Otherwise,
00560  * return the plan as-is.
00561  *
00562  * Note that we don't change cost or size estimates when doing gating.
00563  * The costs of qual eval were already folded into the plan's startup cost.
00564  * Leaving the size alone amounts to assuming that the gating qual will
00565  * succeed, which is the conservative estimate for planning upper queries.
00566  * We certainly don't want to assume the output size is zero (unless the
00567  * gating qual is actually constant FALSE, and that case is dealt with in
00568  * clausesel.c).  Interpolating between the two cases is silly, because
00569  * it doesn't reflect what will really happen at runtime, and besides which
00570  * in most cases we have only a very bad idea of the probability of the gating
00571  * qual being true.
00572  */
00573 static Plan *
00574 create_gating_plan(PlannerInfo *root, Plan *plan, List *quals)
00575 {
00576     List       *pseudoconstants;
00577 
00578     /* Sort into desirable execution order while still in RestrictInfo form */
00579     quals = order_qual_clauses(root, quals);
00580 
00581     /* Pull out any pseudoconstant quals from the RestrictInfo list */
00582     pseudoconstants = extract_actual_clauses(quals, true);
00583 
00584     if (!pseudoconstants)
00585         return plan;
00586 
00587     return (Plan *) make_result(root,
00588                                 plan->targetlist,
00589                                 (Node *) pseudoconstants,
00590                                 plan);
00591 }
00592 
00593 /*
00594  * create_join_plan
00595  *    Create a join plan for 'best_path' and (recursively) plans for its
00596  *    inner and outer paths.
00597  */
00598 static Plan *
00599 create_join_plan(PlannerInfo *root, JoinPath *best_path)
00600 {
00601     Plan       *outer_plan;
00602     Plan       *inner_plan;
00603     Plan       *plan;
00604     Relids      saveOuterRels = root->curOuterRels;
00605 
00606     outer_plan = create_plan_recurse(root, best_path->outerjoinpath);
00607 
00608     /* For a nestloop, include outer relids in curOuterRels for inner side */
00609     if (best_path->path.pathtype == T_NestLoop)
00610         root->curOuterRels = bms_union(root->curOuterRels,
00611                                    best_path->outerjoinpath->parent->relids);
00612 
00613     inner_plan = create_plan_recurse(root, best_path->innerjoinpath);
00614 
00615     switch (best_path->path.pathtype)
00616     {
00617         case T_MergeJoin:
00618             plan = (Plan *) create_mergejoin_plan(root,
00619                                                   (MergePath *) best_path,
00620                                                   outer_plan,
00621                                                   inner_plan);
00622             break;
00623         case T_HashJoin:
00624             plan = (Plan *) create_hashjoin_plan(root,
00625                                                  (HashPath *) best_path,
00626                                                  outer_plan,
00627                                                  inner_plan);
00628             break;
00629         case T_NestLoop:
00630             /* Restore curOuterRels */
00631             bms_free(root->curOuterRels);
00632             root->curOuterRels = saveOuterRels;
00633 
00634             plan = (Plan *) create_nestloop_plan(root,
00635                                                  (NestPath *) best_path,
00636                                                  outer_plan,
00637                                                  inner_plan);
00638             break;
00639         default:
00640             elog(ERROR, "unrecognized node type: %d",
00641                  (int) best_path->path.pathtype);
00642             plan = NULL;        /* keep compiler quiet */
00643             break;
00644     }
00645 
00646     /*
00647      * If there are any pseudoconstant clauses attached to this node, insert a
00648      * gating Result node that evaluates the pseudoconstants as one-time
00649      * quals.
00650      */
00651     if (root->hasPseudoConstantQuals)
00652         plan = create_gating_plan(root, plan, best_path->joinrestrictinfo);
00653 
00654 #ifdef NOT_USED
00655 
00656     /*
00657      * * Expensive function pullups may have pulled local predicates * into
00658      * this path node.  Put them in the qpqual of the plan node. * JMH,
00659      * 6/15/92
00660      */
00661     if (get_loc_restrictinfo(best_path) != NIL)
00662         set_qpqual((Plan) plan,
00663                    list_concat(get_qpqual((Plan) plan),
00664                        get_actual_clauses(get_loc_restrictinfo(best_path))));
00665 #endif
00666 
00667     return plan;
00668 }
00669 
00670 /*
00671  * create_append_plan
00672  *    Create an Append plan for 'best_path' and (recursively) plans
00673  *    for its subpaths.
00674  *
00675  *    Returns a Plan node.
00676  */
00677 static Plan *
00678 create_append_plan(PlannerInfo *root, AppendPath *best_path)
00679 {
00680     Append     *plan;
00681     RelOptInfo *rel = best_path->path.parent;
00682     List       *tlist = build_relation_tlist(rel);
00683     List       *subplans = NIL;
00684     ListCell   *subpaths;
00685 
00686     /*
00687      * The subpaths list could be empty, if every child was proven empty by
00688      * constraint exclusion.  In that case generate a dummy plan that returns
00689      * no rows.
00690      *
00691      * Note that an AppendPath with no members is also generated in certain
00692      * cases where there was no appending construct at all, but we know the
00693      * relation is empty (see set_dummy_rel_pathlist).
00694      */
00695     if (best_path->subpaths == NIL)
00696     {
00697         /*
00698          * If this is a dummy path for a subquery, we have to wrap the
00699          * subquery's original plan in a SubqueryScan so that setrefs.c will
00700          * do the right things.  (In particular, it must pull up the
00701          * subquery's rangetable so that the executor will apply permissions
00702          * checks to those rels at runtime.)
00703          */
00704         if (rel->rtekind == RTE_SUBQUERY)
00705         {
00706             Assert(is_dummy_plan(rel->subplan));
00707             return (Plan *) make_subqueryscan(tlist,
00708                                               NIL,
00709                                               rel->relid,
00710                                               rel->subplan);
00711         }
00712         else
00713         {
00714             /* Generate a Result plan with constant-FALSE gating qual */
00715             return (Plan *) make_result(root,
00716                                         tlist,
00717                                      (Node *) list_make1(makeBoolConst(false,
00718                                                                      false)),
00719                                         NULL);
00720         }
00721     }
00722 
00723     /* Build the plan for each child */
00724     foreach(subpaths, best_path->subpaths)
00725     {
00726         Path       *subpath = (Path *) lfirst(subpaths);
00727 
00728         subplans = lappend(subplans, create_plan_recurse(root, subpath));
00729     }
00730 
00731     /*
00732      * XXX ideally, if there's just one child, we'd not bother to generate an
00733      * Append node but just return the single child.  At the moment this does
00734      * not work because the varno of the child scan plan won't match the
00735      * parent-rel Vars it'll be asked to emit.
00736      */
00737 
00738     plan = make_append(subplans, tlist);
00739 
00740     return (Plan *) plan;
00741 }
00742 
00743 /*
00744  * create_merge_append_plan
00745  *    Create a MergeAppend plan for 'best_path' and (recursively) plans
00746  *    for its subpaths.
00747  *
00748  *    Returns a Plan node.
00749  */
00750 static Plan *
00751 create_merge_append_plan(PlannerInfo *root, MergeAppendPath *best_path)
00752 {
00753     MergeAppend *node = makeNode(MergeAppend);
00754     Plan       *plan = &node->plan;
00755     List       *tlist = build_relation_tlist(best_path->path.parent);
00756     List       *pathkeys = best_path->path.pathkeys;
00757     List       *subplans = NIL;
00758     ListCell   *subpaths;
00759 
00760     /*
00761      * We don't have the actual creation of the MergeAppend node split out
00762      * into a separate make_xxx function.  This is because we want to run
00763      * prepare_sort_from_pathkeys on it before we do so on the individual
00764      * child plans, to make cross-checking the sort info easier.
00765      */
00766     copy_path_costsize(plan, (Path *) best_path);
00767     plan->targetlist = tlist;
00768     plan->qual = NIL;
00769     plan->lefttree = NULL;
00770     plan->righttree = NULL;
00771 
00772     /* Compute sort column info, and adjust MergeAppend's tlist as needed */
00773     (void) prepare_sort_from_pathkeys(root, plan, pathkeys,
00774                                       NULL,
00775                                       NULL,
00776                                       true,
00777                                       &node->numCols,
00778                                       &node->sortColIdx,
00779                                       &node->sortOperators,
00780                                       &node->collations,
00781                                       &node->nullsFirst);
00782 
00783     /*
00784      * Now prepare the child plans.  We must apply prepare_sort_from_pathkeys
00785      * even to subplans that don't need an explicit sort, to make sure they
00786      * are returning the same sort key columns the MergeAppend expects.
00787      */
00788     foreach(subpaths, best_path->subpaths)
00789     {
00790         Path       *subpath = (Path *) lfirst(subpaths);
00791         Plan       *subplan;
00792         int         numsortkeys;
00793         AttrNumber *sortColIdx;
00794         Oid        *sortOperators;
00795         Oid        *collations;
00796         bool       *nullsFirst;
00797 
00798         /* Build the child plan */
00799         subplan = create_plan_recurse(root, subpath);
00800 
00801         /* Compute sort column info, and adjust subplan's tlist as needed */
00802         subplan = prepare_sort_from_pathkeys(root, subplan, pathkeys,
00803                                              subpath->parent->relids,
00804                                              node->sortColIdx,
00805                                              false,
00806                                              &numsortkeys,
00807                                              &sortColIdx,
00808                                              &sortOperators,
00809                                              &collations,
00810                                              &nullsFirst);
00811 
00812         /*
00813          * Check that we got the same sort key information.  We just Assert
00814          * that the sortops match, since those depend only on the pathkeys;
00815          * but it seems like a good idea to check the sort column numbers
00816          * explicitly, to ensure the tlists really do match up.
00817          */
00818         Assert(numsortkeys == node->numCols);
00819         if (memcmp(sortColIdx, node->sortColIdx,
00820                    numsortkeys * sizeof(AttrNumber)) != 0)
00821             elog(ERROR, "MergeAppend child's targetlist doesn't match MergeAppend");
00822         Assert(memcmp(sortOperators, node->sortOperators,
00823                       numsortkeys * sizeof(Oid)) == 0);
00824         Assert(memcmp(collations, node->collations,
00825                       numsortkeys * sizeof(Oid)) == 0);
00826         Assert(memcmp(nullsFirst, node->nullsFirst,
00827                       numsortkeys * sizeof(bool)) == 0);
00828 
00829         /* Now, insert a Sort node if subplan isn't sufficiently ordered */
00830         if (!pathkeys_contained_in(pathkeys, subpath->pathkeys))
00831             subplan = (Plan *) make_sort(root, subplan, numsortkeys,
00832                                          sortColIdx, sortOperators,
00833                                          collations, nullsFirst,
00834                                          best_path->limit_tuples);
00835 
00836         subplans = lappend(subplans, subplan);
00837     }
00838 
00839     node->mergeplans = subplans;
00840 
00841     return (Plan *) node;
00842 }
00843 
00844 /*
00845  * create_result_plan
00846  *    Create a Result plan for 'best_path'.
00847  *    This is only used for the case of a query with an empty jointree.
00848  *
00849  *    Returns a Plan node.
00850  */
00851 static Result *
00852 create_result_plan(PlannerInfo *root, ResultPath *best_path)
00853 {
00854     List       *tlist;
00855     List       *quals;
00856 
00857     /* The tlist will be installed later, since we have no RelOptInfo */
00858     Assert(best_path->path.parent == NULL);
00859     tlist = NIL;
00860 
00861     /* best_path->quals is just bare clauses */
00862 
00863     quals = order_qual_clauses(root, best_path->quals);
00864 
00865     return make_result(root, tlist, (Node *) quals, NULL);
00866 }
00867 
00868 /*
00869  * create_material_plan
00870  *    Create a Material plan for 'best_path' and (recursively) plans
00871  *    for its subpaths.
00872  *
00873  *    Returns a Plan node.
00874  */
00875 static Material *
00876 create_material_plan(PlannerInfo *root, MaterialPath *best_path)
00877 {
00878     Material   *plan;
00879     Plan       *subplan;
00880 
00881     subplan = create_plan_recurse(root, best_path->subpath);
00882 
00883     /* We don't want any excess columns in the materialized tuples */
00884     disuse_physical_tlist(subplan, best_path->subpath);
00885 
00886     plan = make_material(subplan);
00887 
00888     copy_path_costsize(&plan->plan, (Path *) best_path);
00889 
00890     return plan;
00891 }
00892 
00893 /*
00894  * create_unique_plan
00895  *    Create a Unique plan for 'best_path' and (recursively) plans
00896  *    for its subpaths.
00897  *
00898  *    Returns a Plan node.
00899  */
00900 static Plan *
00901 create_unique_plan(PlannerInfo *root, UniquePath *best_path)
00902 {
00903     Plan       *plan;
00904     Plan       *subplan;
00905     List       *in_operators;
00906     List       *uniq_exprs;
00907     List       *newtlist;
00908     int         nextresno;
00909     bool        newitems;
00910     int         numGroupCols;
00911     AttrNumber *groupColIdx;
00912     int         groupColPos;
00913     ListCell   *l;
00914 
00915     subplan = create_plan_recurse(root, best_path->subpath);
00916 
00917     /* Done if we don't need to do any actual unique-ifying */
00918     if (best_path->umethod == UNIQUE_PATH_NOOP)
00919         return subplan;
00920 
00921     /*
00922      * As constructed, the subplan has a "flat" tlist containing just the Vars
00923      * needed here and at upper levels.  The values we are supposed to
00924      * unique-ify may be expressions in these variables.  We have to add any
00925      * such expressions to the subplan's tlist.
00926      *
00927      * The subplan may have a "physical" tlist if it is a simple scan plan. If
00928      * we're going to sort, this should be reduced to the regular tlist, so
00929      * that we don't sort more data than we need to.  For hashing, the tlist
00930      * should be left as-is if we don't need to add any expressions; but if we
00931      * do have to add expressions, then a projection step will be needed at
00932      * runtime anyway, so we may as well remove unneeded items. Therefore
00933      * newtlist starts from build_relation_tlist() not just a copy of the
00934      * subplan's tlist; and we don't install it into the subplan unless we are
00935      * sorting or stuff has to be added.
00936      */
00937     in_operators = best_path->in_operators;
00938     uniq_exprs = best_path->uniq_exprs;
00939 
00940     /* initialize modified subplan tlist as just the "required" vars */
00941     newtlist = build_relation_tlist(best_path->path.parent);
00942     nextresno = list_length(newtlist) + 1;
00943     newitems = false;
00944 
00945     foreach(l, uniq_exprs)
00946     {
00947         Node       *uniqexpr = lfirst(l);
00948         TargetEntry *tle;
00949 
00950         tle = tlist_member(uniqexpr, newtlist);
00951         if (!tle)
00952         {
00953             tle = makeTargetEntry((Expr *) uniqexpr,
00954                                   nextresno,
00955                                   NULL,
00956                                   false);
00957             newtlist = lappend(newtlist, tle);
00958             nextresno++;
00959             newitems = true;
00960         }
00961     }
00962 
00963     if (newitems || best_path->umethod == UNIQUE_PATH_SORT)
00964     {
00965         /*
00966          * If the top plan node can't do projections and its existing target
00967          * list isn't already what we need, we need to add a Result node to
00968          * help it along.
00969          */
00970         if (!is_projection_capable_plan(subplan) &&
00971             !tlist_same_exprs(newtlist, subplan->targetlist))
00972             subplan = (Plan *) make_result(root, newtlist, NULL, subplan);
00973         else
00974             subplan->targetlist = newtlist;
00975     }
00976 
00977     /*
00978      * Build control information showing which subplan output columns are to
00979      * be examined by the grouping step.  Unfortunately we can't merge this
00980      * with the previous loop, since we didn't then know which version of the
00981      * subplan tlist we'd end up using.
00982      */
00983     newtlist = subplan->targetlist;
00984     numGroupCols = list_length(uniq_exprs);
00985     groupColIdx = (AttrNumber *) palloc(numGroupCols * sizeof(AttrNumber));
00986 
00987     groupColPos = 0;
00988     foreach(l, uniq_exprs)
00989     {
00990         Node       *uniqexpr = lfirst(l);
00991         TargetEntry *tle;
00992 
00993         tle = tlist_member(uniqexpr, newtlist);
00994         if (!tle)               /* shouldn't happen */
00995             elog(ERROR, "failed to find unique expression in subplan tlist");
00996         groupColIdx[groupColPos++] = tle->resno;
00997     }
00998 
00999     if (best_path->umethod == UNIQUE_PATH_HASH)
01000     {
01001         long        numGroups;
01002         Oid        *groupOperators;
01003 
01004         numGroups = (long) Min(best_path->path.rows, (double) LONG_MAX);
01005 
01006         /*
01007          * Get the hashable equality operators for the Agg node to use.
01008          * Normally these are the same as the IN clause operators, but if
01009          * those are cross-type operators then the equality operators are the
01010          * ones for the IN clause operators' RHS datatype.
01011          */
01012         groupOperators = (Oid *) palloc(numGroupCols * sizeof(Oid));
01013         groupColPos = 0;
01014         foreach(l, in_operators)
01015         {
01016             Oid         in_oper = lfirst_oid(l);
01017             Oid         eq_oper;
01018 
01019             if (!get_compatible_hash_operators(in_oper, NULL, &eq_oper))
01020                 elog(ERROR, "could not find compatible hash operator for operator %u",
01021                      in_oper);
01022             groupOperators[groupColPos++] = eq_oper;
01023         }
01024 
01025         /*
01026          * Since the Agg node is going to project anyway, we can give it the
01027          * minimum output tlist, without any stuff we might have added to the
01028          * subplan tlist.
01029          */
01030         plan = (Plan *) make_agg(root,
01031                                  build_relation_tlist(best_path->path.parent),
01032                                  NIL,
01033                                  AGG_HASHED,
01034                                  NULL,
01035                                  numGroupCols,
01036                                  groupColIdx,
01037                                  groupOperators,
01038                                  numGroups,
01039                                  subplan);
01040     }
01041     else
01042     {
01043         List       *sortList = NIL;
01044 
01045         /* Create an ORDER BY list to sort the input compatibly */
01046         groupColPos = 0;
01047         foreach(l, in_operators)
01048         {
01049             Oid         in_oper = lfirst_oid(l);
01050             Oid         sortop;
01051             Oid         eqop;
01052             TargetEntry *tle;
01053             SortGroupClause *sortcl;
01054 
01055             sortop = get_ordering_op_for_equality_op(in_oper, false);
01056             if (!OidIsValid(sortop))    /* shouldn't happen */
01057                 elog(ERROR, "could not find ordering operator for equality operator %u",
01058                      in_oper);
01059 
01060             /*
01061              * The Unique node will need equality operators.  Normally these
01062              * are the same as the IN clause operators, but if those are
01063              * cross-type operators then the equality operators are the ones
01064              * for the IN clause operators' RHS datatype.
01065              */
01066             eqop = get_equality_op_for_ordering_op(sortop, NULL);
01067             if (!OidIsValid(eqop))      /* shouldn't happen */
01068                 elog(ERROR, "could not find equality operator for ordering operator %u",
01069                      sortop);
01070 
01071             tle = get_tle_by_resno(subplan->targetlist,
01072                                    groupColIdx[groupColPos]);
01073             Assert(tle != NULL);
01074 
01075             sortcl = makeNode(SortGroupClause);
01076             sortcl->tleSortGroupRef = assignSortGroupRef(tle,
01077                                                          subplan->targetlist);
01078             sortcl->eqop = eqop;
01079             sortcl->sortop = sortop;
01080             sortcl->nulls_first = false;
01081             sortcl->hashable = false;   /* no need to make this accurate */
01082             sortList = lappend(sortList, sortcl);
01083             groupColPos++;
01084         }
01085         plan = (Plan *) make_sort_from_sortclauses(root, sortList, subplan);
01086         plan = (Plan *) make_unique(plan, sortList);
01087     }
01088 
01089     /* Adjust output size estimate (other fields should be OK already) */
01090     plan->plan_rows = best_path->path.rows;
01091 
01092     return plan;
01093 }
01094 
01095 
01096 /*****************************************************************************
01097  *
01098  *  BASE-RELATION SCAN METHODS
01099  *
01100  *****************************************************************************/
01101 
01102 
01103 /*
01104  * create_seqscan_plan
01105  *   Returns a seqscan plan for the base relation scanned by 'best_path'
01106  *   with restriction clauses 'scan_clauses' and targetlist 'tlist'.
01107  */
01108 static SeqScan *
01109 create_seqscan_plan(PlannerInfo *root, Path *best_path,
01110                     List *tlist, List *scan_clauses)
01111 {
01112     SeqScan    *scan_plan;
01113     Index       scan_relid = best_path->parent->relid;
01114 
01115     /* it should be a base rel... */
01116     Assert(scan_relid > 0);
01117     Assert(best_path->parent->rtekind == RTE_RELATION);
01118 
01119     /* Sort clauses into best execution order */
01120     scan_clauses = order_qual_clauses(root, scan_clauses);
01121 
01122     /* Reduce RestrictInfo list to bare expressions; ignore pseudoconstants */
01123     scan_clauses = extract_actual_clauses(scan_clauses, false);
01124 
01125     /* Replace any outer-relation variables with nestloop params */
01126     if (best_path->param_info)
01127     {
01128         scan_clauses = (List *)
01129             replace_nestloop_params(root, (Node *) scan_clauses);
01130     }
01131 
01132     scan_plan = make_seqscan(tlist,
01133                              scan_clauses,
01134                              scan_relid);
01135 
01136     copy_path_costsize(&scan_plan->plan, best_path);
01137 
01138     return scan_plan;
01139 }
01140 
01141 /*
01142  * create_indexscan_plan
01143  *    Returns an indexscan plan for the base relation scanned by 'best_path'
01144  *    with restriction clauses 'scan_clauses' and targetlist 'tlist'.
01145  *
01146  * We use this for both plain IndexScans and IndexOnlyScans, because the
01147  * qual preprocessing work is the same for both.  Note that the caller tells
01148  * us which to build --- we don't look at best_path->path.pathtype, because
01149  * create_bitmap_subplan needs to be able to override the prior decision.
01150  */
01151 static Scan *
01152 create_indexscan_plan(PlannerInfo *root,
01153                       IndexPath *best_path,
01154                       List *tlist,
01155                       List *scan_clauses,
01156                       bool indexonly)
01157 {
01158     Scan       *scan_plan;
01159     List       *indexquals = best_path->indexquals;
01160     List       *indexorderbys = best_path->indexorderbys;
01161     Index       baserelid = best_path->path.parent->relid;
01162     Oid         indexoid = best_path->indexinfo->indexoid;
01163     List       *qpqual;
01164     List       *stripped_indexquals;
01165     List       *fixed_indexquals;
01166     List       *fixed_indexorderbys;
01167     ListCell   *l;
01168 
01169     /* it should be a base rel... */
01170     Assert(baserelid > 0);
01171     Assert(best_path->path.parent->rtekind == RTE_RELATION);
01172 
01173     /*
01174      * Build "stripped" indexquals structure (no RestrictInfos) to pass to
01175      * executor as indexqualorig
01176      */
01177     stripped_indexquals = get_actual_clauses(indexquals);
01178 
01179     /*
01180      * The executor needs a copy with the indexkey on the left of each clause
01181      * and with index Vars substituted for table ones.
01182      */
01183     fixed_indexquals = fix_indexqual_references(root, best_path);
01184 
01185     /*
01186      * Likewise fix up index attr references in the ORDER BY expressions.
01187      */
01188     fixed_indexorderbys = fix_indexorderby_references(root, best_path);
01189 
01190     /*
01191      * The qpqual list must contain all restrictions not automatically handled
01192      * by the index, other than pseudoconstant clauses which will be handled
01193      * by a separate gating plan node.  All the predicates in the indexquals
01194      * will be checked (either by the index itself, or by nodeIndexscan.c),
01195      * but if there are any "special" operators involved then they must be
01196      * included in qpqual.  The upshot is that qpqual must contain
01197      * scan_clauses minus whatever appears in indexquals.
01198      *
01199      * In normal cases simple pointer equality checks will be enough to spot
01200      * duplicate RestrictInfos, so we try that first.
01201      *
01202      * Another common case is that a scan_clauses entry is generated from the
01203      * same EquivalenceClass as some indexqual, and is therefore redundant
01204      * with it, though not equal.  (This happens when indxpath.c prefers a
01205      * different derived equality than what generate_join_implied_equalities
01206      * picked for a parameterized scan's ppi_clauses.)
01207      *
01208      * In some situations (particularly with OR'd index conditions) we may
01209      * have scan_clauses that are not equal to, but are logically implied by,
01210      * the index quals; so we also try a predicate_implied_by() check to see
01211      * if we can discard quals that way.  (predicate_implied_by assumes its
01212      * first input contains only immutable functions, so we have to check
01213      * that.)
01214      *
01215      * We can also discard quals that are implied by a partial index's
01216      * predicate, but only in a plain SELECT; when scanning a target relation
01217      * of UPDATE/DELETE/SELECT FOR UPDATE, we must leave such quals in the
01218      * plan so that they'll be properly rechecked by EvalPlanQual testing.
01219      */
01220     qpqual = NIL;
01221     foreach(l, scan_clauses)
01222     {
01223         RestrictInfo *rinfo = (RestrictInfo *) lfirst(l);
01224 
01225         Assert(IsA(rinfo, RestrictInfo));
01226         if (rinfo->pseudoconstant)
01227             continue;           /* we may drop pseudoconstants here */
01228         if (list_member_ptr(indexquals, rinfo))
01229             continue;           /* simple duplicate */
01230         if (is_redundant_derived_clause(rinfo, indexquals))
01231             continue;           /* derived from same EquivalenceClass */
01232         if (!contain_mutable_functions((Node *) rinfo->clause))
01233         {
01234             List       *clausel = list_make1(rinfo->clause);
01235 
01236             if (predicate_implied_by(clausel, indexquals))
01237                 continue;       /* provably implied by indexquals */
01238             if (best_path->indexinfo->indpred)
01239             {
01240                 if (baserelid != root->parse->resultRelation &&
01241                     get_parse_rowmark(root->parse, baserelid) == NULL)
01242                     if (predicate_implied_by(clausel,
01243                                              best_path->indexinfo->indpred))
01244                         continue;       /* implied by index predicate */
01245             }
01246         }
01247         qpqual = lappend(qpqual, rinfo);
01248     }
01249 
01250     /* Sort clauses into best execution order */
01251     qpqual = order_qual_clauses(root, qpqual);
01252 
01253     /* Reduce RestrictInfo list to bare expressions; ignore pseudoconstants */
01254     qpqual = extract_actual_clauses(qpqual, false);
01255 
01256     /*
01257      * We have to replace any outer-relation variables with nestloop params in
01258      * the indexqualorig, qpqual, and indexorderbyorig expressions.  A bit
01259      * annoying to have to do this separately from the processing in
01260      * fix_indexqual_references --- rethink this when generalizing the inner
01261      * indexscan support.  But note we can't really do this earlier because
01262      * it'd break the comparisons to predicates above ... (or would it?  Those
01263      * wouldn't have outer refs)
01264      */
01265     if (best_path->path.param_info)
01266     {
01267         stripped_indexquals = (List *)
01268             replace_nestloop_params(root, (Node *) stripped_indexquals);
01269         qpqual = (List *)
01270             replace_nestloop_params(root, (Node *) qpqual);
01271         indexorderbys = (List *)
01272             replace_nestloop_params(root, (Node *) indexorderbys);
01273     }
01274 
01275     /* Finally ready to build the plan node */
01276     if (indexonly)
01277         scan_plan = (Scan *) make_indexonlyscan(tlist,
01278                                                 qpqual,
01279                                                 baserelid,
01280                                                 indexoid,
01281                                                 fixed_indexquals,
01282                                                 fixed_indexorderbys,
01283                                             best_path->indexinfo->indextlist,
01284                                                 best_path->indexscandir);
01285     else
01286         scan_plan = (Scan *) make_indexscan(tlist,
01287                                             qpqual,
01288                                             baserelid,
01289                                             indexoid,
01290                                             fixed_indexquals,
01291                                             stripped_indexquals,
01292                                             fixed_indexorderbys,
01293                                             indexorderbys,
01294                                             best_path->indexscandir);
01295 
01296     copy_path_costsize(&scan_plan->plan, &best_path->path);
01297 
01298     return scan_plan;
01299 }
01300 
01301 /*
01302  * create_bitmap_scan_plan
01303  *    Returns a bitmap scan plan for the base relation scanned by 'best_path'
01304  *    with restriction clauses 'scan_clauses' and targetlist 'tlist'.
01305  */
01306 static BitmapHeapScan *
01307 create_bitmap_scan_plan(PlannerInfo *root,
01308                         BitmapHeapPath *best_path,
01309                         List *tlist,
01310                         List *scan_clauses)
01311 {
01312     Index       baserelid = best_path->path.parent->relid;
01313     Plan       *bitmapqualplan;
01314     List       *bitmapqualorig;
01315     List       *indexquals;
01316     List       *indexECs;
01317     List       *qpqual;
01318     ListCell   *l;
01319     BitmapHeapScan *scan_plan;
01320 
01321     /* it should be a base rel... */
01322     Assert(baserelid > 0);
01323     Assert(best_path->path.parent->rtekind == RTE_RELATION);
01324 
01325     /* Process the bitmapqual tree into a Plan tree and qual lists */
01326     bitmapqualplan = create_bitmap_subplan(root, best_path->bitmapqual,
01327                                            &bitmapqualorig, &indexquals,
01328                                            &indexECs);
01329 
01330     /*
01331      * The qpqual list must contain all restrictions not automatically handled
01332      * by the index, other than pseudoconstant clauses which will be handled
01333      * by a separate gating plan node.  All the predicates in the indexquals
01334      * will be checked (either by the index itself, or by
01335      * nodeBitmapHeapscan.c), but if there are any "special" operators
01336      * involved then they must be added to qpqual.  The upshot is that qpqual
01337      * must contain scan_clauses minus whatever appears in indexquals.
01338      *
01339      * This loop is similar to the comparable code in create_indexscan_plan(),
01340      * but with some differences because it has to compare the scan clauses to
01341      * stripped (no RestrictInfos) indexquals.  See comments there for more
01342      * info.
01343      *
01344      * In normal cases simple equal() checks will be enough to spot duplicate
01345      * clauses, so we try that first.  We next see if the scan clause is
01346      * redundant with any top-level indexqual by virtue of being generated
01347      * from the same EC.  After that, try predicate_implied_by().
01348      *
01349      * Unlike create_indexscan_plan(), we need take no special thought here
01350      * for partial index predicates; this is because the predicate conditions
01351      * are already listed in bitmapqualorig and indexquals.  Bitmap scans have
01352      * to do it that way because predicate conditions need to be rechecked if
01353      * the scan becomes lossy, so they have to be included in bitmapqualorig.
01354      */
01355     qpqual = NIL;
01356     foreach(l, scan_clauses)
01357     {
01358         RestrictInfo *rinfo = (RestrictInfo *) lfirst(l);
01359         Node       *clause = (Node *) rinfo->clause;
01360 
01361         Assert(IsA(rinfo, RestrictInfo));
01362         if (rinfo->pseudoconstant)
01363             continue;           /* we may drop pseudoconstants here */
01364         if (list_member(indexquals, clause))
01365             continue;           /* simple duplicate */
01366         if (rinfo->parent_ec && list_member_ptr(indexECs, rinfo->parent_ec))
01367             continue;           /* derived from same EquivalenceClass */
01368         if (!contain_mutable_functions(clause))
01369         {
01370             List       *clausel = list_make1(clause);
01371 
01372             if (predicate_implied_by(clausel, indexquals))
01373                 continue;       /* provably implied by indexquals */
01374         }
01375         qpqual = lappend(qpqual, rinfo);
01376     }
01377 
01378     /* Sort clauses into best execution order */
01379     qpqual = order_qual_clauses(root, qpqual);
01380 
01381     /* Reduce RestrictInfo list to bare expressions; ignore pseudoconstants */
01382     qpqual = extract_actual_clauses(qpqual, false);
01383 
01384     /*
01385      * When dealing with special operators, we will at this point have
01386      * duplicate clauses in qpqual and bitmapqualorig.  We may as well drop
01387      * 'em from bitmapqualorig, since there's no point in making the tests
01388      * twice.
01389      */
01390     bitmapqualorig = list_difference_ptr(bitmapqualorig, qpqual);
01391 
01392     /*
01393      * We have to replace any outer-relation variables with nestloop params in
01394      * the qpqual and bitmapqualorig expressions.  (This was already done for
01395      * expressions attached to plan nodes in the bitmapqualplan tree.)
01396      */
01397     if (best_path->path.param_info)
01398     {
01399         qpqual = (List *)
01400             replace_nestloop_params(root, (Node *) qpqual);
01401         bitmapqualorig = (List *)
01402             replace_nestloop_params(root, (Node *) bitmapqualorig);
01403     }
01404 
01405     /* Finally ready to build the plan node */
01406     scan_plan = make_bitmap_heapscan(tlist,
01407                                      qpqual,
01408                                      bitmapqualplan,
01409                                      bitmapqualorig,
01410                                      baserelid);
01411 
01412     copy_path_costsize(&scan_plan->scan.plan, &best_path->path);
01413 
01414     return scan_plan;
01415 }
01416 
01417 /*
01418  * Given a bitmapqual tree, generate the Plan tree that implements it
01419  *
01420  * As byproducts, we also return in *qual and *indexqual the qual lists
01421  * (in implicit-AND form, without RestrictInfos) describing the original index
01422  * conditions and the generated indexqual conditions.  (These are the same in
01423  * simple cases, but when special index operators are involved, the former
01424  * list includes the special conditions while the latter includes the actual
01425  * indexable conditions derived from them.)  Both lists include partial-index
01426  * predicates, because we have to recheck predicates as well as index
01427  * conditions if the bitmap scan becomes lossy.
01428  *
01429  * In addition, we return a list of EquivalenceClass pointers for all the
01430  * top-level indexquals that were possibly-redundantly derived from ECs.
01431  * This allows removal of scan_clauses that are redundant with such quals.
01432  * (We do not attempt to detect such redundancies for quals that are within
01433  * OR subtrees.  This could be done in a less hacky way if we returned the
01434  * indexquals in RestrictInfo form, but that would be slower and still pretty
01435  * messy, since we'd have to build new RestrictInfos in many cases.)
01436  *
01437  * Note: if you find yourself changing this, you probably need to change
01438  * make_restrictinfo_from_bitmapqual too.
01439  */
01440 static Plan *
01441 create_bitmap_subplan(PlannerInfo *root, Path *bitmapqual,
01442                       List **qual, List **indexqual, List **indexECs)
01443 {
01444     Plan       *plan;
01445 
01446     if (IsA(bitmapqual, BitmapAndPath))
01447     {
01448         BitmapAndPath *apath = (BitmapAndPath *) bitmapqual;
01449         List       *subplans = NIL;
01450         List       *subquals = NIL;
01451         List       *subindexquals = NIL;
01452         List       *subindexECs = NIL;
01453         ListCell   *l;
01454 
01455         /*
01456          * There may well be redundant quals among the subplans, since a
01457          * top-level WHERE qual might have gotten used to form several
01458          * different index quals.  We don't try exceedingly hard to eliminate
01459          * redundancies, but we do eliminate obvious duplicates by using
01460          * list_concat_unique.
01461          */
01462         foreach(l, apath->bitmapquals)
01463         {
01464             Plan       *subplan;
01465             List       *subqual;
01466             List       *subindexqual;
01467             List       *subindexEC;
01468 
01469             subplan = create_bitmap_subplan(root, (Path *) lfirst(l),
01470                                             &subqual, &subindexqual,
01471                                             &subindexEC);
01472             subplans = lappend(subplans, subplan);
01473             subquals = list_concat_unique(subquals, subqual);
01474             subindexquals = list_concat_unique(subindexquals, subindexqual);
01475             /* Duplicates in indexECs aren't worth getting rid of */
01476             subindexECs = list_concat(subindexECs, subindexEC);
01477         }
01478         plan = (Plan *) make_bitmap_and(subplans);
01479         plan->startup_cost = apath->path.startup_cost;
01480         plan->total_cost = apath->path.total_cost;
01481         plan->plan_rows =
01482             clamp_row_est(apath->bitmapselectivity * apath->path.parent->tuples);
01483         plan->plan_width = 0;   /* meaningless */
01484         *qual = subquals;
01485         *indexqual = subindexquals;
01486         *indexECs = subindexECs;
01487     }
01488     else if (IsA(bitmapqual, BitmapOrPath))
01489     {
01490         BitmapOrPath *opath = (BitmapOrPath *) bitmapqual;
01491         List       *subplans = NIL;
01492         List       *subquals = NIL;
01493         List       *subindexquals = NIL;
01494         bool        const_true_subqual = false;
01495         bool        const_true_subindexqual = false;
01496         ListCell   *l;
01497 
01498         /*
01499          * Here, we only detect qual-free subplans.  A qual-free subplan would
01500          * cause us to generate "... OR true ..."  which we may as well reduce
01501          * to just "true".  We do not try to eliminate redundant subclauses
01502          * because (a) it's not as likely as in the AND case, and (b) we might
01503          * well be working with hundreds or even thousands of OR conditions,
01504          * perhaps from a long IN list.  The performance of list_append_unique
01505          * would be unacceptable.
01506          */
01507         foreach(l, opath->bitmapquals)
01508         {
01509             Plan       *subplan;
01510             List       *subqual;
01511             List       *subindexqual;
01512             List       *subindexEC;
01513 
01514             subplan = create_bitmap_subplan(root, (Path *) lfirst(l),
01515                                             &subqual, &subindexqual,
01516                                             &subindexEC);
01517             subplans = lappend(subplans, subplan);
01518             if (subqual == NIL)
01519                 const_true_subqual = true;
01520             else if (!const_true_subqual)
01521                 subquals = lappend(subquals,
01522                                    make_ands_explicit(subqual));
01523             if (subindexqual == NIL)
01524                 const_true_subindexqual = true;
01525             else if (!const_true_subindexqual)
01526                 subindexquals = lappend(subindexquals,
01527                                         make_ands_explicit(subindexqual));
01528         }
01529 
01530         /*
01531          * In the presence of ScalarArrayOpExpr quals, we might have built
01532          * BitmapOrPaths with just one subpath; don't add an OR step.
01533          */
01534         if (list_length(subplans) == 1)
01535         {
01536             plan = (Plan *) linitial(subplans);
01537         }
01538         else
01539         {
01540             plan = (Plan *) make_bitmap_or(subplans);
01541             plan->startup_cost = opath->path.startup_cost;
01542             plan->total_cost = opath->path.total_cost;
01543             plan->plan_rows =
01544                 clamp_row_est(opath->bitmapselectivity * opath->path.parent->tuples);
01545             plan->plan_width = 0;       /* meaningless */
01546         }
01547 
01548         /*
01549          * If there were constant-TRUE subquals, the OR reduces to constant
01550          * TRUE.  Also, avoid generating one-element ORs, which could happen
01551          * due to redundancy elimination or ScalarArrayOpExpr quals.
01552          */
01553         if (const_true_subqual)
01554             *qual = NIL;
01555         else if (list_length(subquals) <= 1)
01556             *qual = subquals;
01557         else
01558             *qual = list_make1(make_orclause(subquals));
01559         if (const_true_subindexqual)
01560             *indexqual = NIL;
01561         else if (list_length(subindexquals) <= 1)
01562             *indexqual = subindexquals;
01563         else
01564             *indexqual = list_make1(make_orclause(subindexquals));
01565         *indexECs = NIL;
01566     }
01567     else if (IsA(bitmapqual, IndexPath))
01568     {
01569         IndexPath  *ipath = (IndexPath *) bitmapqual;
01570         IndexScan  *iscan;
01571         List       *subindexECs;
01572         ListCell   *l;
01573 
01574         /* Use the regular indexscan plan build machinery... */
01575         iscan = (IndexScan *) create_indexscan_plan(root, ipath,
01576                                                     NIL, NIL, false);
01577         Assert(IsA(iscan, IndexScan));
01578         /* then convert to a bitmap indexscan */
01579         plan = (Plan *) make_bitmap_indexscan(iscan->scan.scanrelid,
01580                                               iscan->indexid,
01581                                               iscan->indexqual,
01582                                               iscan->indexqualorig);
01583         plan->startup_cost = 0.0;
01584         plan->total_cost = ipath->indextotalcost;
01585         plan->plan_rows =
01586             clamp_row_est(ipath->indexselectivity * ipath->path.parent->tuples);
01587         plan->plan_width = 0;   /* meaningless */
01588         *qual = get_actual_clauses(ipath->indexclauses);
01589         *indexqual = get_actual_clauses(ipath->indexquals);
01590         foreach(l, ipath->indexinfo->indpred)
01591         {
01592             Expr       *pred = (Expr *) lfirst(l);
01593 
01594             /*
01595              * We know that the index predicate must have been implied by the
01596              * query condition as a whole, but it may or may not be implied by
01597              * the conditions that got pushed into the bitmapqual.  Avoid
01598              * generating redundant conditions.
01599              */
01600             if (!predicate_implied_by(list_make1(pred), ipath->indexclauses))
01601             {
01602                 *qual = lappend(*qual, pred);
01603                 *indexqual = lappend(*indexqual, pred);
01604             }
01605         }
01606         subindexECs = NIL;
01607         foreach(l, ipath->indexquals)
01608         {
01609             RestrictInfo *rinfo = (RestrictInfo *) lfirst(l);
01610 
01611             if (rinfo->parent_ec)
01612                 subindexECs = lappend(subindexECs, rinfo->parent_ec);
01613         }
01614         *indexECs = subindexECs;
01615     }
01616     else
01617     {
01618         elog(ERROR, "unrecognized node type: %d", nodeTag(bitmapqual));
01619         plan = NULL;            /* keep compiler quiet */
01620     }
01621 
01622     return plan;
01623 }
01624 
01625 /*
01626  * create_tidscan_plan
01627  *   Returns a tidscan plan for the base relation scanned by 'best_path'
01628  *   with restriction clauses 'scan_clauses' and targetlist 'tlist'.
01629  */
01630 static TidScan *
01631 create_tidscan_plan(PlannerInfo *root, TidPath *best_path,
01632                     List *tlist, List *scan_clauses)
01633 {
01634     TidScan    *scan_plan;
01635     Index       scan_relid = best_path->path.parent->relid;
01636     List       *tidquals = best_path->tidquals;
01637     List       *ortidquals;
01638 
01639     /* it should be a base rel... */
01640     Assert(scan_relid > 0);
01641     Assert(best_path->path.parent->rtekind == RTE_RELATION);
01642 
01643     /* Sort clauses into best execution order */
01644     scan_clauses = order_qual_clauses(root, scan_clauses);
01645 
01646     /* Reduce RestrictInfo list to bare expressions; ignore pseudoconstants */
01647     scan_clauses = extract_actual_clauses(scan_clauses, false);
01648 
01649     /* Replace any outer-relation variables with nestloop params */
01650     if (best_path->path.param_info)
01651     {
01652         tidquals = (List *)
01653             replace_nestloop_params(root, (Node *) tidquals);
01654         scan_clauses = (List *)
01655             replace_nestloop_params(root, (Node *) scan_clauses);
01656     }
01657 
01658     /*
01659      * Remove any clauses that are TID quals.  This is a bit tricky since the
01660      * tidquals list has implicit OR semantics.
01661      */
01662     ortidquals = tidquals;
01663     if (list_length(ortidquals) > 1)
01664         ortidquals = list_make1(make_orclause(ortidquals));
01665     scan_clauses = list_difference(scan_clauses, ortidquals);
01666 
01667     scan_plan = make_tidscan(tlist,
01668                              scan_clauses,
01669                              scan_relid,
01670                              tidquals);
01671 
01672     copy_path_costsize(&scan_plan->scan.plan, &best_path->path);
01673 
01674     return scan_plan;
01675 }
01676 
01677 /*
01678  * create_subqueryscan_plan
01679  *   Returns a subqueryscan plan for the base relation scanned by 'best_path'
01680  *   with restriction clauses 'scan_clauses' and targetlist 'tlist'.
01681  */
01682 static SubqueryScan *
01683 create_subqueryscan_plan(PlannerInfo *root, Path *best_path,
01684                          List *tlist, List *scan_clauses)
01685 {
01686     SubqueryScan *scan_plan;
01687     Index       scan_relid = best_path->parent->relid;
01688 
01689     /* it should be a subquery base rel... */
01690     Assert(scan_relid > 0);
01691     Assert(best_path->parent->rtekind == RTE_SUBQUERY);
01692 
01693     /* Sort clauses into best execution order */
01694     scan_clauses = order_qual_clauses(root, scan_clauses);
01695 
01696     /* Reduce RestrictInfo list to bare expressions; ignore pseudoconstants */
01697     scan_clauses = extract_actual_clauses(scan_clauses, false);
01698 
01699     /* Replace any outer-relation variables with nestloop params */
01700     if (best_path->param_info)
01701     {
01702         scan_clauses = (List *)
01703             replace_nestloop_params(root, (Node *) scan_clauses);
01704         process_subquery_nestloop_params(root,
01705                                          best_path->parent->subplan_params);
01706     }
01707 
01708     scan_plan = make_subqueryscan(tlist,
01709                                   scan_clauses,
01710                                   scan_relid,
01711                                   best_path->parent->subplan);
01712 
01713     copy_path_costsize(&scan_plan->scan.plan, best_path);
01714 
01715     return scan_plan;
01716 }
01717 
01718 /*
01719  * create_functionscan_plan
01720  *   Returns a functionscan plan for the base relation scanned by 'best_path'
01721  *   with restriction clauses 'scan_clauses' and targetlist 'tlist'.
01722  */
01723 static FunctionScan *
01724 create_functionscan_plan(PlannerInfo *root, Path *best_path,
01725                          List *tlist, List *scan_clauses)
01726 {
01727     FunctionScan *scan_plan;
01728     Index       scan_relid = best_path->parent->relid;
01729     RangeTblEntry *rte;
01730     Node       *funcexpr;
01731 
01732     /* it should be a function base rel... */
01733     Assert(scan_relid > 0);
01734     rte = planner_rt_fetch(scan_relid, root);
01735     Assert(rte->rtekind == RTE_FUNCTION);
01736     funcexpr = rte->funcexpr;
01737 
01738     /* Sort clauses into best execution order */
01739     scan_clauses = order_qual_clauses(root, scan_clauses);
01740 
01741     /* Reduce RestrictInfo list to bare expressions; ignore pseudoconstants */
01742     scan_clauses = extract_actual_clauses(scan_clauses, false);
01743 
01744     /* Replace any outer-relation variables with nestloop params */
01745     if (best_path->param_info)
01746     {
01747         scan_clauses = (List *)
01748             replace_nestloop_params(root, (Node *) scan_clauses);
01749         /* The func expression itself could contain nestloop params, too */
01750         funcexpr = replace_nestloop_params(root, funcexpr);
01751     }
01752 
01753     scan_plan = make_functionscan(tlist, scan_clauses, scan_relid,
01754                                   funcexpr,
01755                                   rte->eref->colnames,
01756                                   rte->funccoltypes,
01757                                   rte->funccoltypmods,
01758                                   rte->funccolcollations);
01759 
01760     copy_path_costsize(&scan_plan->scan.plan, best_path);
01761 
01762     return scan_plan;
01763 }
01764 
01765 /*
01766  * create_valuesscan_plan
01767  *   Returns a valuesscan plan for the base relation scanned by 'best_path'
01768  *   with restriction clauses 'scan_clauses' and targetlist 'tlist'.
01769  */
01770 static ValuesScan *
01771 create_valuesscan_plan(PlannerInfo *root, Path *best_path,
01772                        List *tlist, List *scan_clauses)
01773 {
01774     ValuesScan *scan_plan;
01775     Index       scan_relid = best_path->parent->relid;
01776     RangeTblEntry *rte;
01777     List       *values_lists;
01778 
01779     /* it should be a values base rel... */
01780     Assert(scan_relid > 0);
01781     rte = planner_rt_fetch(scan_relid, root);
01782     Assert(rte->rtekind == RTE_VALUES);
01783     values_lists = rte->values_lists;
01784 
01785     /* Sort clauses into best execution order */
01786     scan_clauses = order_qual_clauses(root, scan_clauses);
01787 
01788     /* Reduce RestrictInfo list to bare expressions; ignore pseudoconstants */
01789     scan_clauses = extract_actual_clauses(scan_clauses, false);
01790 
01791     /* Replace any outer-relation variables with nestloop params */
01792     if (best_path->param_info)
01793     {
01794         scan_clauses = (List *)
01795             replace_nestloop_params(root, (Node *) scan_clauses);
01796         /* The values lists could contain nestloop params, too */
01797         values_lists = (List *)
01798             replace_nestloop_params(root, (Node *) values_lists);
01799     }
01800 
01801     scan_plan = make_valuesscan(tlist, scan_clauses, scan_relid,
01802                                 values_lists);
01803 
01804     copy_path_costsize(&scan_plan->scan.plan, best_path);
01805 
01806     return scan_plan;
01807 }
01808 
01809 /*
01810  * create_ctescan_plan
01811  *   Returns a ctescan plan for the base relation scanned by 'best_path'
01812  *   with restriction clauses 'scan_clauses' and targetlist 'tlist'.
01813  */
01814 static CteScan *
01815 create_ctescan_plan(PlannerInfo *root, Path *best_path,
01816                     List *tlist, List *scan_clauses)
01817 {
01818     CteScan    *scan_plan;
01819     Index       scan_relid = best_path->parent->relid;
01820     RangeTblEntry *rte;
01821     SubPlan    *ctesplan = NULL;
01822     int         plan_id;
01823     int         cte_param_id;
01824     PlannerInfo *cteroot;
01825     Index       levelsup;
01826     int         ndx;
01827     ListCell   *lc;
01828 
01829     Assert(scan_relid > 0);
01830     rte = planner_rt_fetch(scan_relid, root);
01831     Assert(rte->rtekind == RTE_CTE);
01832     Assert(!rte->self_reference);
01833 
01834     /*
01835      * Find the referenced CTE, and locate the SubPlan previously made for it.
01836      */
01837     levelsup = rte->ctelevelsup;
01838     cteroot = root;
01839     while (levelsup-- > 0)
01840     {
01841         cteroot = cteroot->parent_root;
01842         if (!cteroot)           /* shouldn't happen */
01843             elog(ERROR, "bad levelsup for CTE \"%s\"", rte->ctename);
01844     }
01845 
01846     /*
01847      * Note: cte_plan_ids can be shorter than cteList, if we are still working
01848      * on planning the CTEs (ie, this is a side-reference from another CTE).
01849      * So we mustn't use forboth here.
01850      */
01851     ndx = 0;
01852     foreach(lc, cteroot->parse->cteList)
01853     {
01854         CommonTableExpr *cte = (CommonTableExpr *) lfirst(lc);
01855 
01856         if (strcmp(cte->ctename, rte->ctename) == 0)
01857             break;
01858         ndx++;
01859     }
01860     if (lc == NULL)             /* shouldn't happen */
01861         elog(ERROR, "could not find CTE \"%s\"", rte->ctename);
01862     if (ndx >= list_length(cteroot->cte_plan_ids))
01863         elog(ERROR, "could not find plan for CTE \"%s\"", rte->ctename);
01864     plan_id = list_nth_int(cteroot->cte_plan_ids, ndx);
01865     Assert(plan_id > 0);
01866     foreach(lc, cteroot->init_plans)
01867     {
01868         ctesplan = (SubPlan *) lfirst(lc);
01869         if (ctesplan->plan_id == plan_id)
01870             break;
01871     }
01872     if (lc == NULL)             /* shouldn't happen */
01873         elog(ERROR, "could not find plan for CTE \"%s\"", rte->ctename);
01874 
01875     /*
01876      * We need the CTE param ID, which is the sole member of the SubPlan's
01877      * setParam list.
01878      */
01879     cte_param_id = linitial_int(ctesplan->setParam);
01880 
01881     /* Sort clauses into best execution order */
01882     scan_clauses = order_qual_clauses(root, scan_clauses);
01883 
01884     /* Reduce RestrictInfo list to bare expressions; ignore pseudoconstants */
01885     scan_clauses = extract_actual_clauses(scan_clauses, false);
01886 
01887     /* Replace any outer-relation variables with nestloop params */
01888     if (best_path->param_info)
01889     {
01890         scan_clauses = (List *)
01891             replace_nestloop_params(root, (Node *) scan_clauses);
01892     }
01893 
01894     scan_plan = make_ctescan(tlist, scan_clauses, scan_relid,
01895                              plan_id, cte_param_id);
01896 
01897     copy_path_costsize(&scan_plan->scan.plan, best_path);
01898 
01899     return scan_plan;
01900 }
01901 
01902 /*
01903  * create_worktablescan_plan
01904  *   Returns a worktablescan plan for the base relation scanned by 'best_path'
01905  *   with restriction clauses 'scan_clauses' and targetlist 'tlist'.
01906  */
01907 static WorkTableScan *
01908 create_worktablescan_plan(PlannerInfo *root, Path *best_path,
01909                           List *tlist, List *scan_clauses)
01910 {
01911     WorkTableScan *scan_plan;
01912     Index       scan_relid = best_path->parent->relid;
01913     RangeTblEntry *rte;
01914     Index       levelsup;
01915     PlannerInfo *cteroot;
01916 
01917     Assert(scan_relid > 0);
01918     rte = planner_rt_fetch(scan_relid, root);
01919     Assert(rte->rtekind == RTE_CTE);
01920     Assert(rte->self_reference);
01921 
01922     /*
01923      * We need to find the worktable param ID, which is in the plan level
01924      * that's processing the recursive UNION, which is one level *below* where
01925      * the CTE comes from.
01926      */
01927     levelsup = rte->ctelevelsup;
01928     if (levelsup == 0)          /* shouldn't happen */
01929         elog(ERROR, "bad levelsup for CTE \"%s\"", rte->ctename);
01930     levelsup--;
01931     cteroot = root;
01932     while (levelsup-- > 0)
01933     {
01934         cteroot = cteroot->parent_root;
01935         if (!cteroot)           /* shouldn't happen */
01936             elog(ERROR, "bad levelsup for CTE \"%s\"", rte->ctename);
01937     }
01938     if (cteroot->wt_param_id < 0)       /* shouldn't happen */
01939         elog(ERROR, "could not find param ID for CTE \"%s\"", rte->ctename);
01940 
01941     /* Sort clauses into best execution order */
01942     scan_clauses = order_qual_clauses(root, scan_clauses);
01943 
01944     /* Reduce RestrictInfo list to bare expressions; ignore pseudoconstants */
01945     scan_clauses = extract_actual_clauses(scan_clauses, false);
01946 
01947     /* Replace any outer-relation variables with nestloop params */
01948     if (best_path->param_info)
01949     {
01950         scan_clauses = (List *)
01951             replace_nestloop_params(root, (Node *) scan_clauses);
01952     }
01953 
01954     scan_plan = make_worktablescan(tlist, scan_clauses, scan_relid,
01955                                    cteroot->wt_param_id);
01956 
01957     copy_path_costsize(&scan_plan->scan.plan, best_path);
01958 
01959     return scan_plan;
01960 }
01961 
01962 /*
01963  * create_foreignscan_plan
01964  *   Returns a foreignscan plan for the base relation scanned by 'best_path'
01965  *   with restriction clauses 'scan_clauses' and targetlist 'tlist'.
01966  */
01967 static ForeignScan *
01968 create_foreignscan_plan(PlannerInfo *root, ForeignPath *best_path,
01969                         List *tlist, List *scan_clauses)
01970 {
01971     ForeignScan *scan_plan;
01972     RelOptInfo *rel = best_path->path.parent;
01973     Index       scan_relid = rel->relid;
01974     RangeTblEntry *rte;
01975     int         i;
01976 
01977     /* it should be a base rel... */
01978     Assert(scan_relid > 0);
01979     Assert(rel->rtekind == RTE_RELATION);
01980     rte = planner_rt_fetch(scan_relid, root);
01981     Assert(rte->rtekind == RTE_RELATION);
01982 
01983     /*
01984      * Sort clauses into best execution order.  We do this first since the FDW
01985      * might have more info than we do and wish to adjust the ordering.
01986      */
01987     scan_clauses = order_qual_clauses(root, scan_clauses);
01988 
01989     /*
01990      * Let the FDW perform its processing on the restriction clauses and
01991      * generate the plan node.  Note that the FDW might remove restriction
01992      * clauses that it intends to execute remotely, or even add more (if it
01993      * has selected some join clauses for remote use but also wants them
01994      * rechecked locally).
01995      */
01996     scan_plan = rel->fdwroutine->GetForeignPlan(root, rel, rte->relid,
01997                                                 best_path,
01998                                                 tlist, scan_clauses);
01999 
02000     /* Copy cost data from Path to Plan; no need to make FDW do this */
02001     copy_path_costsize(&scan_plan->scan.plan, &best_path->path);
02002 
02003     /*
02004      * Replace any outer-relation variables with nestloop params in the qual
02005      * and fdw_exprs expressions.  We do this last so that the FDW doesn't
02006      * have to be involved.  (Note that parts of fdw_exprs could have come
02007      * from join clauses, so doing this beforehand on the scan_clauses
02008      * wouldn't work.)
02009      */
02010     if (best_path->path.param_info)
02011     {
02012         scan_plan->scan.plan.qual = (List *)
02013             replace_nestloop_params(root, (Node *) scan_plan->scan.plan.qual);
02014         scan_plan->fdw_exprs = (List *)
02015             replace_nestloop_params(root, (Node *) scan_plan->fdw_exprs);
02016     }
02017 
02018     /*
02019      * Detect whether any system columns are requested from rel.  This is a
02020      * bit of a kluge and might go away someday, so we intentionally leave it
02021      * out of the API presented to FDWs.
02022      */
02023     scan_plan->fsSystemCol = false;
02024     for (i = rel->min_attr; i < 0; i++)
02025     {
02026         if (!bms_is_empty(rel->attr_needed[i - rel->min_attr]))
02027         {
02028             scan_plan->fsSystemCol = true;
02029             break;
02030         }
02031     }
02032 
02033     return scan_plan;
02034 }
02035 
02036 
02037 /*****************************************************************************
02038  *
02039  *  JOIN METHODS
02040  *
02041  *****************************************************************************/
02042 
02043 static NestLoop *
02044 create_nestloop_plan(PlannerInfo *root,
02045                      NestPath *best_path,
02046                      Plan *outer_plan,
02047                      Plan *inner_plan)
02048 {
02049     NestLoop   *join_plan;
02050     List       *tlist = build_relation_tlist(best_path->path.parent);
02051     List       *joinrestrictclauses = best_path->joinrestrictinfo;
02052     List       *joinclauses;
02053     List       *otherclauses;
02054     Relids      outerrelids;
02055     List       *nestParams;
02056     ListCell   *cell;
02057     ListCell   *prev;
02058     ListCell   *next;
02059 
02060     /* Sort join qual clauses into best execution order */
02061     joinrestrictclauses = order_qual_clauses(root, joinrestrictclauses);
02062 
02063     /* Get the join qual clauses (in plain expression form) */
02064     /* Any pseudoconstant clauses are ignored here */
02065     if (IS_OUTER_JOIN(best_path->jointype))
02066     {
02067         extract_actual_join_clauses(joinrestrictclauses,
02068                                     &joinclauses, &otherclauses);
02069     }
02070     else
02071     {
02072         /* We can treat all clauses alike for an inner join */
02073         joinclauses = extract_actual_clauses(joinrestrictclauses, false);
02074         otherclauses = NIL;
02075     }
02076 
02077     /* Replace any outer-relation variables with nestloop params */
02078     if (best_path->path.param_info)
02079     {
02080         joinclauses = (List *)
02081             replace_nestloop_params(root, (Node *) joinclauses);
02082         otherclauses = (List *)
02083             replace_nestloop_params(root, (Node *) otherclauses);
02084     }
02085 
02086     /*
02087      * Identify any nestloop parameters that should be supplied by this join
02088      * node, and move them from root->curOuterParams to the nestParams list.
02089      */
02090     outerrelids = best_path->outerjoinpath->parent->relids;
02091     nestParams = NIL;
02092     prev = NULL;
02093     for (cell = list_head(root->curOuterParams); cell; cell = next)
02094     {
02095         NestLoopParam *nlp = (NestLoopParam *) lfirst(cell);
02096 
02097         next = lnext(cell);
02098         if (IsA(nlp->paramval, Var) &&
02099             bms_is_member(nlp->paramval->varno, outerrelids))
02100         {
02101             root->curOuterParams = list_delete_cell(root->curOuterParams,
02102                                                     cell, prev);
02103             nestParams = lappend(nestParams, nlp);
02104         }
02105         else if (IsA(nlp->paramval, PlaceHolderVar) &&
02106                  bms_overlap(((PlaceHolderVar *) nlp->paramval)->phrels,
02107                              outerrelids) &&
02108                  bms_is_subset(find_placeholder_info(root,
02109                                             (PlaceHolderVar *) nlp->paramval,
02110                                                      false)->ph_eval_at,
02111                                outerrelids))
02112         {
02113             root->curOuterParams = list_delete_cell(root->curOuterParams,
02114                                                     cell, prev);
02115             nestParams = lappend(nestParams, nlp);
02116         }
02117         else
02118             prev = cell;
02119     }
02120 
02121     join_plan = make_nestloop(tlist,
02122                               joinclauses,
02123                               otherclauses,
02124                               nestParams,
02125                               outer_plan,
02126                               inner_plan,
02127                               best_path->jointype);
02128 
02129     copy_path_costsize(&join_plan->join.plan, &best_path->path);
02130 
02131     return join_plan;
02132 }
02133 
02134 static MergeJoin *
02135 create_mergejoin_plan(PlannerInfo *root,
02136                       MergePath *best_path,
02137                       Plan *outer_plan,
02138                       Plan *inner_plan)
02139 {
02140     List       *tlist = build_relation_tlist(best_path->jpath.path.parent);
02141     List       *joinclauses;
02142     List       *otherclauses;
02143     List       *mergeclauses;
02144     List       *outerpathkeys;
02145     List       *innerpathkeys;
02146     int         nClauses;
02147     Oid        *mergefamilies;
02148     Oid        *mergecollations;
02149     int        *mergestrategies;
02150     bool       *mergenullsfirst;
02151     MergeJoin  *join_plan;
02152     int         i;
02153     ListCell   *lc;
02154     ListCell   *lop;
02155     ListCell   *lip;
02156 
02157     /* Sort join qual clauses into best execution order */
02158     /* NB: do NOT reorder the mergeclauses */
02159     joinclauses = order_qual_clauses(root, best_path->jpath.joinrestrictinfo);
02160 
02161     /* Get the join qual clauses (in plain expression form) */
02162     /* Any pseudoconstant clauses are ignored here */
02163     if (IS_OUTER_JOIN(best_path->jpath.jointype))
02164     {
02165         extract_actual_join_clauses(joinclauses,
02166                                     &joinclauses, &otherclauses);
02167     }
02168     else
02169     {
02170         /* We can treat all clauses alike for an inner join */
02171         joinclauses = extract_actual_clauses(joinclauses, false);
02172         otherclauses = NIL;
02173     }
02174 
02175     /*
02176      * Remove the mergeclauses from the list of join qual clauses, leaving the
02177      * list of quals that must be checked as qpquals.
02178      */
02179     mergeclauses = get_actual_clauses(best_path->path_mergeclauses);
02180     joinclauses = list_difference(joinclauses, mergeclauses);
02181 
02182     /*
02183      * Replace any outer-relation variables with nestloop params.  There
02184      * should not be any in the mergeclauses.
02185      */
02186     if (best_path->jpath.path.param_info)
02187     {
02188         joinclauses = (List *)
02189             replace_nestloop_params(root, (Node *) joinclauses);
02190         otherclauses = (List *)
02191             replace_nestloop_params(root, (Node *) otherclauses);
02192     }
02193 
02194     /*
02195      * Rearrange mergeclauses, if needed, so that the outer variable is always
02196      * on the left; mark the mergeclause restrictinfos with correct
02197      * outer_is_left status.
02198      */
02199     mergeclauses = get_switched_clauses(best_path->path_mergeclauses,
02200                              best_path->jpath.outerjoinpath->parent->relids);
02201 
02202     /*
02203      * Create explicit sort nodes for the outer and inner paths if necessary.
02204      * Make sure there are no excess columns in the inputs if sorting.
02205      */
02206     if (best_path->outersortkeys)
02207     {
02208         disuse_physical_tlist(outer_plan, best_path->jpath.outerjoinpath);
02209         outer_plan = (Plan *)
02210             make_sort_from_pathkeys(root,
02211                                     outer_plan,
02212                                     best_path->outersortkeys,
02213                                     -1.0);
02214         outerpathkeys = best_path->outersortkeys;
02215     }
02216     else
02217         outerpathkeys = best_path->jpath.outerjoinpath->pathkeys;
02218 
02219     if (best_path->innersortkeys)
02220     {
02221         disuse_physical_tlist(inner_plan, best_path->jpath.innerjoinpath);
02222         inner_plan = (Plan *)
02223             make_sort_from_pathkeys(root,
02224                                     inner_plan,
02225                                     best_path->innersortkeys,
02226                                     -1.0);
02227         innerpathkeys = best_path->innersortkeys;
02228     }
02229     else
02230         innerpathkeys = best_path->jpath.innerjoinpath->pathkeys;
02231 
02232     /*
02233      * If specified, add a materialize node to shield the inner plan from the
02234      * need to handle mark/restore.
02235      */
02236     if (best_path->materialize_inner)
02237     {
02238         Plan       *matplan = (Plan *) make_material(inner_plan);
02239 
02240         /*
02241          * We assume the materialize will not spill to disk, and therefore
02242          * charge just cpu_operator_cost per tuple.  (Keep this estimate in
02243          * sync with final_cost_mergejoin.)
02244          */
02245         copy_plan_costsize(matplan, inner_plan);
02246         matplan->total_cost += cpu_operator_cost * matplan->plan_rows;
02247 
02248         inner_plan = matplan;
02249     }
02250 
02251     /*
02252      * Compute the opfamily/collation/strategy/nullsfirst arrays needed by the
02253      * executor.  The information is in the pathkeys for the two inputs, but
02254      * we need to be careful about the possibility of mergeclauses sharing a
02255      * pathkey (compare find_mergeclauses_for_pathkeys()).
02256      */
02257     nClauses = list_length(mergeclauses);
02258     Assert(nClauses == list_length(best_path->path_mergeclauses));
02259     mergefamilies = (Oid *) palloc(nClauses * sizeof(Oid));
02260     mergecollations = (Oid *) palloc(nClauses * sizeof(Oid));
02261     mergestrategies = (int *) palloc(nClauses * sizeof(int));
02262     mergenullsfirst = (bool *) palloc(nClauses * sizeof(bool));
02263 
02264     lop = list_head(outerpathkeys);
02265     lip = list_head(innerpathkeys);
02266     i = 0;
02267     foreach(lc, best_path->path_mergeclauses)
02268     {
02269         RestrictInfo *rinfo = (RestrictInfo *) lfirst(lc);
02270         EquivalenceClass *oeclass;
02271         EquivalenceClass *ieclass;
02272         PathKey    *opathkey;
02273         PathKey    *ipathkey;
02274         EquivalenceClass *opeclass;
02275         EquivalenceClass *ipeclass;
02276         ListCell   *l2;
02277 
02278         /* fetch outer/inner eclass from mergeclause */
02279         Assert(IsA(rinfo, RestrictInfo));
02280         if (rinfo->outer_is_left)
02281         {
02282             oeclass = rinfo->left_ec;
02283             ieclass = rinfo->right_ec;
02284         }
02285         else
02286         {
02287             oeclass = rinfo->right_ec;
02288             ieclass = rinfo->left_ec;
02289         }
02290         Assert(oeclass != NULL);
02291         Assert(ieclass != NULL);
02292 
02293         /*
02294          * For debugging purposes, we check that the eclasses match the paths'
02295          * pathkeys.  In typical cases the merge clauses are one-to-one with
02296          * the pathkeys, but when dealing with partially redundant query
02297          * conditions, we might have clauses that re-reference earlier path
02298          * keys.  The case that we need to reject is where a pathkey is
02299          * entirely skipped over.
02300          *
02301          * lop and lip reference the first as-yet-unused pathkey elements;
02302          * it's okay to match them, or any element before them.  If they're
02303          * NULL then we have found all pathkey elements to be used.
02304          */
02305         if (lop)
02306         {
02307             opathkey = (PathKey *) lfirst(lop);
02308             opeclass = opathkey->pk_eclass;
02309             if (oeclass == opeclass)
02310             {
02311                 /* fast path for typical case */
02312                 lop = lnext(lop);
02313             }
02314             else
02315             {
02316                 /* redundant clauses ... must match something before lop */
02317                 foreach(l2, outerpathkeys)
02318                 {
02319                     if (l2 == lop)
02320                         break;
02321                     opathkey = (PathKey *) lfirst(l2);
02322                     opeclass = opathkey->pk_eclass;
02323                     if (oeclass == opeclass)
02324                         break;
02325                 }
02326                 if (oeclass != opeclass)
02327                     elog(ERROR, "outer pathkeys do not match mergeclauses");
02328             }
02329         }
02330         else
02331         {
02332             /* redundant clauses ... must match some already-used pathkey */
02333             opathkey = NULL;
02334             opeclass = NULL;
02335             foreach(l2, outerpathkeys)
02336             {
02337                 opathkey = (PathKey *) lfirst(l2);
02338                 opeclass = opathkey->pk_eclass;
02339                 if (oeclass == opeclass)
02340                     break;
02341             }
02342             if (l2 == NULL)
02343                 elog(ERROR, "outer pathkeys do not match mergeclauses");
02344         }
02345 
02346         if (lip)
02347         {
02348             ipathkey = (PathKey *) lfirst(lip);
02349             ipeclass = ipathkey->pk_eclass;
02350             if (ieclass == ipeclass)
02351             {
02352                 /* fast path for typical case */
02353                 lip = lnext(lip);
02354             }
02355             else
02356             {
02357                 /* redundant clauses ... must match something before lip */
02358                 foreach(l2, innerpathkeys)
02359                 {
02360                     if (l2 == lip)
02361                         break;
02362                     ipathkey = (PathKey *) lfirst(l2);
02363                     ipeclass = ipathkey->pk_eclass;
02364                     if (ieclass == ipeclass)
02365                         break;
02366                 }
02367                 if (ieclass != ipeclass)
02368                     elog(ERROR, "inner pathkeys do not match mergeclauses");
02369             }
02370         }
02371         else
02372         {
02373             /* redundant clauses ... must match some already-used pathkey */
02374             ipathkey = NULL;
02375             ipeclass = NULL;
02376             foreach(l2, innerpathkeys)
02377             {
02378                 ipathkey = (PathKey *) lfirst(l2);
02379                 ipeclass = ipathkey->pk_eclass;
02380                 if (ieclass == ipeclass)
02381                     break;
02382             }
02383             if (l2 == NULL)
02384                 elog(ERROR, "inner pathkeys do not match mergeclauses");
02385         }
02386 
02387         /* pathkeys should match each other too (more debugging) */
02388         if (opathkey->pk_opfamily != ipathkey->pk_opfamily ||
02389             opathkey->pk_eclass->ec_collation != ipathkey->pk_eclass->ec_collation ||
02390             opathkey->pk_strategy != ipathkey->pk_strategy ||
02391             opathkey->pk_nulls_first != ipathkey->pk_nulls_first)
02392             elog(ERROR, "left and right pathkeys do not match in mergejoin");
02393 
02394         /* OK, save info for executor */
02395         mergefamilies[i] = opathkey->pk_opfamily;
02396         mergecollations[i] = opathkey->pk_eclass->ec_collation;
02397         mergestrategies[i] = opathkey->pk_strategy;
02398         mergenullsfirst[i] = opathkey->pk_nulls_first;
02399         i++;
02400     }
02401 
02402     /*
02403      * Note: it is not an error if we have additional pathkey elements (i.e.,
02404      * lop or lip isn't NULL here).  The input paths might be better-sorted
02405      * than we need for the current mergejoin.
02406      */
02407 
02408     /*
02409      * Now we can build the mergejoin node.
02410      */
02411     join_plan = make_mergejoin(tlist,
02412                                joinclauses,
02413                                otherclauses,
02414                                mergeclauses,
02415                                mergefamilies,
02416                                mergecollations,
02417                                mergestrategies,
02418                                mergenullsfirst,
02419                                outer_plan,
02420                                inner_plan,
02421                                best_path->jpath.jointype);
02422 
02423     /* Costs of sort and material steps are included in path cost already */
02424     copy_path_costsize(&join_plan->join.plan, &best_path->jpath.path);
02425 
02426     return join_plan;
02427 }
02428 
02429 static HashJoin *
02430 create_hashjoin_plan(PlannerInfo *root,
02431                      HashPath *best_path,
02432                      Plan *outer_plan,
02433                      Plan *inner_plan)
02434 {
02435     List       *tlist = build_relation_tlist(best_path->jpath.path.parent);
02436     List       *joinclauses;
02437     List       *otherclauses;
02438     List       *hashclauses;
02439     Oid         skewTable = InvalidOid;
02440     AttrNumber  skewColumn = InvalidAttrNumber;
02441     bool        skewInherit = false;
02442     Oid         skewColType = InvalidOid;
02443     int32       skewColTypmod = -1;
02444     HashJoin   *join_plan;
02445     Hash       *hash_plan;
02446 
02447     /* Sort join qual clauses into best execution order */
02448     joinclauses = order_qual_clauses(root, best_path->jpath.joinrestrictinfo);
02449     /* There's no point in sorting the hash clauses ... */
02450 
02451     /* Get the join qual clauses (in plain expression form) */
02452     /* Any pseudoconstant clauses are ignored here */
02453     if (IS_OUTER_JOIN(best_path->jpath.jointype))
02454     {
02455         extract_actual_join_clauses(joinclauses,
02456                                     &joinclauses, &otherclauses);
02457     }
02458     else
02459     {
02460         /* We can treat all clauses alike for an inner join */
02461         joinclauses = extract_actual_clauses(joinclauses, false);
02462         otherclauses = NIL;
02463     }
02464 
02465     /*
02466      * Remove the hashclauses from the list of join qual clauses, leaving the
02467      * list of quals that must be checked as qpquals.
02468      */
02469     hashclauses = get_actual_clauses(best_path->path_hashclauses);
02470     joinclauses = list_difference(joinclauses, hashclauses);
02471 
02472     /*
02473      * Replace any outer-relation variables with nestloop params.  There
02474      * should not be any in the hashclauses.
02475      */
02476     if (best_path->jpath.path.param_info)
02477     {
02478         joinclauses = (List *)
02479             replace_nestloop_params(root, (Node *) joinclauses);
02480         otherclauses = (List *)
02481             replace_nestloop_params(root, (Node *) otherclauses);
02482     }
02483 
02484     /*
02485      * Rearrange hashclauses, if needed, so that the outer variable is always
02486      * on the left.
02487      */
02488     hashclauses = get_switched_clauses(best_path->path_hashclauses,
02489                              best_path->jpath.outerjoinpath->parent->relids);
02490 
02491     /* We don't want any excess columns in the hashed tuples */
02492     disuse_physical_tlist(inner_plan, best_path->jpath.innerjoinpath);
02493 
02494     /* If we expect batching, suppress excess columns in outer tuples too */
02495     if (best_path->num_batches > 1)
02496         disuse_physical_tlist(outer_plan, best_path->jpath.outerjoinpath);
02497 
02498     /*
02499      * If there is a single join clause and we can identify the outer variable
02500      * as a simple column reference, supply its identity for possible use in
02501      * skew optimization.  (Note: in principle we could do skew optimization
02502      * with multiple join clauses, but we'd have to be able to determine the
02503      * most common combinations of outer values, which we don't currently have
02504      * enough stats for.)
02505      */
02506     if (list_length(hashclauses) == 1)
02507     {
02508         OpExpr     *clause = (OpExpr *) linitial(hashclauses);
02509         Node       *node;
02510 
02511         Assert(is_opclause(clause));
02512         node = (Node *) linitial(clause->args);
02513         if (IsA(node, RelabelType))
02514             node = (Node *) ((RelabelType *) node)->arg;
02515         if (IsA(node, Var))
02516         {
02517             Var        *var = (Var *) node;
02518             RangeTblEntry *rte;
02519 
02520             rte = root->simple_rte_array[var->varno];
02521             if (rte->rtekind == RTE_RELATION)
02522             {
02523                 skewTable = rte->relid;
02524                 skewColumn = var->varattno;
02525                 skewInherit = rte->inh;
02526                 skewColType = var->vartype;
02527                 skewColTypmod = var->vartypmod;
02528             }
02529         }
02530     }
02531 
02532     /*
02533      * Build the hash node and hash join node.
02534      */
02535     hash_plan = make_hash(inner_plan,
02536                           skewTable,
02537                           skewColumn,
02538                           skewInherit,
02539                           skewColType,
02540                           skewColTypmod);
02541     join_plan = make_hashjoin(tlist,
02542                               joinclauses,
02543                               otherclauses,
02544                               hashclauses,
02545                               outer_plan,
02546                               (Plan *) hash_plan,
02547                               best_path->jpath.jointype);
02548 
02549     copy_path_costsize(&join_plan->join.plan, &best_path->jpath.path);
02550 
02551     return join_plan;
02552 }
02553 
02554 
02555 /*****************************************************************************
02556  *
02557  *  SUPPORTING ROUTINES
02558  *
02559  *****************************************************************************/
02560 
02561 /*
02562  * replace_nestloop_params
02563  *    Replace outer-relation Vars and PlaceHolderVars in the given expression
02564  *    with nestloop Params
02565  *
02566  * All Vars and PlaceHolderVars belonging to the relation(s) identified by
02567  * root->curOuterRels are replaced by Params, and entries are added to
02568  * root->curOuterParams if not already present.
02569  */
02570 static Node *
02571 replace_nestloop_params(PlannerInfo *root, Node *expr)
02572 {
02573     /* No setup needed for tree walk, so away we go */
02574     return replace_nestloop_params_mutator(expr, root);
02575 }
02576 
02577 static Node *
02578 replace_nestloop_params_mutator(Node *node, PlannerInfo *root)
02579 {
02580     if (node == NULL)
02581         return NULL;
02582     if (IsA(node, Var))
02583     {
02584         Var        *var = (Var *) node;
02585         Param      *param;
02586         NestLoopParam *nlp;
02587         ListCell   *lc;
02588 
02589         /* Upper-level Vars should be long gone at this point */
02590         Assert(var->varlevelsup == 0);
02591         /* If not to be replaced, we can just return the Var unmodified */
02592         if (!bms_is_member(var->varno, root->curOuterRels))
02593             return node;
02594         /* Create a Param representing the Var */
02595         param = assign_nestloop_param_var(root, var);
02596         /* Is this param already listed in root->curOuterParams? */
02597         foreach(lc, root->curOuterParams)
02598         {
02599             nlp = (NestLoopParam *) lfirst(lc);
02600             if (nlp->paramno == param->paramid)
02601             {
02602                 Assert(equal(var, nlp->paramval));
02603                 /* Present, so we can just return the Param */
02604                 return (Node *) param;
02605             }
02606         }
02607         /* No, so add it */
02608         nlp = makeNode(NestLoopParam);
02609         nlp->paramno = param->paramid;
02610         nlp->paramval = var;
02611         root->curOuterParams = lappend(root->curOuterParams, nlp);
02612         /* And return the replacement Param */
02613         return (Node *) param;
02614     }
02615     if (IsA(node, PlaceHolderVar))
02616     {
02617         PlaceHolderVar *phv = (PlaceHolderVar *) node;
02618         Param      *param;
02619         NestLoopParam *nlp;
02620         ListCell   *lc;
02621 
02622         /* Upper-level PlaceHolderVars should be long gone at this point */
02623         Assert(phv->phlevelsup == 0);
02624 
02625         /*
02626          * If not to be replaced, just return the PlaceHolderVar unmodified.
02627          * We use bms_overlap as a cheap/quick test to see if the PHV might be
02628          * evaluated in the outer rels, and then grab its PlaceHolderInfo to
02629          * tell for sure.
02630          */
02631         if (!bms_overlap(phv->phrels, root->curOuterRels))
02632             return node;
02633         if (!bms_is_subset(find_placeholder_info(root, phv, false)->ph_eval_at,
02634                            root->curOuterRels))
02635             return node;
02636         /* Create a Param representing the PlaceHolderVar */
02637         param = assign_nestloop_param_placeholdervar(root, phv);
02638         /* Is this param already listed in root->curOuterParams? */
02639         foreach(lc, root->curOuterParams)
02640         {
02641             nlp = (NestLoopParam *) lfirst(lc);
02642             if (nlp->paramno == param->paramid)
02643             {
02644                 Assert(equal(phv, nlp->paramval));
02645                 /* Present, so we can just return the Param */
02646                 return (Node *) param;
02647             }
02648         }
02649         /* No, so add it */
02650         nlp = makeNode(NestLoopParam);
02651         nlp->paramno = param->paramid;
02652         nlp->paramval = (Var *) phv;
02653         root->curOuterParams = lappend(root->curOuterParams, nlp);
02654         /* And return the replacement Param */
02655         return (Node *) param;
02656     }
02657     return expression_tree_mutator(node,
02658                                    replace_nestloop_params_mutator,
02659                                    (void *) root);
02660 }
02661 
02662 /*
02663  * process_subquery_nestloop_params
02664  *    Handle params of a parameterized subquery that need to be fed
02665  *    from an outer nestloop.
02666  *
02667  * Currently, that would be *all* params that a subquery in FROM has demanded
02668  * from the current query level, since they must be LATERAL references.
02669  *
02670  * The subplan's references to the outer variables are already represented
02671  * as PARAM_EXEC Params, so we need not modify the subplan here.  What we
02672  * do need to do is add entries to root->curOuterParams to signal the parent
02673  * nestloop plan node that it must provide these values.
02674  */
02675 static void
02676 process_subquery_nestloop_params(PlannerInfo *root, List *subplan_params)
02677 {
02678     ListCell   *ppl;
02679 
02680     foreach(ppl, subplan_params)
02681     {
02682         PlannerParamItem *pitem = (PlannerParamItem *) lfirst(ppl);
02683 
02684         if (IsA(pitem->item, Var))
02685         {
02686             Var        *var = (Var *) pitem->item;
02687             NestLoopParam *nlp;
02688             ListCell   *lc;
02689 
02690             /* If not from a nestloop outer rel, complain */
02691             if (!bms_is_member(var->varno, root->curOuterRels))
02692                 elog(ERROR, "non-LATERAL parameter required by subquery");
02693             /* Is this param already listed in root->curOuterParams? */
02694             foreach(lc, root->curOuterParams)
02695             {
02696                 nlp = (NestLoopParam *) lfirst(lc);
02697                 if (nlp->paramno == pitem->paramId)
02698                 {
02699                     Assert(equal(var, nlp->paramval));
02700                     /* Present, so nothing to do */
02701                     break;
02702                 }
02703             }
02704             if (lc == NULL)
02705             {
02706                 /* No, so add it */
02707                 nlp = makeNode(NestLoopParam);
02708                 nlp->paramno = pitem->paramId;
02709                 nlp->paramval = copyObject(var);
02710                 root->curOuterParams = lappend(root->curOuterParams, nlp);
02711             }
02712         }
02713         else if (IsA(pitem->item, PlaceHolderVar))
02714         {
02715             PlaceHolderVar *phv = (PlaceHolderVar *) pitem->item;
02716             NestLoopParam *nlp;
02717             ListCell   *lc;
02718 
02719             /* If not from a nestloop outer rel, complain */
02720             if (!bms_is_subset(find_placeholder_info(root, phv, false)->ph_eval_at,
02721                                root->curOuterRels))
02722                 elog(ERROR, "non-LATERAL parameter required by subquery");
02723             /* Is this param already listed in root->curOuterParams? */
02724             foreach(lc, root->curOuterParams)
02725             {
02726                 nlp = (NestLoopParam *) lfirst(lc);
02727                 if (nlp->paramno == pitem->paramId)
02728                 {
02729                     Assert(equal(phv, nlp->paramval));
02730                     /* Present, so nothing to do */
02731                     break;
02732                 }
02733             }
02734             if (lc == NULL)
02735             {
02736                 /* No, so add it */
02737                 nlp = makeNode(NestLoopParam);
02738                 nlp->paramno = pitem->paramId;
02739                 nlp->paramval = copyObject(phv);
02740                 root->curOuterParams = lappend(root->curOuterParams, nlp);
02741             }
02742         }
02743         else
02744             elog(ERROR, "unexpected type of subquery parameter");
02745     }
02746 }
02747 
02748 /*
02749  * fix_indexqual_references
02750  *    Adjust indexqual clauses to the form the executor's indexqual
02751  *    machinery needs.
02752  *
02753  * We have four tasks here:
02754  *  * Remove RestrictInfo nodes from the input clauses.
02755  *  * Replace any outer-relation Var or PHV nodes with nestloop Params.
02756  *    (XXX eventually, that responsibility should go elsewhere?)
02757  *  * Index keys must be represented by Var nodes with varattno set to the
02758  *    index's attribute number, not the attribute number in the original rel.
02759  *  * If the index key is on the right, commute the clause to put it on the
02760  *    left.
02761  *
02762  * The result is a modified copy of the path's indexquals list --- the
02763  * original is not changed.  Note also that the copy shares no substructure
02764  * with the original; this is needed in case there is a subplan in it (we need
02765  * two separate copies of the subplan tree, or things will go awry).
02766  */
02767 static List *
02768 fix_indexqual_references(PlannerInfo *root, IndexPath *index_path)
02769 {
02770     IndexOptInfo *index = index_path->indexinfo;
02771     List       *fixed_indexquals;
02772     ListCell   *lcc,
02773                *lci;
02774 
02775     fixed_indexquals = NIL;
02776 
02777     forboth(lcc, index_path->indexquals, lci, index_path->indexqualcols)
02778     {
02779         RestrictInfo *rinfo = (RestrictInfo *) lfirst(lcc);
02780         int         indexcol = lfirst_int(lci);
02781         Node       *clause;
02782 
02783         Assert(IsA(rinfo, RestrictInfo));
02784 
02785         /*
02786          * Replace any outer-relation variables with nestloop params.
02787          *
02788          * This also makes a copy of the clause, so it's safe to modify it
02789          * in-place below.
02790          */
02791         clause = replace_nestloop_params(root, (Node *) rinfo->clause);
02792 
02793         if (IsA(clause, OpExpr))
02794         {
02795             OpExpr     *op = (OpExpr *) clause;
02796 
02797             if (list_length(op->args) != 2)
02798                 elog(ERROR, "indexqual clause is not binary opclause");
02799 
02800             /*
02801              * Check to see if the indexkey is on the right; if so, commute
02802              * the clause.  The indexkey should be the side that refers to
02803              * (only) the base relation.
02804              */
02805             if (!bms_equal(rinfo->left_relids, index->rel->relids))
02806                 CommuteOpExpr(op);
02807 
02808             /*
02809              * Now replace the indexkey expression with an index Var.
02810              */
02811             linitial(op->args) = fix_indexqual_operand(linitial(op->args),
02812                                                        index,
02813                                                        indexcol);
02814         }
02815         else if (IsA(clause, RowCompareExpr))
02816         {
02817             RowCompareExpr *rc = (RowCompareExpr *) clause;
02818             Expr       *newrc;
02819             List       *indexcolnos;
02820             bool        var_on_left;
02821             ListCell   *lca,
02822                        *lcai;
02823 
02824             /*
02825              * Re-discover which index columns are used in the rowcompare.
02826              */
02827             newrc = adjust_rowcompare_for_index(rc,
02828                                                 index,
02829                                                 indexcol,
02830                                                 &indexcolnos,
02831                                                 &var_on_left);
02832 
02833             /*
02834              * Trouble if adjust_rowcompare_for_index thought the
02835              * RowCompareExpr didn't match the index as-is; the clause should
02836              * have gone through that routine already.
02837              */
02838             if (newrc != (Expr *) rc)
02839                 elog(ERROR, "inconsistent results from adjust_rowcompare_for_index");
02840 
02841             /*
02842              * Check to see if the indexkey is on the right; if so, commute
02843              * the clause.
02844              */
02845             if (!var_on_left)
02846                 CommuteRowCompareExpr(rc);
02847 
02848             /*
02849              * Now replace the indexkey expressions with index Vars.
02850              */
02851             Assert(list_length(rc->largs) == list_length(indexcolnos));
02852             forboth(lca, rc->largs, lcai, indexcolnos)
02853             {
02854                 lfirst(lca) = fix_indexqual_operand(lfirst(lca),
02855                                                     index,
02856                                                     lfirst_int(lcai));
02857             }
02858         }
02859         else if (IsA(clause, ScalarArrayOpExpr))
02860         {
02861             ScalarArrayOpExpr *saop = (ScalarArrayOpExpr *) clause;
02862 
02863             /* Never need to commute... */
02864 
02865             /* Replace the indexkey expression with an index Var. */
02866             linitial(saop->args) = fix_indexqual_operand(linitial(saop->args),
02867                                                          index,
02868                                                          indexcol);
02869         }
02870         else if (IsA(clause, NullTest))
02871         {
02872             NullTest   *nt = (NullTest *) clause;
02873 
02874             /* Replace the indexkey expression with an index Var. */
02875             nt->arg = (Expr *) fix_indexqual_operand((Node *) nt->arg,
02876                                                      index,
02877                                                      indexcol);
02878         }
02879         else
02880             elog(ERROR, "unsupported indexqual type: %d",
02881                  (int) nodeTag(clause));
02882 
02883         fixed_indexquals = lappend(fixed_indexquals, clause);
02884     }
02885 
02886     return fixed_indexquals;
02887 }
02888 
02889 /*
02890  * fix_indexorderby_references
02891  *    Adjust indexorderby clauses to the form the executor's index
02892  *    machinery needs.
02893  *
02894  * This is a simplified version of fix_indexqual_references.  The input does
02895  * not have RestrictInfo nodes, and we assume that indxpath.c already
02896  * commuted the clauses to put the index keys on the left.  Also, we don't
02897  * bother to support any cases except simple OpExprs, since nothing else
02898  * is allowed for ordering operators.
02899  */
02900 static List *
02901 fix_indexorderby_references(PlannerInfo *root, IndexPath *index_path)
02902 {
02903     IndexOptInfo *index = index_path->indexinfo;
02904     List       *fixed_indexorderbys;
02905     ListCell   *lcc,
02906                *lci;
02907 
02908     fixed_indexorderbys = NIL;
02909 
02910     forboth(lcc, index_path->indexorderbys, lci, index_path->indexorderbycols)
02911     {
02912         Node       *clause = (Node *) lfirst(lcc);
02913         int         indexcol = lfirst_int(lci);
02914 
02915         /*
02916          * Replace any outer-relation variables with nestloop params.
02917          *
02918          * This also makes a copy of the clause, so it's safe to modify it
02919          * in-place below.
02920          */
02921         clause = replace_nestloop_params(root, clause);
02922 
02923         if (IsA(clause, OpExpr))
02924         {
02925             OpExpr     *op = (OpExpr *) clause;
02926 
02927             if (list_length(op->args) != 2)
02928                 elog(ERROR, "indexorderby clause is not binary opclause");
02929 
02930             /*
02931              * Now replace the indexkey expression with an index Var.
02932              */
02933             linitial(op->args) = fix_indexqual_operand(linitial(op->args),
02934                                                        index,
02935                                                        indexcol);
02936         }
02937         else
02938             elog(ERROR, "unsupported indexorderby type: %d",
02939                  (int) nodeTag(clause));
02940 
02941         fixed_indexorderbys = lappend(fixed_indexorderbys, clause);
02942     }
02943 
02944     return fixed_indexorderbys;
02945 }
02946 
02947 /*
02948  * fix_indexqual_operand
02949  *    Convert an indexqual expression to a Var referencing the index column.
02950  *
02951  * We represent index keys by Var nodes having varno == INDEX_VAR and varattno
02952  * equal to the index's attribute number (index column position).
02953  *
02954  * Most of the code here is just for sanity cross-checking that the given
02955  * expression actually matches the index column it's claimed to.
02956  */
02957 static Node *
02958 fix_indexqual_operand(Node *node, IndexOptInfo *index, int indexcol)
02959 {
02960     Var        *result;
02961     int         pos;
02962     ListCell   *indexpr_item;
02963 
02964     /*
02965      * Remove any binary-compatible relabeling of the indexkey
02966      */
02967     if (IsA(node, RelabelType))
02968         node = (Node *) ((RelabelType *) node)->arg;
02969 
02970     Assert(indexcol >= 0 && indexcol < index->ncolumns);
02971 
02972     if (index->indexkeys[indexcol] != 0)
02973     {
02974         /* It's a simple index column */
02975         if (IsA(node, Var) &&
02976             ((Var *) node)->varno == index->rel->relid &&
02977             ((Var *) node)->varattno == index->indexkeys[indexcol])
02978         {
02979             result = (Var *) copyObject(node);
02980             result->varno = INDEX_VAR;
02981             result->varattno = indexcol + 1;
02982             return (Node *) result;
02983         }
02984         else
02985             elog(ERROR, "index key does not match expected index column");
02986     }
02987 
02988     /* It's an index expression, so find and cross-check the expression */
02989     indexpr_item = list_head(index->indexprs);
02990     for (pos = 0; pos < index->ncolumns; pos++)
02991     {
02992         if (index->indexkeys[pos] == 0)
02993         {
02994             if (indexpr_item == NULL)
02995                 elog(ERROR, "too few entries in indexprs list");
02996             if (pos == indexcol)
02997             {
02998                 Node       *indexkey;
02999 
03000                 indexkey = (Node *) lfirst(indexpr_item);
03001                 if (indexkey && IsA(indexkey, RelabelType))
03002                     indexkey = (Node *) ((RelabelType *) indexkey)->arg;
03003                 if (equal(node, indexkey))
03004                 {
03005                     result = makeVar(INDEX_VAR, indexcol + 1,
03006                                      exprType(lfirst(indexpr_item)), -1,
03007                                      exprCollation(lfirst(indexpr_item)),
03008                                      0);
03009                     return (Node *) result;
03010                 }
03011                 else
03012                     elog(ERROR, "index key does not match expected index column");
03013             }
03014             indexpr_item = lnext(indexpr_item);
03015         }
03016     }
03017 
03018     /* Ooops... */
03019     elog(ERROR, "index key does not match expected index column");
03020     return NULL;                /* keep compiler quiet */
03021 }
03022 
03023 /*
03024  * get_switched_clauses
03025  *    Given a list of merge or hash joinclauses (as RestrictInfo nodes),
03026  *    extract the bare clauses, and rearrange the elements within the
03027  *    clauses, if needed, so the outer join variable is on the left and
03028  *    the inner is on the right.  The original clause data structure is not
03029  *    touched; a modified list is returned.  We do, however, set the transient
03030  *    outer_is_left field in each RestrictInfo to show which side was which.
03031  */
03032 static List *
03033 get_switched_clauses(List *clauses, Relids outerrelids)
03034 {
03035     List       *t_list = NIL;
03036     ListCell   *l;
03037 
03038     foreach(l, clauses)
03039     {
03040         RestrictInfo *restrictinfo = (RestrictInfo *) lfirst(l);
03041         OpExpr     *clause = (OpExpr *) restrictinfo->clause;
03042 
03043         Assert(is_opclause(clause));
03044         if (bms_is_subset(restrictinfo->right_relids, outerrelids))
03045         {
03046             /*
03047              * Duplicate just enough of the structure to allow commuting the
03048              * clause without changing the original list.  Could use
03049              * copyObject, but a complete deep copy is overkill.
03050              */
03051             OpExpr     *temp = makeNode(OpExpr);
03052 
03053             temp->opno = clause->opno;
03054             temp->opfuncid = InvalidOid;
03055             temp->opresulttype = clause->opresulttype;
03056             temp->opretset = clause->opretset;
03057             temp->opcollid = clause->opcollid;
03058             temp->inputcollid = clause->inputcollid;
03059             temp->args = list_copy(clause->args);
03060             temp->location = clause->location;
03061             /* Commute it --- note this modifies the temp node in-place. */
03062             CommuteOpExpr(temp);
03063             t_list = lappend(t_list, temp);
03064             restrictinfo->outer_is_left = false;
03065         }
03066         else
03067         {
03068             Assert(bms_is_subset(restrictinfo->left_relids, outerrelids));
03069             t_list = lappend(t_list, clause);
03070             restrictinfo->outer_is_left = true;
03071         }
03072     }
03073     return t_list;
03074 }
03075 
03076 /*
03077  * order_qual_clauses
03078  *      Given a list of qual clauses that will all be evaluated at the same
03079  *      plan node, sort the list into the order we want to check the quals
03080  *      in at runtime.
03081  *
03082  * Ideally the order should be driven by a combination of execution cost and
03083  * selectivity, but it's not immediately clear how to account for both,
03084  * and given the uncertainty of the estimates the reliability of the decisions
03085  * would be doubtful anyway.  So we just order by estimated per-tuple cost,
03086  * being careful not to change the order when (as is often the case) the
03087  * estimates are identical.
03088  *
03089  * Although this will work on either bare clauses or RestrictInfos, it's
03090  * much faster to apply it to RestrictInfos, since it can re-use cost
03091  * information that is cached in RestrictInfos.
03092  *
03093  * Note: some callers pass lists that contain entries that will later be
03094  * removed; this is the easiest way to let this routine see RestrictInfos
03095  * instead of bare clauses.  It's OK because we only sort by cost, but
03096  * a cost/selectivity combination would likely do the wrong thing.
03097  */
03098 static List *
03099 order_qual_clauses(PlannerInfo *root, List *clauses)
03100 {
03101     typedef struct
03102     {
03103         Node       *clause;
03104         Cost        cost;
03105     } QualItem;
03106     int         nitems = list_length(clauses);
03107     QualItem   *items;
03108     ListCell   *lc;
03109     int         i;
03110     List       *result;
03111 
03112     /* No need to work hard for 0 or 1 clause */
03113     if (nitems <= 1)
03114         return clauses;
03115 
03116     /*
03117      * Collect the items and costs into an array.  This is to avoid repeated
03118      * cost_qual_eval work if the inputs aren't RestrictInfos.
03119      */
03120     items = (QualItem *) palloc(nitems * sizeof(QualItem));
03121     i = 0;
03122     foreach(lc, clauses)
03123     {
03124         Node       *clause = (Node *) lfirst(lc);
03125         QualCost    qcost;
03126 
03127         cost_qual_eval_node(&qcost, clause, root);
03128         items[i].clause = clause;
03129         items[i].cost = qcost.per_tuple;
03130         i++;
03131     }
03132 
03133     /*
03134      * Sort.  We don't use qsort() because it's not guaranteed stable for
03135      * equal keys.  The expected number of entries is small enough that a
03136      * simple insertion sort should be good enough.
03137      */
03138     for (i = 1; i < nitems; i++)
03139     {
03140         QualItem    newitem = items[i];
03141         int         j;
03142 
03143         /* insert newitem into the already-sorted subarray */
03144         for (j = i; j > 0; j--)
03145         {
03146             if (newitem.cost >= items[j - 1].cost)
03147                 break;
03148             items[j] = items[j - 1];
03149         }
03150         items[j] = newitem;
03151     }
03152 
03153     /* Convert back to a list */
03154     result = NIL;
03155     for (i = 0; i < nitems; i++)
03156         result = lappend(result, items[i].clause);
03157 
03158     return result;
03159 }
03160 
03161 /*
03162  * Copy cost and size info from a Path node to the Plan node created from it.
03163  * The executor usually won't use this info, but it's needed by EXPLAIN.
03164  */
03165 static void
03166 copy_path_costsize(Plan *dest, Path *src)
03167 {
03168     if (src)
03169     {
03170         dest->startup_cost = src->startup_cost;
03171         dest->total_cost = src->total_cost;
03172         dest->plan_rows = src->rows;
03173         dest->plan_width = src->parent->width;
03174     }
03175     else
03176     {
03177         dest->startup_cost = 0;
03178         dest->total_cost = 0;
03179         dest->plan_rows = 0;
03180         dest->plan_width = 0;
03181     }
03182 }
03183 
03184 /*
03185  * Copy cost and size info from a lower plan node to an inserted node.
03186  * (Most callers alter the info after copying it.)
03187  */
03188 static void
03189 copy_plan_costsize(Plan *dest, Plan *src)
03190 {
03191     if (src)
03192     {
03193         dest->startup_cost = src->startup_cost;
03194         dest->total_cost = src->total_cost;
03195         dest->plan_rows = src->plan_rows;
03196         dest->plan_width = src->plan_width;
03197     }
03198     else
03199     {
03200         dest->startup_cost = 0;
03201         dest->total_cost = 0;
03202         dest->plan_rows = 0;
03203         dest->plan_width = 0;
03204     }
03205 }
03206 
03207 
03208 /*****************************************************************************
03209  *
03210  *  PLAN NODE BUILDING ROUTINES
03211  *
03212  * Some of these are exported because they are called to build plan nodes
03213  * in contexts where we're not deriving the plan node from a path node.
03214  *
03215  *****************************************************************************/
03216 
03217 static SeqScan *
03218 make_seqscan(List *qptlist,
03219              List *qpqual,
03220              Index scanrelid)
03221 {
03222     SeqScan    *node = makeNode(SeqScan);
03223     Plan       *plan = &node->plan;
03224 
03225     /* cost should be inserted by caller */
03226     plan->targetlist = qptlist;
03227     plan->qual = qpqual;
03228     plan->lefttree = NULL;
03229     plan->righttree = NULL;
03230     node->scanrelid = scanrelid;
03231 
03232     return node;
03233 }
03234 
03235 static IndexScan *
03236 make_indexscan(List *qptlist,
03237                List *qpqual,
03238                Index scanrelid,
03239                Oid indexid,
03240                List *indexqual,
03241                List *indexqualorig,
03242                List *indexorderby,
03243                List *indexorderbyorig,
03244                ScanDirection indexscandir)
03245 {
03246     IndexScan  *node = makeNode(IndexScan);
03247     Plan       *plan = &node->scan.plan;
03248 
03249     /* cost should be inserted by caller */
03250     plan->targetlist = qptlist;
03251     plan->qual = qpqual;
03252     plan->lefttree = NULL;
03253     plan->righttree = NULL;
03254     node->scan.scanrelid = scanrelid;
03255     node->indexid = indexid;
03256     node->indexqual = indexqual;
03257     node->indexqualorig = indexqualorig;
03258     node->indexorderby = indexorderby;
03259     node->indexorderbyorig = indexorderbyorig;
03260     node->indexorderdir = indexscandir;
03261 
03262     return node;
03263 }
03264 
03265 static IndexOnlyScan *
03266 make_indexonlyscan(List *qptlist,
03267                    List *qpqual,
03268                    Index scanrelid,
03269                    Oid indexid,
03270                    List *indexqual,
03271                    List *indexorderby,
03272                    List *indextlist,
03273                    ScanDirection indexscandir)
03274 {
03275     IndexOnlyScan *node = makeNode(IndexOnlyScan);
03276     Plan       *plan = &node->scan.plan;
03277 
03278     /* cost should be inserted by caller */
03279     plan->targetlist = qptlist;
03280     plan->qual = qpqual;
03281     plan->lefttree = NULL;
03282     plan->righttree = NULL;
03283     node->scan.scanrelid = scanrelid;
03284     node->indexid = indexid;
03285     node->indexqual = indexqual;
03286     node->indexorderby = indexorderby;
03287     node->indextlist = indextlist;
03288     node->indexorderdir = indexscandir;
03289 
03290     return node;
03291 }
03292 
03293 static BitmapIndexScan *
03294 make_bitmap_indexscan(Index scanrelid,
03295                       Oid indexid,
03296                       List *indexqual,
03297                       List *indexqualorig)
03298 {
03299     BitmapIndexScan *node = makeNode(BitmapIndexScan);
03300     Plan       *plan = &node->scan.plan;
03301 
03302     /* cost should be inserted by caller */
03303     plan->targetlist = NIL;     /* not used */
03304     plan->qual = NIL;           /* not used */
03305     plan->lefttree = NULL;
03306     plan->righttree = NULL;
03307     node->scan.scanrelid = scanrelid;
03308     node->indexid = indexid;
03309     node->indexqual = indexqual;
03310     node->indexqualorig = indexqualorig;
03311 
03312     return node;
03313 }
03314 
03315 static BitmapHeapScan *
03316 make_bitmap_heapscan(List *qptlist,
03317                      List *qpqual,
03318                      Plan *lefttree,
03319                      List *bitmapqualorig,
03320                      Index scanrelid)
03321 {
03322     BitmapHeapScan *node = makeNode(BitmapHeapScan);
03323     Plan       *plan = &node->scan.plan;
03324 
03325     /* cost should be inserted by caller */
03326     plan->targetlist = qptlist;
03327     plan->qual = qpqual;
03328     plan->lefttree = lefttree;
03329     plan->righttree = NULL;
03330     node->scan.scanrelid = scanrelid;
03331     node->bitmapqualorig = bitmapqualorig;
03332 
03333     return node;
03334 }
03335 
03336 static TidScan *
03337 make_tidscan(List *qptlist,
03338              List *qpqual,
03339              Index scanrelid,
03340              List *tidquals)
03341 {
03342     TidScan    *node = makeNode(TidScan);
03343     Plan       *plan = &node->scan.plan;
03344 
03345     /* cost should be inserted by caller */
03346     plan->targetlist = qptlist;
03347     plan->qual = qpqual;
03348     plan->lefttree = NULL;
03349     plan->righttree = NULL;
03350     node->scan.scanrelid = scanrelid;
03351     node->tidquals = tidquals;
03352 
03353     return node;
03354 }
03355 
03356 SubqueryScan *
03357 make_subqueryscan(List *qptlist,
03358                   List *qpqual,
03359                   Index scanrelid,
03360                   Plan *subplan)
03361 {
03362     SubqueryScan *node = makeNode(SubqueryScan);
03363     Plan       *plan = &node->scan.plan;
03364 
03365     /*
03366      * Cost is figured here for the convenience of prepunion.c.  Note this is
03367      * only correct for the case where qpqual is empty; otherwise caller
03368      * should overwrite cost with a better estimate.
03369      */
03370     copy_plan_costsize(plan, subplan);
03371     plan->total_cost += cpu_tuple_cost * subplan->plan_rows;
03372 
03373     plan->targetlist = qptlist;
03374     plan->qual = qpqual;
03375     plan->lefttree = NULL;
03376     plan->righttree = NULL;
03377     node->scan.scanrelid = scanrelid;
03378     node->subplan = subplan;
03379 
03380     return node;
03381 }
03382 
03383 static FunctionScan *
03384 make_functionscan(List *qptlist,
03385                   List *qpqual,
03386                   Index scanrelid,
03387                   Node *funcexpr,
03388                   List *funccolnames,
03389                   List *funccoltypes,
03390                   List *funccoltypmods,
03391                   List *funccolcollations)
03392 {
03393     FunctionScan *node = makeNode(FunctionScan);
03394     Plan       *plan = &node->scan.plan;
03395 
03396     /* cost should be inserted by caller */
03397     plan->targetlist = qptlist;
03398     plan->qual = qpqual;
03399     plan->lefttree = NULL;
03400     plan->righttree = NULL;
03401     node->scan.scanrelid = scanrelid;
03402     node->funcexpr = funcexpr;
03403     node->funccolnames = funccolnames;
03404     node->funccoltypes = funccoltypes;
03405     node->funccoltypmods = funccoltypmods;
03406     node->funccolcollations = funccolcollations;
03407 
03408     return node;
03409 }
03410 
03411 static ValuesScan *
03412 make_valuesscan(List *qptlist,
03413                 List *qpqual,
03414                 Index scanrelid,
03415                 List *values_lists)
03416 {
03417     ValuesScan *node = makeNode(ValuesScan);
03418     Plan       *plan = &node->scan.plan;
03419 
03420     /* cost should be inserted by caller */
03421     plan->targetlist = qptlist;
03422     plan->qual = qpqual;
03423     plan->lefttree = NULL;
03424     plan->righttree = NULL;
03425     node->scan.scanrelid = scanrelid;
03426     node->values_lists = values_lists;
03427 
03428     return node;
03429 }
03430 
03431 static CteScan *
03432 make_ctescan(List *qptlist,
03433              List *qpqual,
03434              Index scanrelid,
03435              int ctePlanId,
03436              int cteParam)
03437 {
03438     CteScan    *node = makeNode(CteScan);
03439     Plan       *plan = &node->scan.plan;
03440 
03441     /* cost should be inserted by caller */
03442     plan->targetlist = qptlist;
03443     plan->qual = qpqual;
03444     plan->lefttree = NULL;
03445     plan->righttree = NULL;
03446     node->scan.scanrelid = scanrelid;
03447     node->ctePlanId = ctePlanId;
03448     node->cteParam = cteParam;
03449 
03450     return node;
03451 }
03452 
03453 static WorkTableScan *
03454 make_worktablescan(List *qptlist,
03455                    List *qpqual,
03456                    Index scanrelid,
03457                    int wtParam)
03458 {
03459     WorkTableScan *node = makeNode(WorkTableScan);
03460     Plan       *plan = &node->scan.plan;
03461 
03462     /* cost should be inserted by caller */
03463     plan->targetlist = qptlist;
03464     plan->qual = qpqual;
03465     plan->lefttree = NULL;
03466     plan->righttree = NULL;
03467     node->scan.scanrelid = scanrelid;
03468     node->wtParam = wtParam;
03469 
03470     return node;
03471 }
03472 
03473 ForeignScan *
03474 make_foreignscan(List *qptlist,
03475                  List *qpqual,
03476                  Index scanrelid,
03477                  List *fdw_exprs,
03478                  List *fdw_private)
03479 {
03480     ForeignScan *node = makeNode(ForeignScan);
03481     Plan       *plan = &node->scan.plan;
03482 
03483     /* cost will be filled in by create_foreignscan_plan */
03484     plan->targetlist = qptlist;
03485     plan->qual = qpqual;
03486     plan->lefttree = NULL;
03487     plan->righttree = NULL;
03488     node->scan.scanrelid = scanrelid;
03489     node->fdw_exprs = fdw_exprs;
03490     node->fdw_private = fdw_private;
03491     /* fsSystemCol will be filled in by create_foreignscan_plan */
03492     node->fsSystemCol = false;
03493 
03494     return node;
03495 }
03496 
03497 Append *
03498 make_append(List *appendplans, List *tlist)
03499 {
03500     Append     *node = makeNode(Append);
03501     Plan       *plan = &node->plan;
03502     double      total_size;
03503     ListCell   *subnode;
03504 
03505     /*
03506      * Compute cost as sum of subplan costs.  We charge nothing extra for the
03507      * Append itself, which perhaps is too optimistic, but since it doesn't do
03508      * any selection or projection, it is a pretty cheap node.
03509      *
03510      * If you change this, see also create_append_path().  Also, the size
03511      * calculations should match set_append_rel_pathlist().  It'd be better
03512      * not to duplicate all this logic, but some callers of this function
03513      * aren't working from an appendrel or AppendPath, so there's noplace to
03514      * copy the data from.
03515      */
03516     plan->startup_cost = 0;
03517     plan->total_cost = 0;
03518     plan->plan_rows = 0;
03519     total_size = 0;
03520     foreach(subnode, appendplans)
03521     {
03522         Plan       *subplan = (Plan *) lfirst(subnode);
03523 
03524         if (subnode == list_head(appendplans))  /* first node? */
03525             plan->startup_cost = subplan->startup_cost;
03526         plan->total_cost += subplan->total_cost;
03527         plan->plan_rows += subplan->plan_rows;
03528         total_size += subplan->plan_width * subplan->plan_rows;
03529     }
03530     if (plan->plan_rows > 0)
03531         plan->plan_width = rint(total_size / plan->plan_rows);
03532     else
03533         plan->plan_width = 0;
03534 
03535     plan->targetlist = tlist;
03536     plan->qual = NIL;
03537     plan->lefttree = NULL;
03538     plan->righttree = NULL;
03539     node->appendplans = appendplans;
03540 
03541     return node;
03542 }
03543 
03544 RecursiveUnion *
03545 make_recursive_union(List *tlist,
03546                      Plan *lefttree,
03547                      Plan *righttree,
03548                      int wtParam,
03549                      List *distinctList,
03550                      long numGroups)
03551 {
03552     RecursiveUnion *node = makeNode(RecursiveUnion);
03553     Plan       *plan = &node->plan;
03554     int         numCols = list_length(distinctList);
03555 
03556     cost_recursive_union(plan, lefttree, righttree);
03557 
03558     plan->targetlist = tlist;
03559     plan->qual = NIL;
03560     plan->lefttree = lefttree;
03561     plan->righttree = righttree;
03562     node->wtParam = wtParam;
03563 
03564     /*
03565      * convert SortGroupClause list into arrays of attr indexes and equality
03566      * operators, as wanted by executor
03567      */
03568     node->numCols = numCols;
03569     if (numCols > 0)
03570     {
03571         int         keyno = 0;
03572         AttrNumber *dupColIdx;
03573         Oid        *dupOperators;
03574         ListCell   *slitem;
03575 
03576         dupColIdx = (AttrNumber *) palloc(sizeof(AttrNumber) * numCols);
03577         dupOperators = (Oid *) palloc(sizeof(Oid) * numCols);
03578 
03579         foreach(slitem, distinctList)
03580         {
03581             SortGroupClause *sortcl = (SortGroupClause *) lfirst(slitem);
03582             TargetEntry *tle = get_sortgroupclause_tle(sortcl,
03583                                                        plan->targetlist);
03584 
03585             dupColIdx[keyno] = tle->resno;
03586             dupOperators[keyno] = sortcl->eqop;
03587             Assert(OidIsValid(dupOperators[keyno]));
03588             keyno++;
03589         }
03590         node->dupColIdx = dupColIdx;
03591         node->dupOperators = dupOperators;
03592     }
03593     node->numGroups = numGroups;
03594 
03595     return node;
03596 }
03597 
03598 static BitmapAnd *
03599 make_bitmap_and(List *bitmapplans)
03600 {
03601     BitmapAnd  *node = makeNode(BitmapAnd);
03602     Plan       *plan = &node->plan;
03603 
03604     /* cost should be inserted by caller */
03605     plan->targetlist = NIL;
03606     plan->qual = NIL;
03607     plan->lefttree = NULL;
03608     plan->righttree = NULL;
03609     node->bitmapplans = bitmapplans;
03610 
03611     return node;
03612 }
03613 
03614 static BitmapOr *
03615 make_bitmap_or(List *bitmapplans)
03616 {
03617     BitmapOr   *node = makeNode(BitmapOr);
03618     Plan       *plan = &node->plan;
03619 
03620     /* cost should be inserted by caller */
03621     plan->targetlist = NIL;
03622     plan->qual = NIL;
03623     plan->lefttree = NULL;
03624     plan->righttree = NULL;
03625     node->bitmapplans = bitmapplans;
03626 
03627     return node;
03628 }
03629 
03630 static NestLoop *
03631 make_nestloop(List *tlist,
03632               List *joinclauses,
03633               List *otherclauses,
03634               List *nestParams,
03635               Plan *lefttree,
03636               Plan *righttree,
03637               JoinType jointype)
03638 {
03639     NestLoop   *node = makeNode(NestLoop);
03640     Plan       *plan = &node->join.plan;
03641 
03642     /* cost should be inserted by caller */
03643     plan->targetlist = tlist;
03644     plan->qual = otherclauses;
03645     plan->lefttree = lefttree;
03646     plan->righttree = righttree;
03647     node->join.jointype = jointype;
03648     node->join.joinqual = joinclauses;
03649     node->nestParams = nestParams;
03650 
03651     return node;
03652 }
03653 
03654 static HashJoin *
03655 make_hashjoin(List *tlist,
03656               List *joinclauses,
03657               List *otherclauses,
03658               List *hashclauses,
03659               Plan *lefttree,
03660               Plan *righttree,
03661               JoinType jointype)
03662 {
03663     HashJoin   *node = makeNode(HashJoin);
03664     Plan       *plan = &node->join.plan;
03665 
03666     /* cost should be inserted by caller */
03667     plan->targetlist = tlist;
03668     plan->qual = otherclauses;
03669     plan->lefttree = lefttree;
03670     plan->righttree = righttree;
03671     node->hashclauses = hashclauses;
03672     node->join.jointype = jointype;
03673     node->join.joinqual = joinclauses;
03674 
03675     return node;
03676 }
03677 
03678 static Hash *
03679 make_hash(Plan *lefttree,
03680           Oid skewTable,
03681           AttrNumber skewColumn,
03682           bool skewInherit,
03683           Oid skewColType,
03684           int32 skewColTypmod)
03685 {
03686     Hash       *node = makeNode(Hash);
03687     Plan       *plan = &node->plan;
03688 
03689     copy_plan_costsize(plan, lefttree);
03690 
03691     /*
03692      * For plausibility, make startup & total costs equal total cost of input
03693      * plan; this only affects EXPLAIN display not decisions.
03694      */
03695     plan->startup_cost = plan->total_cost;
03696     plan->targetlist = lefttree->targetlist;
03697     plan->qual = NIL;
03698     plan->lefttree = lefttree;
03699     plan->righttree = NULL;
03700 
03701     node->skewTable = skewTable;
03702     node->skewColumn = skewColumn;
03703     node->skewInherit = skewInherit;
03704     node->skewColType = skewColType;
03705     node->skewColTypmod = skewColTypmod;
03706 
03707     return node;
03708 }
03709 
03710 static MergeJoin *
03711 make_mergejoin(List *tlist,
03712                List *joinclauses,
03713                List *otherclauses,
03714                List *mergeclauses,
03715                Oid *mergefamilies,
03716                Oid *mergecollations,
03717                int *mergestrategies,
03718                bool *mergenullsfirst,
03719                Plan *lefttree,
03720                Plan *righttree,
03721                JoinType jointype)
03722 {
03723     MergeJoin  *node = makeNode(MergeJoin);
03724     Plan       *plan = &node->join.plan;
03725 
03726     /* cost should be inserted by caller */
03727     plan->targetlist = tlist;
03728     plan->qual = otherclauses;
03729     plan->lefttree = lefttree;
03730     plan->righttree = righttree;
03731     node->mergeclauses = mergeclauses;
03732     node->mergeFamilies = mergefamilies;
03733     node->mergeCollations = mergecollations;
03734     node->mergeStrategies = mergestrategies;
03735     node->mergeNullsFirst = mergenullsfirst;
03736     node->join.jointype = jointype;
03737     node->join.joinqual = joinclauses;
03738 
03739     return node;
03740 }
03741 
03742 /*
03743  * make_sort --- basic routine to build a Sort plan node
03744  *
03745  * Caller must have built the sortColIdx, sortOperators, collations, and
03746  * nullsFirst arrays already.
03747  * limit_tuples is as for cost_sort (in particular, pass -1 if no limit)
03748  */
03749 static Sort *
03750 make_sort(PlannerInfo *root, Plan *lefttree, int numCols,
03751           AttrNumber *sortColIdx, Oid *sortOperators,
03752           Oid *collations, bool *nullsFirst,
03753           double limit_tuples)
03754 {
03755     Sort       *node = makeNode(Sort);
03756     Plan       *plan = &node->plan;
03757     Path        sort_path;      /* dummy for result of cost_sort */
03758 
03759     copy_plan_costsize(plan, lefttree); /* only care about copying size */
03760     cost_sort(&sort_path, root, NIL,
03761               lefttree->total_cost,
03762               lefttree->plan_rows,
03763               lefttree->plan_width,
03764               0.0,
03765               work_mem,
03766               limit_tuples);
03767     plan->startup_cost = sort_path.startup_cost;
03768     plan->total_cost = sort_path.total_cost;
03769     plan->targetlist = lefttree->targetlist;
03770     plan->qual = NIL;
03771     plan->lefttree = lefttree;
03772     plan->righttree = NULL;
03773     node->numCols = numCols;
03774     node->sortColIdx = sortColIdx;
03775     node->sortOperators = sortOperators;
03776     node->collations = collations;
03777     node->nullsFirst = nullsFirst;
03778 
03779     return node;
03780 }
03781 
03782 /*
03783  * prepare_sort_from_pathkeys
03784  *    Prepare to sort according to given pathkeys
03785  *
03786  * This is used to set up for both Sort and MergeAppend nodes.  It calculates
03787  * the executor's representation of the sort key information, and adjusts the
03788  * plan targetlist if needed to add resjunk sort columns.
03789  *
03790  * Input parameters:
03791  *    'lefttree' is the plan node which yields input tuples
03792  *    'pathkeys' is the list of pathkeys by which the result is to be sorted
03793  *    'relids' identifies the child relation being sorted, if any
03794  *    'reqColIdx' is NULL or an array of required sort key column numbers
03795  *    'adjust_tlist_in_place' is TRUE if lefttree must be modified in-place
03796  *
03797  * We must convert the pathkey information into arrays of sort key column
03798  * numbers, sort operator OIDs, collation OIDs, and nulls-first flags,
03799  * which is the representation the executor wants.  These are returned into
03800  * the output parameters *p_numsortkeys etc.
03801  *
03802  * When looking for matches to an EquivalenceClass's members, we will only
03803  * consider child EC members if they match 'relids'.  This protects against
03804  * possible incorrect matches to child expressions that contain no Vars.
03805  *
03806  * If reqColIdx isn't NULL then it contains sort key column numbers that
03807  * we should match.  This is used when making child plans for a MergeAppend;
03808  * it's an error if we can't match the columns.
03809  *
03810  * If the pathkeys include expressions that aren't simple Vars, we will
03811  * usually need to add resjunk items to the input plan's targetlist to
03812  * compute these expressions, since the Sort/MergeAppend node itself won't
03813  * do any such calculations.  If the input plan type isn't one that can do
03814  * projections, this means adding a Result node just to do the projection.
03815  * However, the caller can pass adjust_tlist_in_place = TRUE to force the
03816  * lefttree tlist to be modified in-place regardless of whether the node type
03817  * can project --- we use this for fixing the tlist of MergeAppend itself.
03818  *
03819  * Returns the node which is to be the input to the Sort (either lefttree,
03820  * or a Result stacked atop lefttree).
03821  */
03822 static Plan *
03823 prepare_sort_from_pathkeys(PlannerInfo *root, Plan *lefttree, List *pathkeys,
03824                            Relids relids,
03825                            const AttrNumber *reqColIdx,
03826                            bool adjust_tlist_in_place,
03827                            int *p_numsortkeys,
03828                            AttrNumber **p_sortColIdx,
03829                            Oid **p_sortOperators,
03830                            Oid **p_collations,
03831                            bool **p_nullsFirst)
03832 {
03833     List       *tlist = lefttree->targetlist;
03834     ListCell   *i;
03835     int         numsortkeys;
03836     AttrNumber *sortColIdx;
03837     Oid        *sortOperators;
03838     Oid        *collations;
03839     bool       *nullsFirst;
03840 
03841     /*
03842      * We will need at most list_length(pathkeys) sort columns; possibly less
03843      */
03844     numsortkeys = list_length(pathkeys);
03845     sortColIdx = (AttrNumber *) palloc(numsortkeys * sizeof(AttrNumber));
03846     sortOperators = (Oid *) palloc(numsortkeys * sizeof(Oid));
03847     collations = (Oid *) palloc(numsortkeys * sizeof(Oid));
03848     nullsFirst = (bool *) palloc(numsortkeys * sizeof(bool));
03849 
03850     numsortkeys = 0;
03851 
03852     foreach(i, pathkeys)
03853     {
03854         PathKey    *pathkey = (PathKey *) lfirst(i);
03855         EquivalenceClass *ec = pathkey->pk_eclass;
03856         EquivalenceMember *em;
03857         TargetEntry *tle = NULL;
03858         Oid         pk_datatype = InvalidOid;
03859         Oid         sortop;
03860         ListCell   *j;
03861 
03862         if (ec->ec_has_volatile)
03863         {
03864             /*
03865              * If the pathkey's EquivalenceClass is volatile, then it must
03866              * have come from an ORDER BY clause, and we have to match it to
03867              * that same targetlist entry.
03868              */
03869             if (ec->ec_sortref == 0)    /* can't happen */
03870                 elog(ERROR, "volatile EquivalenceClass has no sortref");
03871             tle = get_sortgroupref_tle(ec->ec_sortref, tlist);
03872             Assert(tle);
03873             Assert(list_length(ec->ec_members) == 1);
03874             pk_datatype = ((EquivalenceMember *) linitial(ec->ec_members))->em_datatype;
03875         }
03876         else if (reqColIdx != NULL)
03877         {
03878             /*
03879              * If we are given a sort column number to match, only consider
03880              * the single TLE at that position.  It's possible that there is
03881              * no such TLE, in which case fall through and generate a resjunk
03882              * targetentry (we assume this must have happened in the parent
03883              * plan as well).  If there is a TLE but it doesn't match the
03884              * pathkey's EC, we do the same, which is probably the wrong thing
03885              * but we'll leave it to caller to complain about the mismatch.
03886              */
03887             tle = get_tle_by_resno(tlist, reqColIdx[numsortkeys]);
03888             if (tle)
03889             {
03890                 em = find_ec_member_for_tle(ec, tle, relids);
03891                 if (em)
03892                 {
03893                     /* found expr at right place in tlist */
03894                     pk_datatype = em->em_datatype;
03895                 }
03896                 else
03897                     tle = NULL;
03898             }
03899         }
03900         else
03901         {
03902             /*
03903              * Otherwise, we can sort by any non-constant expression listed in
03904              * the pathkey's EquivalenceClass.  For now, we take the first
03905              * tlist item found in the EC. If there's no match, we'll generate
03906              * a resjunk entry using the first EC member that is an expression
03907              * in the input's vars.  (The non-const restriction only matters
03908              * if the EC is below_outer_join; but if it isn't, it won't
03909              * contain consts anyway, else we'd have discarded the pathkey as
03910              * redundant.)
03911              *
03912              * XXX if we have a choice, is there any way of figuring out which
03913              * might be cheapest to execute?  (For example, int4lt is likely
03914              * much cheaper to execute than numericlt, but both might appear
03915              * in the same equivalence class...)  Not clear that we ever will
03916              * have an interesting choice in practice, so it may not matter.
03917              */
03918             foreach(j, tlist)
03919             {
03920                 tle = (TargetEntry *) lfirst(j);
03921                 em = find_ec_member_for_tle(ec, tle, relids);
03922                 if (em)
03923                 {
03924                     /* found expr already in tlist */
03925                     pk_datatype = em->em_datatype;
03926                     break;
03927                 }
03928                 tle = NULL;
03929             }
03930         }
03931 
03932         if (!tle)
03933         {
03934             /*
03935              * No matching tlist item; look for a computable expression. Note
03936              * that we treat Aggrefs as if they were variables; this is
03937              * necessary when attempting to sort the output from an Agg node
03938              * for use in a WindowFunc (since grouping_planner will have
03939              * treated the Aggrefs as variables, too).
03940              */
03941             Expr       *sortexpr = NULL;
03942 
03943             foreach(j, ec->ec_members)
03944             {
03945                 EquivalenceMember *em = (EquivalenceMember *) lfirst(j);
03946                 List       *exprvars;
03947                 ListCell   *k;
03948 
03949                 /*
03950                  * We shouldn't be trying to sort by an equivalence class that
03951                  * contains a constant, so no need to consider such cases any
03952                  * further.
03953                  */
03954                 if (em->em_is_const)
03955                     continue;
03956 
03957                 /*
03958                  * Ignore child members unless they match the rel being
03959                  * sorted.
03960                  */
03961                 if (em->em_is_child &&
03962                     !bms_equal(em->em_relids, relids))
03963                     continue;
03964 
03965                 sortexpr = em->em_expr;
03966                 exprvars = pull_var_clause((Node *) sortexpr,
03967                                            PVC_INCLUDE_AGGREGATES,
03968                                            PVC_INCLUDE_PLACEHOLDERS);
03969                 foreach(k, exprvars)
03970                 {
03971                     if (!tlist_member_ignore_relabel(lfirst(k), tlist))
03972                         break;
03973                 }
03974                 list_free(exprvars);
03975                 if (!k)
03976                 {
03977                     pk_datatype = em->em_datatype;
03978                     break;      /* found usable expression */
03979                 }
03980             }
03981             if (!j)
03982                 elog(ERROR, "could not find pathkey item to sort");
03983 
03984             /*
03985              * Do we need to insert a Result node?
03986              */
03987             if (!adjust_tlist_in_place &&
03988                 !is_projection_capable_plan(lefttree))
03989             {
03990                 /* copy needed so we don't modify input's tlist below */
03991                 tlist = copyObject(tlist);
03992                 lefttree = (Plan *) make_result(root, tlist, NULL,
03993                                                 lefttree);
03994             }
03995 
03996             /* Don't bother testing is_projection_capable_plan again */
03997             adjust_tlist_in_place = true;
03998 
03999             /*
04000              * Add resjunk entry to input's tlist
04001              */
04002             tle = makeTargetEntry(sortexpr,
04003                                   list_length(tlist) + 1,
04004                                   NULL,
04005                                   true);
04006             tlist = lappend(tlist, tle);
04007             lefttree->targetlist = tlist;       /* just in case NIL before */
04008         }
04009 
04010         /*
04011          * Look up the correct sort operator from the PathKey's slightly
04012          * abstracted representation.
04013          */
04014         sortop = get_opfamily_member(pathkey->pk_opfamily,
04015                                      pk_datatype,
04016                                      pk_datatype,
04017                                      pathkey->pk_strategy);
04018         if (!OidIsValid(sortop))    /* should not happen */
04019             elog(ERROR, "could not find member %d(%u,%u) of opfamily %u",
04020                  pathkey->pk_strategy, pk_datatype, pk_datatype,
04021                  pathkey->pk_opfamily);
04022 
04023         /* Add the column to the sort arrays */
04024         sortColIdx[numsortkeys] = tle->resno;
04025         sortOperators[numsortkeys] = sortop;
04026         collations[numsortkeys] = ec->ec_collation;
04027         nullsFirst[numsortkeys] = pathkey->pk_nulls_first;
04028         numsortkeys++;
04029     }
04030 
04031     /* Return results */
04032     *p_numsortkeys = numsortkeys;
04033     *p_sortColIdx = sortColIdx;
04034     *p_sortOperators = sortOperators;
04035     *p_collations = collations;
04036     *p_nullsFirst = nullsFirst;
04037 
04038     return lefttree;
04039 }
04040 
04041 /*
04042  * find_ec_member_for_tle
04043  *      Locate an EquivalenceClass member matching the given TLE, if any
04044  *
04045  * Child EC members are ignored unless they match 'relids'.
04046  */
04047 static EquivalenceMember *
04048 find_ec_member_for_tle(EquivalenceClass *ec,
04049                        TargetEntry *tle,
04050                        Relids relids)
04051 {
04052     Expr       *tlexpr;
04053     ListCell   *lc;
04054 
04055     /* We ignore binary-compatible relabeling on both ends */
04056     tlexpr = tle->expr;
04057     while (tlexpr && IsA(tlexpr, RelabelType))
04058         tlexpr = ((RelabelType *) tlexpr)->arg;
04059 
04060     foreach(lc, ec->ec_members)
04061     {
04062         EquivalenceMember *em = (EquivalenceMember *) lfirst(lc);
04063         Expr       *emexpr;
04064 
04065         /*
04066          * We shouldn't be trying to sort by an equivalence class that
04067          * contains a constant, so no need to consider such cases any further.
04068          */
04069         if (em->em_is_const)
04070             continue;
04071 
04072         /*
04073          * Ignore child members unless they match the rel being sorted.
04074          */
04075         if (em->em_is_child &&
04076             !bms_equal(em->em_relids, relids))
04077             continue;
04078 
04079         /* Match if same expression (after stripping relabel) */
04080         emexpr = em->em_expr;
04081         while (emexpr && IsA(emexpr, RelabelType))
04082             emexpr = ((RelabelType *) emexpr)->arg;
04083 
04084         if (equal(emexpr, tlexpr))
04085             return em;
04086     }
04087 
04088     return NULL;
04089 }
04090 
04091 /*
04092  * make_sort_from_pathkeys
04093  *    Create sort plan to sort according to given pathkeys
04094  *
04095  *    'lefttree' is the node which yields input tuples
04096  *    'pathkeys' is the list of pathkeys by which the result is to be sorted
04097  *    'limit_tuples' is the bound on the number of output tuples;
04098  *              -1 if no bound
04099  */
04100 Sort *
04101 make_sort_from_pathkeys(PlannerInfo *root, Plan *lefttree, List *pathkeys,
04102                         double limit_tuples)
04103 {
04104     int         numsortkeys;
04105     AttrNumber *sortColIdx;
04106     Oid        *sortOperators;
04107     Oid        *collations;
04108     bool       *nullsFirst;
04109 
04110     /* Compute sort column info, and adjust lefttree as needed */
04111     lefttree = prepare_sort_from_pathkeys(root, lefttree, pathkeys,
04112                                           NULL,
04113                                           NULL,
04114                                           false,
04115                                           &numsortkeys,
04116                                           &sortColIdx,
04117                                           &sortOperators,
04118                                           &collations,
04119                                           &nullsFirst);
04120 
04121     /* Now build the Sort node */
04122     return make_sort(root, lefttree, numsortkeys,
04123                      sortColIdx, sortOperators, collations,
04124                      nullsFirst, limit_tuples);
04125 }
04126 
04127 /*
04128  * make_sort_from_sortclauses
04129  *    Create sort plan to sort according to given sortclauses
04130  *
04131  *    'sortcls' is a list of SortGroupClauses
04132  *    'lefttree' is the node which yields input tuples
04133  */
04134 Sort *
04135 make_sort_from_sortclauses(PlannerInfo *root, List *sortcls, Plan *lefttree)
04136 {
04137     List       *sub_tlist = lefttree->targetlist;
04138     ListCell   *l;
04139     int         numsortkeys;
04140     AttrNumber *sortColIdx;
04141     Oid        *sortOperators;
04142     Oid        *collations;
04143     bool       *nullsFirst;
04144 
04145     /* Convert list-ish representation to arrays wanted by executor */
04146     numsortkeys = list_length(sortcls);
04147     sortColIdx = (AttrNumber *) palloc(numsortkeys * sizeof(AttrNumber));
04148     sortOperators = (Oid *) palloc(numsortkeys * sizeof(Oid));
04149     collations = (Oid *) palloc(numsortkeys * sizeof(Oid));
04150     nullsFirst = (bool *) palloc(numsortkeys * sizeof(bool));
04151 
04152     numsortkeys = 0;
04153     foreach(l, sortcls)
04154     {
04155         SortGroupClause *sortcl = (SortGroupClause *) lfirst(l);
04156         TargetEntry *tle = get_sortgroupclause_tle(sortcl, sub_tlist);
04157 
04158         sortColIdx[numsortkeys] = tle->resno;
04159         sortOperators[numsortkeys] = sortcl->sortop;
04160         collations[numsortkeys] = exprCollation((Node *) tle->expr);
04161         nullsFirst[numsortkeys] = sortcl->nulls_first;
04162         numsortkeys++;
04163     }
04164 
04165     return make_sort(root, lefttree, numsortkeys,
04166                      sortColIdx, sortOperators, collations,
04167                      nullsFirst, -1.0);
04168 }
04169 
04170 /*
04171  * make_sort_from_groupcols
04172  *    Create sort plan to sort based on grouping columns
04173  *
04174  * 'groupcls' is the list of SortGroupClauses
04175  * 'grpColIdx' gives the column numbers to use
04176  *
04177  * This might look like it could be merged with make_sort_from_sortclauses,
04178  * but presently we *must* use the grpColIdx[] array to locate sort columns,
04179  * because the child plan's tlist is not marked with ressortgroupref info
04180  * appropriate to the grouping node.  So, only the sort ordering info
04181  * is used from the SortGroupClause entries.
04182  */
04183 Sort *
04184 make_sort_from_groupcols(PlannerInfo *root,
04185                          List *groupcls,
04186                          AttrNumber *grpColIdx,
04187                          Plan *lefttree)
04188 {
04189     List       *sub_tlist = lefttree->targetlist;
04190     ListCell   *l;
04191     int         numsortkeys;
04192     AttrNumber *sortColIdx;
04193     Oid        *sortOperators;
04194     Oid        *collations;
04195     bool       *nullsFirst;
04196 
04197     /* Convert list-ish representation to arrays wanted by executor */
04198     numsortkeys = list_length(groupcls);
04199     sortColIdx = (AttrNumber *) palloc(numsortkeys * sizeof(AttrNumber));
04200     sortOperators = (Oid *) palloc(numsortkeys * sizeof(Oid));
04201     collations = (Oid *) palloc(numsortkeys * sizeof(Oid));
04202     nullsFirst = (bool *) palloc(numsortkeys * sizeof(bool));
04203 
04204     numsortkeys = 0;
04205     foreach(l, groupcls)
04206     {
04207         SortGroupClause *grpcl = (SortGroupClause *) lfirst(l);
04208         TargetEntry *tle = get_tle_by_resno(sub_tlist, grpColIdx[numsortkeys]);
04209 
04210         sortColIdx[numsortkeys] = tle->resno;
04211         sortOperators[numsortkeys] = grpcl->sortop;
04212         collations[numsortkeys] = exprCollation((Node *) tle->expr);
04213         nullsFirst[numsortkeys] = grpcl->nulls_first;
04214         numsortkeys++;
04215     }
04216 
04217     return make_sort(root, lefttree, numsortkeys,
04218                      sortColIdx, sortOperators, collations,
04219                      nullsFirst, -1.0);
04220 }
04221 
04222 static Material *
04223 make_material(Plan *lefttree)
04224 {
04225     Material   *node = makeNode(Material);
04226     Plan       *plan = &node->plan;
04227 
04228     /* cost should be inserted by caller */
04229     plan->targetlist = lefttree->targetlist;
04230     plan->qual = NIL;
04231     plan->lefttree = lefttree;
04232     plan->righttree = NULL;
04233 
04234     return node;
04235 }
04236 
04237 /*
04238  * materialize_finished_plan: stick a Material node atop a completed plan
04239  *
04240  * There are a couple of places where we want to attach a Material node
04241  * after completion of subquery_planner().  This currently requires hackery.
04242  * Since subquery_planner has already run SS_finalize_plan on the subplan
04243  * tree, we have to kluge up parameter lists for the Material node.
04244  * Possibly this could be fixed by postponing SS_finalize_plan processing
04245  * until setrefs.c is run?
04246  */
04247 Plan *
04248 materialize_finished_plan(Plan *subplan)
04249 {
04250     Plan       *matplan;
04251     Path        matpath;        /* dummy for result of cost_material */
04252 
04253     matplan = (Plan *) make_material(subplan);
04254 
04255     /* Set cost data */
04256     cost_material(&matpath,
04257                   subplan->startup_cost,
04258                   subplan->total_cost,
04259                   subplan->plan_rows,
04260                   subplan->plan_width);
04261     matplan->startup_cost = matpath.startup_cost;
04262     matplan->total_cost = matpath.total_cost;
04263     matplan->plan_rows = subplan->plan_rows;
04264     matplan->plan_width = subplan->plan_width;
04265 
04266     /* parameter kluge --- see comments above */
04267     matplan->extParam = bms_copy(subplan->extParam);
04268     matplan->allParam = bms_copy(subplan->allParam);
04269 
04270     return matplan;
04271 }
04272 
04273 Agg *
04274 make_agg(PlannerInfo *root, List *tlist, List *qual,
04275          AggStrategy aggstrategy, const AggClauseCosts *aggcosts,
04276          int numGroupCols, AttrNumber *grpColIdx, Oid *grpOperators,
04277          long numGroups,
04278          Plan *lefttree)
04279 {
04280     Agg        *node = makeNode(Agg);
04281     Plan       *plan = &node->plan;
04282     Path        agg_path;       /* dummy for result of cost_agg */
04283     QualCost    qual_cost;
04284 
04285     node->aggstrategy = aggstrategy;
04286     node->numCols = numGroupCols;
04287     node->grpColIdx = grpColIdx;
04288     node->grpOperators = grpOperators;
04289     node->numGroups = numGroups;
04290 
04291     copy_plan_costsize(plan, lefttree); /* only care about copying size */
04292     cost_agg(&agg_path, root,
04293              aggstrategy, aggcosts,
04294              numGroupCols, numGroups,
04295              lefttree->startup_cost,
04296              lefttree->total_cost,
04297              lefttree->plan_rows);
04298     plan->startup_cost = agg_path.startup_cost;
04299     plan->total_cost = agg_path.total_cost;
04300 
04301     /*
04302      * We will produce a single output tuple if not grouping, and a tuple per
04303      * group otherwise.
04304      */
04305     if (aggstrategy == AGG_PLAIN)
04306         plan->plan_rows = 1;
04307     else
04308         plan->plan_rows = numGroups;
04309 
04310     /*
04311      * We also need to account for the cost of evaluation of the qual (ie, the
04312      * HAVING clause) and the tlist.  Note that cost_qual_eval doesn't charge
04313      * anything for Aggref nodes; this is okay since they are really
04314      * comparable to Vars.
04315      *
04316      * See notes in add_tlist_costs_to_plan about why only make_agg,
04317      * make_windowagg and make_group worry about tlist eval cost.
04318      */
04319     if (qual)
04320     {
04321         cost_qual_eval(&qual_cost, qual, root);
04322         plan->startup_cost += qual_cost.startup;
04323         plan->total_cost += qual_cost.startup;
04324         plan->total_cost += qual_cost.per_tuple * plan->plan_rows;
04325     }
04326     add_tlist_costs_to_plan(root, plan, tlist);
04327 
04328     plan->qual = qual;
04329     plan->targetlist = tlist;
04330     plan->lefttree = lefttree;
04331     plan->righttree = NULL;
04332 
04333     return node;
04334 }
04335 
04336 WindowAgg *
04337 make_windowagg(PlannerInfo *root, List *tlist,
04338                List *windowFuncs, Index winref,
04339                int partNumCols, AttrNumber *partColIdx, Oid *partOperators,
04340                int ordNumCols, AttrNumber *ordColIdx, Oid *ordOperators,
04341                int frameOptions, Node *startOffset, Node *endOffset,
04342                Plan *lefttree)
04343 {
04344     WindowAgg  *node = makeNode(WindowAgg);
04345     Plan       *plan = &node->plan;
04346     Path        windowagg_path; /* dummy for result of cost_windowagg */
04347 
04348     node->winref = winref;
04349     node->partNumCols = partNumCols;
04350     node->partColIdx = partColIdx;
04351     node->partOperators = partOperators;
04352     node->ordNumCols = ordNumCols;
04353     node->ordColIdx = ordColIdx;
04354     node->ordOperators = ordOperators;
04355     node->frameOptions = frameOptions;
04356     node->startOffset = startOffset;
04357     node->endOffset = endOffset;
04358 
04359     copy_plan_costsize(plan, lefttree); /* only care about copying size */
04360     cost_windowagg(&windowagg_path, root,
04361                    windowFuncs, partNumCols, ordNumCols,
04362                    lefttree->startup_cost,
04363                    lefttree->total_cost,
04364                    lefttree->plan_rows);
04365     plan->startup_cost = windowagg_path.startup_cost;
04366     plan->total_cost = windowagg_path.total_cost;
04367 
04368     /*
04369      * We also need to account for the cost of evaluation of the tlist.
04370      *
04371      * See notes in add_tlist_costs_to_plan about why only make_agg,
04372      * make_windowagg and make_group worry about tlist eval cost.
04373      */
04374     add_tlist_costs_to_plan(root, plan, tlist);
04375 
04376     plan->targetlist = tlist;
04377     plan->lefttree = lefttree;
04378     plan->righttree = NULL;
04379     /* WindowAgg nodes never have a qual clause */
04380     plan->qual = NIL;
04381 
04382     return node;
04383 }
04384 
04385 Group *
04386 make_group(PlannerInfo *root,
04387            List *tlist,
04388            List *qual,
04389            int numGroupCols,
04390            AttrNumber *grpColIdx,
04391            Oid *grpOperators,
04392            double numGroups,
04393            Plan *lefttree)
04394 {
04395     Group      *node = makeNode(Group);
04396     Plan       *plan = &node->plan;
04397     Path        group_path;     /* dummy for result of cost_group */
04398     QualCost    qual_cost;
04399 
04400     node->numCols = numGroupCols;
04401     node->grpColIdx = grpColIdx;
04402     node->grpOperators = grpOperators;
04403 
04404     copy_plan_costsize(plan, lefttree); /* only care about copying size */
04405     cost_group(&group_path, root,
04406                numGroupCols, numGroups,
04407                lefttree->startup_cost,
04408                lefttree->total_cost,
04409                lefttree->plan_rows);
04410     plan->startup_cost = group_path.startup_cost;
04411     plan->total_cost = group_path.total_cost;
04412 
04413     /* One output tuple per estimated result group */
04414     plan->plan_rows = numGroups;
04415 
04416     /*
04417      * We also need to account for the cost of evaluation of the qual (ie, the
04418      * HAVING clause) and the tlist.
04419      *
04420      * XXX this double-counts the cost of evaluation of any expressions used
04421      * for grouping, since in reality those will have been evaluated at a
04422      * lower plan level and will only be copied by the Group node. Worth
04423      * fixing?
04424      *
04425      * See notes in add_tlist_costs_to_plan about why only make_agg,
04426      * make_windowagg and make_group worry about tlist eval cost.
04427      */
04428     if (qual)
04429     {
04430         cost_qual_eval(&qual_cost, qual, root);
04431         plan->startup_cost += qual_cost.startup;
04432         plan->total_cost += qual_cost.startup;
04433         plan->total_cost += qual_cost.per_tuple * plan->plan_rows;
04434     }
04435     add_tlist_costs_to_plan(root, plan, tlist);
04436 
04437     plan->qual = qual;
04438     plan->targetlist = tlist;
04439     plan->lefttree = lefttree;
04440     plan->righttree = NULL;
04441 
04442     return node;
04443 }
04444 
04445 /*
04446  * distinctList is a list of SortGroupClauses, identifying the targetlist items
04447  * that should be considered by the Unique filter.  The input path must
04448  * already be sorted accordingly.
04449  */
04450 Unique *
04451 make_unique(Plan *lefttree, List *distinctList)
04452 {
04453     Unique     *node = makeNode(Unique);
04454     Plan       *plan = &node->plan;
04455     int         numCols = list_length(distinctList);
04456     int         keyno = 0;
04457     AttrNumber *uniqColIdx;
04458     Oid        *uniqOperators;
04459     ListCell   *slitem;
04460 
04461     copy_plan_costsize(plan, lefttree);
04462 
04463     /*
04464      * Charge one cpu_operator_cost per comparison per input tuple. We assume
04465      * all columns get compared at most of the tuples.  (XXX probably this is
04466      * an overestimate.)
04467      */
04468     plan->total_cost += cpu_operator_cost * plan->plan_rows * numCols;
04469 
04470     /*
04471      * plan->plan_rows is left as a copy of the input subplan's plan_rows; ie,
04472      * we assume the filter removes nothing.  The caller must alter this if he
04473      * has a better idea.
04474      */
04475 
04476     plan->targetlist = lefttree->targetlist;
04477     plan->qual = NIL;
04478     plan->lefttree = lefttree;
04479     plan->righttree = NULL;
04480 
04481     /*
04482      * convert SortGroupClause list into arrays of attr indexes and equality
04483      * operators, as wanted by executor
04484      */
04485     Assert(numCols > 0);
04486     uniqColIdx = (AttrNumber *) palloc(sizeof(AttrNumber) * numCols);
04487     uniqOperators = (Oid *) palloc(sizeof(Oid) * numCols);
04488 
04489     foreach(slitem, distinctList)
04490     {
04491         SortGroupClause *sortcl = (SortGroupClause *) lfirst(slitem);
04492         TargetEntry *tle = get_sortgroupclause_tle(sortcl, plan->targetlist);
04493 
04494         uniqColIdx[keyno] = tle->resno;
04495         uniqOperators[keyno] = sortcl->eqop;
04496         Assert(OidIsValid(uniqOperators[keyno]));
04497         keyno++;
04498     }
04499 
04500     node->numCols = numCols;
04501     node->uniqColIdx = uniqColIdx;
04502     node->uniqOperators = uniqOperators;
04503 
04504     return node;
04505 }
04506 
04507 /*
04508  * distinctList is a list of SortGroupClauses, identifying the targetlist
04509  * items that should be considered by the SetOp filter.  The input path must
04510  * already be sorted accordingly.
04511  */
04512 SetOp *
04513 make_setop(SetOpCmd cmd, SetOpStrategy strategy, Plan *lefttree,
04514            List *distinctList, AttrNumber flagColIdx, int firstFlag,
04515            long numGroups, double outputRows)
04516 {
04517     SetOp      *node = makeNode(SetOp);
04518     Plan       *plan = &node->plan;
04519     int         numCols = list_length(distinctList);
04520     int         keyno = 0;
04521     AttrNumber *dupColIdx;
04522     Oid        *dupOperators;
04523     ListCell   *slitem;
04524 
04525     copy_plan_costsize(plan, lefttree);
04526     plan->plan_rows = outputRows;
04527 
04528     /*
04529      * Charge one cpu_operator_cost per comparison per input tuple. We assume
04530      * all columns get compared at most of the tuples.
04531      */
04532     plan->total_cost += cpu_operator_cost * lefttree->plan_rows * numCols;
04533 
04534     plan->targetlist = lefttree->targetlist;
04535     plan->qual = NIL;
04536     plan->lefttree = lefttree;
04537     plan->righttree = NULL;
04538 
04539     /*
04540      * convert SortGroupClause list into arrays of attr indexes and equality
04541      * operators, as wanted by executor
04542      */
04543     Assert(numCols > 0);
04544     dupColIdx = (AttrNumber *) palloc(sizeof(AttrNumber) * numCols);
04545     dupOperators = (Oid *) palloc(sizeof(Oid) * numCols);
04546 
04547     foreach(slitem, distinctList)
04548     {
04549         SortGroupClause *sortcl = (SortGroupClause *) lfirst(slitem);
04550         TargetEntry *tle = get_sortgroupclause_tle(sortcl, plan->targetlist);
04551 
04552         dupColIdx[keyno] = tle->resno;
04553         dupOperators[keyno] = sortcl->eqop;
04554         Assert(OidIsValid(dupOperators[keyno]));
04555         keyno++;
04556     }
04557 
04558     node->cmd = cmd;
04559     node->strategy = strategy;
04560     node->numCols = numCols;
04561     node->dupColIdx = dupColIdx;
04562     node->dupOperators = dupOperators;
04563     node->flagColIdx = flagColIdx;
04564     node->firstFlag = firstFlag;
04565     node->numGroups = numGroups;
04566 
04567     return node;
04568 }
04569 
04570 /*
04571  * make_lockrows
04572  *    Build a LockRows plan node
04573  */
04574 LockRows *
04575 make_lockrows(Plan *lefttree, List *rowMarks, int epqParam)
04576 {
04577     LockRows   *node = makeNode(LockRows);
04578     Plan       *plan = &node->plan;
04579 
04580     copy_plan_costsize(plan, lefttree);
04581 
04582     /* charge cpu_tuple_cost to reflect locking costs (underestimate?) */
04583     plan->total_cost += cpu_tuple_cost * plan->plan_rows;
04584 
04585     plan->targetlist = lefttree->targetlist;
04586     plan->qual = NIL;
04587     plan->lefttree = lefttree;
04588     plan->righttree = NULL;
04589 
04590     node->rowMarks = rowMarks;
04591     node->epqParam = epqParam;
04592 
04593     return node;
04594 }
04595 
04596 /*
04597  * Note: offset_est and count_est are passed in to save having to repeat
04598  * work already done to estimate the values of the limitOffset and limitCount
04599  * expressions.  Their values are as returned by preprocess_limit (0 means
04600  * "not relevant", -1 means "couldn't estimate").  Keep the code below in sync
04601  * with that function!
04602  */
04603 Limit *
04604 make_limit(Plan *lefttree, Node *limitOffset, Node *limitCount,
04605            int64 offset_est, int64 count_est)
04606 {
04607     Limit      *node = makeNode(Limit);
04608     Plan       *plan = &node->plan;
04609 
04610     copy_plan_costsize(plan, lefttree);
04611 
04612     /*
04613      * Adjust the output rows count and costs according to the offset/limit.
04614      * This is only a cosmetic issue if we are at top level, but if we are
04615      * building a subquery then it's important to report correct info to the
04616      * outer planner.
04617      *
04618      * When the offset or count couldn't be estimated, use 10% of the
04619      * estimated number of rows emitted from the subplan.
04620      */
04621     if (offset_est != 0)
04622     {
04623         double      offset_rows;
04624 
04625         if (offset_est > 0)
04626             offset_rows = (double) offset_est;
04627         else
04628             offset_rows = clamp_row_est(lefttree->plan_rows * 0.10);
04629         if (offset_rows > plan->plan_rows)
04630             offset_rows = plan->plan_rows;
04631         if (plan->plan_rows > 0)
04632             plan->startup_cost +=
04633                 (plan->total_cost - plan->startup_cost)
04634                 * offset_rows / plan->plan_rows;
04635         plan->plan_rows -= offset_rows;
04636         if (plan->plan_rows < 1)
04637             plan->plan_rows = 1;
04638     }
04639 
04640     if (count_est != 0)
04641     {
04642         double      count_rows;
04643 
04644         if (count_est > 0)
04645             count_rows = (double) count_est;
04646         else
04647             count_rows = clamp_row_est(lefttree->plan_rows * 0.10);
04648         if (count_rows > plan->plan_rows)
04649             count_rows = plan->plan_rows;
04650         if (plan->plan_rows > 0)
04651             plan->total_cost = plan->startup_cost +
04652                 (plan->total_cost - plan->startup_cost)
04653                 * count_rows / plan->plan_rows;
04654         plan->plan_rows = count_rows;
04655         if (plan->plan_rows < 1)
04656             plan->plan_rows = 1;
04657     }
04658 
04659     plan->targetlist = lefttree->targetlist;
04660     plan->qual = NIL;
04661     plan->lefttree = lefttree;
04662     plan->righttree = NULL;
04663 
04664     node->limitOffset = limitOffset;
04665     node->limitCount = limitCount;
04666 
04667     return node;
04668 }
04669 
04670 /*
04671  * make_result
04672  *    Build a Result plan node
04673  *
04674  * If we have a subplan, assume that any evaluation costs for the gating qual
04675  * were already factored into the subplan's startup cost, and just copy the
04676  * subplan cost.  If there's no subplan, we should include the qual eval
04677  * cost.  In either case, tlist eval cost is not to be included here.
04678  */
04679 Result *
04680 make_result(PlannerInfo *root,
04681             List *tlist,
04682             Node *resconstantqual,
04683             Plan *subplan)
04684 {
04685     Result     *node = makeNode(Result);
04686     Plan       *plan = &node->plan;
04687 
04688     if (subplan)
04689         copy_plan_costsize(plan, subplan);
04690     else
04691     {
04692         plan->startup_cost = 0;
04693         plan->total_cost = cpu_tuple_cost;
04694         plan->plan_rows = 1;    /* wrong if we have a set-valued function? */
04695         plan->plan_width = 0;   /* XXX is it worth being smarter? */
04696         if (resconstantqual)
04697         {
04698             QualCost    qual_cost;
04699 
04700             cost_qual_eval(&qual_cost, (List *) resconstantqual, root);
04701             /* resconstantqual is evaluated once at startup */
04702             plan->startup_cost += qual_cost.startup + qual_cost.per_tuple;
04703             plan->total_cost += qual_cost.startup + qual_cost.per_tuple;
04704         }
04705     }
04706 
04707     plan->targetlist = tlist;
04708     plan->qual = NIL;
04709     plan->lefttree = subplan;
04710     plan->righttree = NULL;
04711     node->resconstantqual = resconstantqual;
04712 
04713     return node;
04714 }
04715 
04716 /*
04717  * make_modifytable
04718  *    Build a ModifyTable plan node
04719  *
04720  * Currently, we don't charge anything extra for the actual table modification
04721  * work, nor for the RETURNING expressions if any.  It would only be window
04722  * dressing, since these are always top-level nodes and there is no way for
04723  * the costs to change any higher-level planning choices.  But we might want
04724  * to make it look better sometime.
04725  */
04726 ModifyTable *
04727 make_modifytable(PlannerInfo *root,
04728                  CmdType operation, bool canSetTag,
04729                  List *resultRelations,
04730                  List *subplans, List *returningLists,
04731                  List *rowMarks, int epqParam)
04732 {
04733     ModifyTable *node = makeNode(ModifyTable);
04734     Plan       *plan = &node->plan;
04735     double      total_size;
04736     List       *fdw_private_list;
04737     ListCell   *subnode;
04738     ListCell   *lc;
04739     int         i;
04740 
04741     Assert(list_length(resultRelations) == list_length(subplans));
04742     Assert(returningLists == NIL ||
04743            list_length(resultRelations) == list_length(returningLists));
04744 
04745     /*
04746      * Compute cost as sum of subplan costs.
04747      */
04748     plan->startup_cost = 0;
04749     plan->total_cost = 0;
04750     plan->plan_rows = 0;
04751     total_size = 0;
04752     foreach(subnode, subplans)
04753     {
04754         Plan       *subplan = (Plan *) lfirst(subnode);
04755 
04756         if (subnode == list_head(subplans))     /* first node? */
04757             plan->startup_cost = subplan->startup_cost;
04758         plan->total_cost += subplan->total_cost;
04759         plan->plan_rows += subplan->plan_rows;
04760         total_size += subplan->plan_width * subplan->plan_rows;
04761     }
04762     if (plan->plan_rows > 0)
04763         plan->plan_width = rint(total_size / plan->plan_rows);
04764     else
04765         plan->plan_width = 0;
04766 
04767     node->plan.lefttree = NULL;
04768     node->plan.righttree = NULL;
04769     node->plan.qual = NIL;
04770     /* setrefs.c will fill in the targetlist, if needed */
04771     node->plan.targetlist = NIL;
04772 
04773     node->operation = operation;
04774     node->canSetTag = canSetTag;
04775     node->resultRelations = resultRelations;
04776     node->resultRelIndex = -1;  /* will be set correctly in setrefs.c */
04777     node->plans = subplans;
04778     node->returningLists = returningLists;
04779     node->rowMarks = rowMarks;
04780     node->epqParam = epqParam;
04781 
04782     /*
04783      * For each result relation that is a foreign table, allow the FDW to
04784      * construct private plan data, and accumulate it all into a list.
04785      */
04786     fdw_private_list = NIL;
04787     i = 0;
04788     foreach(lc, resultRelations)
04789     {
04790         Index       rti = lfirst_int(lc);
04791         FdwRoutine *fdwroutine;
04792         List       *fdw_private;
04793 
04794         /*
04795          * If possible, we want to get the FdwRoutine from our RelOptInfo for
04796          * the table.  But sometimes we don't have a RelOptInfo and must get
04797          * it the hard way.  (In INSERT, the target relation is not scanned,
04798          * so it's not a baserel; and there are also corner cases for
04799          * updatable views where the target rel isn't a baserel.)
04800          */
04801         if (rti < root->simple_rel_array_size &&
04802             root->simple_rel_array[rti] != NULL)
04803         {
04804             RelOptInfo *resultRel = root->simple_rel_array[rti];
04805 
04806             fdwroutine = resultRel->fdwroutine;
04807         }
04808         else
04809         {
04810             RangeTblEntry *rte = planner_rt_fetch(rti, root);
04811 
04812             Assert(rte->rtekind == RTE_RELATION);
04813             if (rte->relkind == RELKIND_FOREIGN_TABLE)
04814                 fdwroutine = GetFdwRoutineByRelId(rte->relid);
04815             else
04816                 fdwroutine = NULL;
04817         }
04818 
04819         if (fdwroutine != NULL &&
04820             fdwroutine->PlanForeignModify != NULL)
04821             fdw_private = fdwroutine->PlanForeignModify(root, node, rti, i);
04822         else
04823             fdw_private = NIL;
04824         fdw_private_list = lappend(fdw_private_list, fdw_private);
04825         i++;
04826     }
04827     node->fdwPrivLists = fdw_private_list;
04828 
04829     return node;
04830 }
04831 
04832 /*
04833  * is_projection_capable_plan
04834  *      Check whether a given Plan node is able to do projection.
04835  */
04836 bool
04837 is_projection_capable_plan(Plan *plan)
04838 {
04839     /* Most plan types can project, so just list the ones that can't */
04840     switch (nodeTag(plan))
04841     {
04842         case T_Hash:
04843         case T_Material:
04844         case T_Sort:
04845         case T_Unique:
04846         case T_SetOp:
04847         case T_LockRows:
04848         case T_Limit:
04849         case T_ModifyTable:
04850         case T_Append:
04851         case T_MergeAppend:
04852         case T_RecursiveUnion:
04853             return false;
04854         default:
04855             break;
04856     }
04857     return true;
04858 }