LCOV - code coverage report
Current view: top level - src/backend/optimizer/plan - createplan.c (source / functions) Hit Total Coverage
Test: PostgreSQL 13devel Lines: 2029 2121 95.7 %
Date: 2019-11-22 07:06:56 Functions: 106 107 99.1 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*-------------------------------------------------------------------------
       2             :  *
       3             :  * createplan.c
       4             :  *    Routines to create the desired plan for processing a query.
       5             :  *    Planning is complete, we just need to convert the selected
       6             :  *    Path into a Plan.
       7             :  *
       8             :  * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group
       9             :  * Portions Copyright (c) 1994, Regents of the University of California
      10             :  *
      11             :  *
      12             :  * IDENTIFICATION
      13             :  *    src/backend/optimizer/plan/createplan.c
      14             :  *
      15             :  *-------------------------------------------------------------------------
      16             :  */
      17             : #include "postgres.h"
      18             : 
      19             : #include <limits.h>
      20             : #include <math.h>
      21             : 
      22             : #include "access/sysattr.h"
      23             : #include "catalog/pg_class.h"
      24             : #include "foreign/fdwapi.h"
      25             : #include "miscadmin.h"
      26             : #include "nodes/extensible.h"
      27             : #include "nodes/makefuncs.h"
      28             : #include "nodes/nodeFuncs.h"
      29             : #include "optimizer/clauses.h"
      30             : #include "optimizer/cost.h"
      31             : #include "optimizer/optimizer.h"
      32             : #include "optimizer/paramassign.h"
      33             : #include "optimizer/paths.h"
      34             : #include "optimizer/placeholder.h"
      35             : #include "optimizer/plancat.h"
      36             : #include "optimizer/planmain.h"
      37             : #include "optimizer/restrictinfo.h"
      38             : #include "optimizer/subselect.h"
      39             : #include "optimizer/tlist.h"
      40             : #include "parser/parse_clause.h"
      41             : #include "parser/parsetree.h"
      42             : #include "partitioning/partprune.h"
      43             : #include "utils/lsyscache.h"
      44             : 
      45             : 
      46             : /*
      47             :  * Flag bits that can appear in the flags argument of create_plan_recurse().
      48             :  * These can be OR-ed together.
      49             :  *
      50             :  * CP_EXACT_TLIST specifies that the generated plan node must return exactly
      51             :  * the tlist specified by the path's pathtarget (this overrides both
      52             :  * CP_SMALL_TLIST and CP_LABEL_TLIST, if those are set).  Otherwise, the
      53             :  * plan node is allowed to return just the Vars and PlaceHolderVars needed
      54             :  * to evaluate the pathtarget.
      55             :  *
      56             :  * CP_SMALL_TLIST specifies that a narrower tlist is preferred.  This is
      57             :  * passed down by parent nodes such as Sort and Hash, which will have to
      58             :  * store the returned tuples.
      59             :  *
      60             :  * CP_LABEL_TLIST specifies that the plan node must return columns matching
      61             :  * any sortgrouprefs specified in its pathtarget, with appropriate
      62             :  * ressortgroupref labels.  This is passed down by parent nodes such as Sort
      63             :  * and Group, which need these values to be available in their inputs.
      64             :  *
      65             :  * CP_IGNORE_TLIST specifies that the caller plans to replace the targetlist,
      66             :  * and therefore it doesn't matter a bit what target list gets generated.
      67             :  */
      68             : #define CP_EXACT_TLIST      0x0001  /* Plan must return specified tlist */
      69             : #define CP_SMALL_TLIST      0x0002  /* Prefer narrower tlists */
      70             : #define CP_LABEL_TLIST      0x0004  /* tlist must contain sortgrouprefs */
      71             : #define CP_IGNORE_TLIST     0x0008  /* caller will replace tlist */
      72             : 
      73             : 
      74             : static Plan *create_plan_recurse(PlannerInfo *root, Path *best_path,
      75             :                                  int flags);
      76             : static Plan *create_scan_plan(PlannerInfo *root, Path *best_path,
      77             :                               int flags);
      78             : static List *build_path_tlist(PlannerInfo *root, Path *path);
      79             : static bool use_physical_tlist(PlannerInfo *root, Path *path, int flags);
      80             : static List *get_gating_quals(PlannerInfo *root, List *quals);
      81             : static Plan *create_gating_plan(PlannerInfo *root, Path *path, Plan *plan,
      82             :                                 List *gating_quals);
      83             : static Plan *create_join_plan(PlannerInfo *root, JoinPath *best_path);
      84             : static Plan *create_append_plan(PlannerInfo *root, AppendPath *best_path,
      85             :                                 int flags);
      86             : static Plan *create_merge_append_plan(PlannerInfo *root, MergeAppendPath *best_path,
      87             :                                       int flags);
      88             : static Result *create_group_result_plan(PlannerInfo *root,
      89             :                                         GroupResultPath *best_path);
      90             : static ProjectSet *create_project_set_plan(PlannerInfo *root, ProjectSetPath *best_path);
      91             : static Material *create_material_plan(PlannerInfo *root, MaterialPath *best_path,
      92             :                                       int flags);
      93             : static Plan *create_unique_plan(PlannerInfo *root, UniquePath *best_path,
      94             :                                 int flags);
      95             : static Gather *create_gather_plan(PlannerInfo *root, GatherPath *best_path);
      96             : static Plan *create_projection_plan(PlannerInfo *root,
      97             :                                     ProjectionPath *best_path,
      98             :                                     int flags);
      99             : static Plan *inject_projection_plan(Plan *subplan, List *tlist, bool parallel_safe);
     100             : static Sort *create_sort_plan(PlannerInfo *root, SortPath *best_path, int flags);
     101             : static Group *create_group_plan(PlannerInfo *root, GroupPath *best_path);
     102             : static Unique *create_upper_unique_plan(PlannerInfo *root, UpperUniquePath *best_path,
     103             :                                         int flags);
     104             : static Agg *create_agg_plan(PlannerInfo *root, AggPath *best_path);
     105             : static Plan *create_groupingsets_plan(PlannerInfo *root, GroupingSetsPath *best_path);
     106             : static Result *create_minmaxagg_plan(PlannerInfo *root, MinMaxAggPath *best_path);
     107             : static WindowAgg *create_windowagg_plan(PlannerInfo *root, WindowAggPath *best_path);
     108             : static SetOp *create_setop_plan(PlannerInfo *root, SetOpPath *best_path,
     109             :                                 int flags);
     110             : static RecursiveUnion *create_recursiveunion_plan(PlannerInfo *root, RecursiveUnionPath *best_path);
     111             : static LockRows *create_lockrows_plan(PlannerInfo *root, LockRowsPath *best_path,
     112             :                                       int flags);
     113             : static ModifyTable *create_modifytable_plan(PlannerInfo *root, ModifyTablePath *best_path);
     114             : static Limit *create_limit_plan(PlannerInfo *root, LimitPath *best_path,
     115             :                                 int flags);
     116             : static SeqScan *create_seqscan_plan(PlannerInfo *root, Path *best_path,
     117             :                                     List *tlist, List *scan_clauses);
     118             : static SampleScan *create_samplescan_plan(PlannerInfo *root, Path *best_path,
     119             :                                           List *tlist, List *scan_clauses);
     120             : static Scan *create_indexscan_plan(PlannerInfo *root, IndexPath *best_path,
     121             :                                    List *tlist, List *scan_clauses, bool indexonly);
     122             : static BitmapHeapScan *create_bitmap_scan_plan(PlannerInfo *root,
     123             :                                                BitmapHeapPath *best_path,
     124             :                                                List *tlist, List *scan_clauses);
     125             : static Plan *create_bitmap_subplan(PlannerInfo *root, Path *bitmapqual,
     126             :                                    List **qual, List **indexqual, List **indexECs);
     127             : static void bitmap_subplan_mark_shared(Plan *plan);
     128             : static TidScan *create_tidscan_plan(PlannerInfo *root, TidPath *best_path,
     129             :                                     List *tlist, List *scan_clauses);
     130             : static SubqueryScan *create_subqueryscan_plan(PlannerInfo *root,
     131             :                                               SubqueryScanPath *best_path,
     132             :                                               List *tlist, List *scan_clauses);
     133             : static FunctionScan *create_functionscan_plan(PlannerInfo *root, Path *best_path,
     134             :                                               List *tlist, List *scan_clauses);
     135             : static ValuesScan *create_valuesscan_plan(PlannerInfo *root, Path *best_path,
     136             :                                           List *tlist, List *scan_clauses);
     137             : static TableFuncScan *create_tablefuncscan_plan(PlannerInfo *root, Path *best_path,
     138             :                                                 List *tlist, List *scan_clauses);
     139             : static CteScan *create_ctescan_plan(PlannerInfo *root, Path *best_path,
     140             :                                     List *tlist, List *scan_clauses);
     141             : static NamedTuplestoreScan *create_namedtuplestorescan_plan(PlannerInfo *root,
     142             :                                                             Path *best_path, List *tlist, List *scan_clauses);
     143             : static Result *create_resultscan_plan(PlannerInfo *root, Path *best_path,
     144             :                                       List *tlist, List *scan_clauses);
     145             : static WorkTableScan *create_worktablescan_plan(PlannerInfo *root, Path *best_path,
     146             :                                                 List *tlist, List *scan_clauses);
     147             : static ForeignScan *create_foreignscan_plan(PlannerInfo *root, ForeignPath *best_path,
     148             :                                             List *tlist, List *scan_clauses);
     149             : static CustomScan *create_customscan_plan(PlannerInfo *root,
     150             :                                           CustomPath *best_path,
     151             :                                           List *tlist, List *scan_clauses);
     152             : static NestLoop *create_nestloop_plan(PlannerInfo *root, NestPath *best_path);
     153             : static MergeJoin *create_mergejoin_plan(PlannerInfo *root, MergePath *best_path);
     154             : static HashJoin *create_hashjoin_plan(PlannerInfo *root, HashPath *best_path);
     155             : static Node *replace_nestloop_params(PlannerInfo *root, Node *expr);
     156             : static Node *replace_nestloop_params_mutator(Node *node, PlannerInfo *root);
     157             : static void fix_indexqual_references(PlannerInfo *root, IndexPath *index_path,
     158             :                                      List **stripped_indexquals_p,
     159             :                                      List **fixed_indexquals_p);
     160             : static List *fix_indexorderby_references(PlannerInfo *root, IndexPath *index_path);
     161             : static Node *fix_indexqual_clause(PlannerInfo *root,
     162             :                                   IndexOptInfo *index, int indexcol,
     163             :                                   Node *clause, List *indexcolnos);
     164             : static Node *fix_indexqual_operand(Node *node, IndexOptInfo *index, int indexcol);
     165             : static List *get_switched_clauses(List *clauses, Relids outerrelids);
     166             : static List *order_qual_clauses(PlannerInfo *root, List *clauses);
     167             : static void copy_generic_path_info(Plan *dest, Path *src);
     168             : static void copy_plan_costsize(Plan *dest, Plan *src);
     169             : static void label_sort_with_costsize(PlannerInfo *root, Sort *plan,
     170             :                                      double limit_tuples);
     171             : static SeqScan *make_seqscan(List *qptlist, List *qpqual, Index scanrelid);
     172             : static SampleScan *make_samplescan(List *qptlist, List *qpqual, Index scanrelid,
     173             :                                    TableSampleClause *tsc);
     174             : static IndexScan *make_indexscan(List *qptlist, List *qpqual, Index scanrelid,
     175             :                                  Oid indexid, List *indexqual, List *indexqualorig,
     176             :                                  List *indexorderby, List *indexorderbyorig,
     177             :                                  List *indexorderbyops,
     178             :                                  ScanDirection indexscandir);
     179             : static IndexOnlyScan *make_indexonlyscan(List *qptlist, List *qpqual,
     180             :                                          Index scanrelid, Oid indexid,
     181             :                                          List *indexqual, List *indexorderby,
     182             :                                          List *indextlist,
     183             :                                          ScanDirection indexscandir);
     184             : static BitmapIndexScan *make_bitmap_indexscan(Index scanrelid, Oid indexid,
     185             :                                               List *indexqual,
     186             :                                               List *indexqualorig);
     187             : static BitmapHeapScan *make_bitmap_heapscan(List *qptlist,
     188             :                                             List *qpqual,
     189             :                                             Plan *lefttree,
     190             :                                             List *bitmapqualorig,
     191             :                                             Index scanrelid);
     192             : static TidScan *make_tidscan(List *qptlist, List *qpqual, Index scanrelid,
     193             :                              List *tidquals);
     194             : static SubqueryScan *make_subqueryscan(List *qptlist,
     195             :                                        List *qpqual,
     196             :                                        Index scanrelid,
     197             :                                        Plan *subplan);
     198             : static FunctionScan *make_functionscan(List *qptlist, List *qpqual,
     199             :                                        Index scanrelid, List *functions, bool funcordinality);
     200             : static ValuesScan *make_valuesscan(List *qptlist, List *qpqual,
     201             :                                    Index scanrelid, List *values_lists);
     202             : static TableFuncScan *make_tablefuncscan(List *qptlist, List *qpqual,
     203             :                                          Index scanrelid, TableFunc *tablefunc);
     204             : static CteScan *make_ctescan(List *qptlist, List *qpqual,
     205             :                              Index scanrelid, int ctePlanId, int cteParam);
     206             : static NamedTuplestoreScan *make_namedtuplestorescan(List *qptlist, List *qpqual,
     207             :                                                      Index scanrelid, char *enrname);
     208             : static WorkTableScan *make_worktablescan(List *qptlist, List *qpqual,
     209             :                                          Index scanrelid, int wtParam);
     210             : static RecursiveUnion *make_recursive_union(List *tlist,
     211             :                                             Plan *lefttree,
     212             :                                             Plan *righttree,
     213             :                                             int wtParam,
     214             :                                             List *distinctList,
     215             :                                             long numGroups);
     216             : static BitmapAnd *make_bitmap_and(List *bitmapplans);
     217             : static BitmapOr *make_bitmap_or(List *bitmapplans);
     218             : static NestLoop *make_nestloop(List *tlist,
     219             :                                List *joinclauses, List *otherclauses, List *nestParams,
     220             :                                Plan *lefttree, Plan *righttree,
     221             :                                JoinType jointype, bool inner_unique);
     222             : static HashJoin *make_hashjoin(List *tlist,
     223             :                                List *joinclauses, List *otherclauses,
     224             :                                List *hashclauses,
     225             :                                List *hashoperators, List *hashcollations,
     226             :                                List *hashkeys,
     227             :                                Plan *lefttree, Plan *righttree,
     228             :                                JoinType jointype, bool inner_unique);
     229             : static Hash *make_hash(Plan *lefttree,
     230             :                        List *hashkeys,
     231             :                        Oid skewTable,
     232             :                        AttrNumber skewColumn,
     233             :                        bool skewInherit);
     234             : static MergeJoin *make_mergejoin(List *tlist,
     235             :                                  List *joinclauses, List *otherclauses,
     236             :                                  List *mergeclauses,
     237             :                                  Oid *mergefamilies,
     238             :                                  Oid *mergecollations,
     239             :                                  int *mergestrategies,
     240             :                                  bool *mergenullsfirst,
     241             :                                  Plan *lefttree, Plan *righttree,
     242             :                                  JoinType jointype, bool inner_unique,
     243             :                                  bool skip_mark_restore);
     244             : static Sort *make_sort(Plan *lefttree, int numCols,
     245             :                        AttrNumber *sortColIdx, Oid *sortOperators,
     246             :                        Oid *collations, bool *nullsFirst);
     247             : static Plan *prepare_sort_from_pathkeys(Plan *lefttree, List *pathkeys,
     248             :                                         Relids relids,
     249             :                                         const AttrNumber *reqColIdx,
     250             :                                         bool adjust_tlist_in_place,
     251             :                                         int *p_numsortkeys,
     252             :                                         AttrNumber **p_sortColIdx,
     253             :                                         Oid **p_sortOperators,
     254             :                                         Oid **p_collations,
     255             :                                         bool **p_nullsFirst);
     256             : static EquivalenceMember *find_ec_member_for_tle(EquivalenceClass *ec,
     257             :                                                  TargetEntry *tle,
     258             :                                                  Relids relids);
     259             : static Sort *make_sort_from_pathkeys(Plan *lefttree, List *pathkeys,
     260             :                                      Relids relids);
     261             : static Sort *make_sort_from_groupcols(List *groupcls,
     262             :                                       AttrNumber *grpColIdx,
     263             :                                       Plan *lefttree);
     264             : static Material *make_material(Plan *lefttree);
     265             : static WindowAgg *make_windowagg(List *tlist, Index winref,
     266             :                                  int partNumCols, AttrNumber *partColIdx, Oid *partOperators, Oid *partCollations,
     267             :                                  int ordNumCols, AttrNumber *ordColIdx, Oid *ordOperators, Oid *ordCollations,
     268             :                                  int frameOptions, Node *startOffset, Node *endOffset,
     269             :                                  Oid startInRangeFunc, Oid endInRangeFunc,
     270             :                                  Oid inRangeColl, bool inRangeAsc, bool inRangeNullsFirst,
     271             :                                  Plan *lefttree);
     272             : static Group *make_group(List *tlist, List *qual, int numGroupCols,
     273             :                          AttrNumber *grpColIdx, Oid *grpOperators, Oid *grpCollations,
     274             :                          Plan *lefttree);
     275             : static Unique *make_unique_from_sortclauses(Plan *lefttree, List *distinctList);
     276             : static Unique *make_unique_from_pathkeys(Plan *lefttree,
     277             :                                          List *pathkeys, int numCols);
     278             : static Gather *make_gather(List *qptlist, List *qpqual,
     279             :                            int nworkers, int rescan_param, bool single_copy, Plan *subplan);
     280             : static SetOp *make_setop(SetOpCmd cmd, SetOpStrategy strategy, Plan *lefttree,
     281             :                          List *distinctList, AttrNumber flagColIdx, int firstFlag,
     282             :                          long numGroups);
     283             : static LockRows *make_lockrows(Plan *lefttree, List *rowMarks, int epqParam);
     284             : static Result *make_result(List *tlist, Node *resconstantqual, Plan *subplan);
     285             : static ProjectSet *make_project_set(List *tlist, Plan *subplan);
     286             : static ModifyTable *make_modifytable(PlannerInfo *root,
     287             :                                      CmdType operation, bool canSetTag,
     288             :                                      Index nominalRelation, Index rootRelation,
     289             :                                      bool partColsUpdated,
     290             :                                      List *resultRelations, List *subplans, List *subroots,
     291             :                                      List *withCheckOptionLists, List *returningLists,
     292             :                                      List *rowMarks, OnConflictExpr *onconflict, int epqParam);
     293             : static GatherMerge *create_gather_merge_plan(PlannerInfo *root,
     294             :                                              GatherMergePath *best_path);
     295             : 
     296             : 
     297             : /*
     298             :  * create_plan
     299             :  *    Creates the access plan for a query by recursively processing the
     300             :  *    desired tree of pathnodes, starting at the node 'best_path'.  For
     301             :  *    every pathnode found, we create a corresponding plan node containing
     302             :  *    appropriate id, target list, and qualification information.
     303             :  *
     304             :  *    The tlists and quals in the plan tree are still in planner format,
     305             :  *    ie, Vars still correspond to the parser's numbering.  This will be
     306             :  *    fixed later by setrefs.c.
     307             :  *
     308             :  *    best_path is the best access path
     309             :  *
     310             :  *    Returns a Plan tree.
     311             :  */
     312             : Plan *
     313      300674 : create_plan(PlannerInfo *root, Path *best_path)
     314             : {
     315             :     Plan       *plan;
     316             : 
     317             :     /* plan_params should not be in use in current query level */
     318             :     Assert(root->plan_params == NIL);
     319             : 
     320             :     /* Initialize this module's workspace in PlannerInfo */
     321      300674 :     root->curOuterRels = NULL;
     322      300674 :     root->curOuterParams = NIL;
     323             : 
     324             :     /* Recursively process the path tree, demanding the correct tlist result */
     325      300674 :     plan = create_plan_recurse(root, best_path, CP_EXACT_TLIST);
     326             : 
     327             :     /*
     328             :      * Make sure the topmost plan node's targetlist exposes the original
     329             :      * column names and other decorative info.  Targetlists generated within
     330             :      * the planner don't bother with that stuff, but we must have it on the
     331             :      * top-level tlist seen at execution time.  However, ModifyTable plan
     332             :      * nodes don't have a tlist matching the querytree targetlist.
     333             :      */
     334      300554 :     if (!IsA(plan, ModifyTable))
     335      231302 :         apply_tlist_labeling(plan->targetlist, root->processed_tlist);
     336             : 
     337             :     /*
     338             :      * Attach any initPlans created in this query level to the topmost plan
     339             :      * node.  (In principle the initplans could go in any plan node at or
     340             :      * above where they're referenced, but there seems no reason to put them
     341             :      * any lower than the topmost node for the query level.  Also, see
     342             :      * comments for SS_finalize_plan before you try to change this.)
     343             :      */
     344      300554 :     SS_attach_initplans(root, plan);
     345             : 
     346             :     /* Check we successfully assigned all NestLoopParams to plan nodes */
     347      300554 :     if (root->curOuterParams != NIL)
     348           0 :         elog(ERROR, "failed to assign all NestLoopParams to plan nodes");
     349             : 
     350             :     /*
     351             :      * Reset plan_params to ensure param IDs used for nestloop params are not
     352             :      * re-used later
     353             :      */
     354      300554 :     root->plan_params = NIL;
     355             : 
     356      300554 :     return plan;
     357             : }
     358             : 
     359             : /*
     360             :  * create_plan_recurse
     361             :  *    Recursive guts of create_plan().
     362             :  */
     363             : static Plan *
     364      795740 : create_plan_recurse(PlannerInfo *root, Path *best_path, int flags)
     365             : {
     366             :     Plan       *plan;
     367             : 
     368             :     /* Guard against stack overflow due to overly complex plans */
     369      795740 :     check_stack_depth();
     370             : 
     371      795740 :     switch (best_path->pathtype)
     372             :     {
     373             :         case T_SeqScan:
     374             :         case T_SampleScan:
     375             :         case T_IndexScan:
     376             :         case T_IndexOnlyScan:
     377             :         case T_BitmapHeapScan:
     378             :         case T_TidScan:
     379             :         case T_SubqueryScan:
     380             :         case T_FunctionScan:
     381             :         case T_TableFuncScan:
     382             :         case T_ValuesScan:
     383             :         case T_CteScan:
     384             :         case T_WorkTableScan:
     385             :         case T_NamedTuplestoreScan:
     386             :         case T_ForeignScan:
     387             :         case T_CustomScan:
     388      259476 :             plan = create_scan_plan(root, best_path, flags);
     389      259476 :             break;
     390             :         case T_HashJoin:
     391             :         case T_MergeJoin:
     392             :         case T_NestLoop:
     393       60208 :             plan = create_join_plan(root,
     394             :                                     (JoinPath *) best_path);
     395       60208 :             break;
     396             :         case T_Append:
     397        9394 :             plan = create_append_plan(root,
     398             :                                       (AppendPath *) best_path,
     399             :                                       flags);
     400        9394 :             break;
     401             :         case T_MergeAppend:
     402         236 :             plan = create_merge_append_plan(root,
     403             :                                             (MergeAppendPath *) best_path,
     404             :                                             flags);
     405         236 :             break;
     406             :         case T_Result:
     407      326312 :             if (IsA(best_path, ProjectionPath))
     408             :             {
     409      213056 :                 plan = create_projection_plan(root,
     410             :                                               (ProjectionPath *) best_path,
     411             :                                               flags);
     412             :             }
     413      113256 :             else if (IsA(best_path, MinMaxAggPath))
     414             :             {
     415         336 :                 plan = (Plan *) create_minmaxagg_plan(root,
     416             :                                                       (MinMaxAggPath *) best_path);
     417             :             }
     418      112920 :             else if (IsA(best_path, GroupResultPath))
     419             :             {
     420      112330 :                 plan = (Plan *) create_group_result_plan(root,
     421             :                                                          (GroupResultPath *) best_path);
     422             :             }
     423             :             else
     424             :             {
     425             :                 /* Simple RTE_RESULT base relation */
     426             :                 Assert(IsA(best_path, Path));
     427         590 :                 plan = create_scan_plan(root, best_path, flags);
     428             :             }
     429      326312 :             break;
     430             :         case T_ProjectSet:
     431        3686 :             plan = (Plan *) create_project_set_plan(root,
     432             :                                                     (ProjectSetPath *) best_path);
     433        3686 :             break;
     434             :         case T_Material:
     435        2656 :             plan = (Plan *) create_material_plan(root,
     436             :                                                  (MaterialPath *) best_path,
     437             :                                                  flags);
     438        2656 :             break;
     439             :         case T_Unique:
     440         524 :             if (IsA(best_path, UpperUniquePath))
     441             :             {
     442         324 :                 plan = (Plan *) create_upper_unique_plan(root,
     443             :                                                          (UpperUniquePath *) best_path,
     444             :                                                          flags);
     445             :             }
     446             :             else
     447             :             {
     448             :                 Assert(IsA(best_path, UniquePath));
     449         200 :                 plan = create_unique_plan(root,
     450             :                                           (UniquePath *) best_path,
     451             :                                           flags);
     452             :             }
     453         524 :             break;
     454             :         case T_Gather:
     455         488 :             plan = (Plan *) create_gather_plan(root,
     456             :                                                (GatherPath *) best_path);
     457         488 :             break;
     458             :         case T_Sort:
     459       29058 :             plan = (Plan *) create_sort_plan(root,
     460             :                                              (SortPath *) best_path,
     461             :                                              flags);
     462       29058 :             break;
     463             :         case T_Group:
     464         138 :             plan = (Plan *) create_group_plan(root,
     465             :                                               (GroupPath *) best_path);
     466         138 :             break;
     467             :         case T_Agg:
     468       24812 :             if (IsA(best_path, GroupingSetsPath))
     469         424 :                 plan = create_groupingsets_plan(root,
     470             :                                                 (GroupingSetsPath *) best_path);
     471             :             else
     472             :             {
     473             :                 Assert(IsA(best_path, AggPath));
     474       24388 :                 plan = (Plan *) create_agg_plan(root,
     475             :                                                 (AggPath *) best_path);
     476             :             }
     477       24812 :             break;
     478             :         case T_WindowAgg:
     479        1160 :             plan = (Plan *) create_windowagg_plan(root,
     480             :                                                   (WindowAggPath *) best_path);
     481        1160 :             break;
     482             :         case T_SetOp:
     483         208 :             plan = (Plan *) create_setop_plan(root,
     484             :                                               (SetOpPath *) best_path,
     485             :                                               flags);
     486         208 :             break;
     487             :         case T_RecursiveUnion:
     488         320 :             plan = (Plan *) create_recursiveunion_plan(root,
     489             :                                                        (RecursiveUnionPath *) best_path);
     490         320 :             break;
     491             :         case T_LockRows:
     492        4840 :             plan = (Plan *) create_lockrows_plan(root,
     493             :                                                  (LockRowsPath *) best_path,
     494             :                                                  flags);
     495        4840 :             break;
     496             :         case T_ModifyTable:
     497       69372 :             plan = (Plan *) create_modifytable_plan(root,
     498             :                                                     (ModifyTablePath *) best_path);
     499       69252 :             break;
     500             :         case T_Limit:
     501        2716 :             plan = (Plan *) create_limit_plan(root,
     502             :                                               (LimitPath *) best_path,
     503             :                                               flags);
     504        2716 :             break;
     505             :         case T_GatherMerge:
     506         136 :             plan = (Plan *) create_gather_merge_plan(root,
     507             :                                                      (GatherMergePath *) best_path);
     508         136 :             break;
     509             :         default:
     510           0 :             elog(ERROR, "unrecognized node type: %d",
     511             :                  (int) best_path->pathtype);
     512             :             plan = NULL;        /* keep compiler quiet */
     513             :             break;
     514             :     }
     515             : 
     516      795620 :     return plan;
     517             : }
     518             : 
     519             : /*
     520             :  * create_scan_plan
     521             :  *   Create a scan plan for the parent relation of 'best_path'.
     522             :  */
     523             : static Plan *
     524      260066 : create_scan_plan(PlannerInfo *root, Path *best_path, int flags)
     525             : {
     526      260066 :     RelOptInfo *rel = best_path->parent;
     527             :     List       *scan_clauses;
     528             :     List       *gating_clauses;
     529             :     List       *tlist;
     530             :     Plan       *plan;
     531             : 
     532             :     /*
     533             :      * Extract the relevant restriction clauses from the parent relation. The
     534             :      * executor must apply all these restrictions during the scan, except for
     535             :      * pseudoconstants which we'll take care of below.
     536             :      *
     537             :      * If this is a plain indexscan or index-only scan, we need not consider
     538             :      * restriction clauses that are implied by the index's predicate, so use
     539             :      * indrestrictinfo not baserestrictinfo.  Note that we can't do that for
     540             :      * bitmap indexscans, since there's not necessarily a single index
     541             :      * involved; but it doesn't matter since create_bitmap_scan_plan() will be
     542             :      * able to get rid of such clauses anyway via predicate proof.
     543             :      */
     544      260066 :     switch (best_path->pathtype)
     545             :     {
     546             :         case T_IndexScan:
     547             :         case T_IndexOnlyScan:
     548       80818 :             scan_clauses = castNode(IndexPath, best_path)->indexinfo->indrestrictinfo;
     549       80818 :             break;
     550             :         default:
     551      179248 :             scan_clauses = rel->baserestrictinfo;
     552      179248 :             break;
     553             :     }
     554             : 
     555             :     /*
     556             :      * If this is a parameterized scan, we also need to enforce all the join
     557             :      * clauses available from the outer relation(s).
     558             :      *
     559             :      * For paranoia's sake, don't modify the stored baserestrictinfo list.
     560             :      */
     561      260066 :     if (best_path->param_info)
     562       18050 :         scan_clauses = list_concat_copy(scan_clauses,
     563       18050 :                                         best_path->param_info->ppi_clauses);
     564             : 
     565             :     /*
     566             :      * Detect whether we have any pseudoconstant quals to deal with.  Then, if
     567             :      * we'll need a gating Result node, it will be able to project, so there
     568             :      * are no requirements on the child's tlist.
     569             :      */
     570      260066 :     gating_clauses = get_gating_quals(root, scan_clauses);
     571      260066 :     if (gating_clauses)
     572        2524 :         flags = 0;
     573             : 
     574             :     /*
     575             :      * For table scans, rather than using the relation targetlist (which is
     576             :      * only those Vars actually needed by the query), we prefer to generate a
     577             :      * tlist containing all Vars in order.  This will allow the executor to
     578             :      * optimize away projection of the table tuples, if possible.
     579             :      *
     580             :      * But if the caller is going to ignore our tlist anyway, then don't
     581             :      * bother generating one at all.  We use an exact equality test here, so
     582             :      * that this only applies when CP_IGNORE_TLIST is the only flag set.
     583             :      */
     584      260066 :     if (flags == CP_IGNORE_TLIST)
     585             :     {
     586       69102 :         tlist = NULL;
     587             :     }
     588      190964 :     else if (use_physical_tlist(root, best_path, flags))
     589             :     {
     590       78772 :         if (best_path->pathtype == T_IndexOnlyScan)
     591             :         {
     592             :             /* For index-only scan, the preferred tlist is the index's */
     593        2854 :             tlist = copyObject(((IndexPath *) best_path)->indexinfo->indextlist);
     594             : 
     595             :             /*
     596             :              * Transfer sortgroupref data to the replacement tlist, if
     597             :              * requested (use_physical_tlist checked that this will work).
     598             :              */
     599        2854 :             if (flags & CP_LABEL_TLIST)
     600        1356 :                 apply_pathtarget_labeling_to_tlist(tlist, best_path->pathtarget);
     601             :         }
     602             :         else
     603             :         {
     604       75918 :             tlist = build_physical_tlist(root, rel);
     605       75918 :             if (tlist == NIL)
     606             :             {
     607             :                 /* Failed because of dropped cols, so use regular method */
     608         144 :                 tlist = build_path_tlist(root, best_path);
     609             :             }
     610             :             else
     611             :             {
     612             :                 /* As above, transfer sortgroupref data to replacement tlist */
     613       75774 :                 if (flags & CP_LABEL_TLIST)
     614        7196 :                     apply_pathtarget_labeling_to_tlist(tlist, best_path->pathtarget);
     615             :             }
     616             :         }
     617             :     }
     618             :     else
     619             :     {
     620      112192 :         tlist = build_path_tlist(root, best_path);
     621             :     }
     622             : 
     623      260066 :     switch (best_path->pathtype)
     624             :     {
     625             :         case T_SeqScan:
     626      114992 :             plan = (Plan *) create_seqscan_plan(root,
     627             :                                                 best_path,
     628             :                                                 tlist,
     629             :                                                 scan_clauses);
     630      114992 :             break;
     631             : 
     632             :         case T_SampleScan:
     633         180 :             plan = (Plan *) create_samplescan_plan(root,
     634             :                                                    best_path,
     635             :                                                    tlist,
     636             :                                                    scan_clauses);
     637         180 :             break;
     638             : 
     639             :         case T_IndexScan:
     640       72772 :             plan = (Plan *) create_indexscan_plan(root,
     641             :                                                   (IndexPath *) best_path,
     642             :                                                   tlist,
     643             :                                                   scan_clauses,
     644             :                                                   false);
     645       72772 :             break;
     646             : 
     647             :         case T_IndexOnlyScan:
     648        8046 :             plan = (Plan *) create_indexscan_plan(root,
     649             :                                                   (IndexPath *) best_path,
     650             :                                                   tlist,
     651             :                                                   scan_clauses,
     652             :                                                   true);
     653        8046 :             break;
     654             : 
     655             :         case T_BitmapHeapScan:
     656       19314 :             plan = (Plan *) create_bitmap_scan_plan(root,
     657             :                                                     (BitmapHeapPath *) best_path,
     658             :                                                     tlist,
     659             :                                                     scan_clauses);
     660       19314 :             break;
     661             : 
     662             :         case T_TidScan:
     663         410 :             plan = (Plan *) create_tidscan_plan(root,
     664             :                                                 (TidPath *) best_path,
     665             :                                                 tlist,
     666             :                                                 scan_clauses);
     667         410 :             break;
     668             : 
     669             :         case T_SubqueryScan:
     670        8278 :             plan = (Plan *) create_subqueryscan_plan(root,
     671             :                                                      (SubqueryScanPath *) best_path,
     672             :                                                      tlist,
     673             :                                                      scan_clauses);
     674        8278 :             break;
     675             : 
     676             :         case T_FunctionScan:
     677       28676 :             plan = (Plan *) create_functionscan_plan(root,
     678             :                                                      best_path,
     679             :                                                      tlist,
     680             :                                                      scan_clauses);
     681       28676 :             break;
     682             : 
     683             :         case T_TableFuncScan:
     684         144 :             plan = (Plan *) create_tablefuncscan_plan(root,
     685             :                                                       best_path,
     686             :                                                       tlist,
     687             :                                                       scan_clauses);
     688         144 :             break;
     689             : 
     690             :         case T_ValuesScan:
     691        3792 :             plan = (Plan *) create_valuesscan_plan(root,
     692             :                                                    best_path,
     693             :                                                    tlist,
     694             :                                                    scan_clauses);
     695        3792 :             break;
     696             : 
     697             :         case T_CteScan:
     698         876 :             plan = (Plan *) create_ctescan_plan(root,
     699             :                                                 best_path,
     700             :                                                 tlist,
     701             :                                                 scan_clauses);
     702         876 :             break;
     703             : 
     704             :         case T_NamedTuplestoreScan:
     705         256 :             plan = (Plan *) create_namedtuplestorescan_plan(root,
     706             :                                                             best_path,
     707             :                                                             tlist,
     708             :                                                             scan_clauses);
     709         256 :             break;
     710             : 
     711             :         case T_Result:
     712         590 :             plan = (Plan *) create_resultscan_plan(root,
     713             :                                                    best_path,
     714             :                                                    tlist,
     715             :                                                    scan_clauses);
     716         590 :             break;
     717             : 
     718             :         case T_WorkTableScan:
     719         320 :             plan = (Plan *) create_worktablescan_plan(root,
     720             :                                                       best_path,
     721             :                                                       tlist,
     722             :                                                       scan_clauses);
     723         320 :             break;
     724             : 
     725             :         case T_ForeignScan:
     726        1420 :             plan = (Plan *) create_foreignscan_plan(root,
     727             :                                                     (ForeignPath *) best_path,
     728             :                                                     tlist,
     729             :                                                     scan_clauses);
     730        1420 :             break;
     731             : 
     732             :         case T_CustomScan:
     733           0 :             plan = (Plan *) create_customscan_plan(root,
     734             :                                                    (CustomPath *) best_path,
     735             :                                                    tlist,
     736             :                                                    scan_clauses);
     737           0 :             break;
     738             : 
     739             :         default:
     740           0 :             elog(ERROR, "unrecognized node type: %d",
     741             :                  (int) best_path->pathtype);
     742             :             plan = NULL;        /* keep compiler quiet */
     743             :             break;
     744             :     }
     745             : 
     746             :     /*
     747             :      * If there are any pseudoconstant clauses attached to this node, insert a
     748             :      * gating Result node that evaluates the pseudoconstants as one-time
     749             :      * quals.
     750             :      */
     751      260066 :     if (gating_clauses)
     752        2524 :         plan = create_gating_plan(root, best_path, plan, gating_clauses);
     753             : 
     754      260066 :     return plan;
     755             : }
     756             : 
     757             : /*
     758             :  * Build a target list (ie, a list of TargetEntry) for the Path's output.
     759             :  *
     760             :  * This is almost just make_tlist_from_pathtarget(), but we also have to
     761             :  * deal with replacing nestloop params.
     762             :  */
     763             : static List *
     764      541276 : build_path_tlist(PlannerInfo *root, Path *path)
     765             : {
     766      541276 :     List       *tlist = NIL;
     767      541276 :     Index      *sortgrouprefs = path->pathtarget->sortgrouprefs;
     768      541276 :     int         resno = 1;
     769             :     ListCell   *v;
     770             : 
     771     2120156 :     foreach(v, path->pathtarget->exprs)
     772             :     {
     773     1578880 :         Node       *node = (Node *) lfirst(v);
     774             :         TargetEntry *tle;
     775             : 
     776             :         /*
     777             :          * If it's a parameterized path, there might be lateral references in
     778             :          * the tlist, which need to be replaced with Params.  There's no need
     779             :          * to remake the TargetEntry nodes, so apply this to each list item
     780             :          * separately.
     781             :          */
     782     1578880 :         if (path->param_info)
     783       10802 :             node = replace_nestloop_params(root, node);
     784             : 
     785     1578880 :         tle = makeTargetEntry((Expr *) node,
     786             :                               resno,
     787             :                               NULL,
     788             :                               false);
     789     1578880 :         if (sortgrouprefs)
     790     1053296 :             tle->ressortgroupref = sortgrouprefs[resno - 1];
     791             : 
     792     1578880 :         tlist = lappend(tlist, tle);
     793     1578880 :         resno++;
     794             :     }
     795      541276 :     return tlist;
     796             : }
     797             : 
     798             : /*
     799             :  * use_physical_tlist
     800             :  *      Decide whether to use a tlist matching relation structure,
     801             :  *      rather than only those Vars actually referenced.
     802             :  */
     803             : static bool
     804      404020 : use_physical_tlist(PlannerInfo *root, Path *path, int flags)
     805             : {
     806      404020 :     RelOptInfo *rel = path->parent;
     807             :     int         i;
     808             :     ListCell   *lc;
     809             : 
     810             :     /*
     811             :      * Forget it if either exact tlist or small tlist is demanded.
     812             :      */
     813      404020 :     if (flags & (CP_EXACT_TLIST | CP_SMALL_TLIST))
     814      308124 :         return false;
     815             : 
     816             :     /*
     817             :      * We can do this for real relation scans, subquery scans, function scans,
     818             :      * tablefunc scans, values scans, and CTE scans (but not for, eg, joins).
     819             :      */
     820      109222 :     if (rel->rtekind != RTE_RELATION &&
     821       25686 :         rel->rtekind != RTE_SUBQUERY &&
     822       17108 :         rel->rtekind != RTE_FUNCTION &&
     823        9400 :         rel->rtekind != RTE_TABLEFUNC &&
     824        8648 :         rel->rtekind != RTE_VALUES &&
     825        3996 :         rel->rtekind != RTE_CTE)
     826        3776 :         return false;
     827             : 
     828             :     /*
     829             :      * Can't do it with inheritance cases either (mainly because Append
     830             :      * doesn't project; this test may be unnecessary now that
     831             :      * create_append_plan instructs its children to return an exact tlist).
     832             :      */
     833       92120 :     if (rel->reloptkind != RELOPT_BASEREL)
     834        1426 :         return false;
     835             : 
     836             :     /*
     837             :      * Also, don't do it to a CustomPath; the premise that we're extracting
     838             :      * columns from a simple physical tuple is unlikely to hold for those.
     839             :      * (When it does make sense, the custom path creator can set up the path's
     840             :      * pathtarget that way.)
     841             :      */
     842       90694 :     if (IsA(path, CustomPath))
     843           0 :         return false;
     844             : 
     845             :     /*
     846             :      * If a bitmap scan's tlist is empty, keep it as-is.  This may allow the
     847             :      * executor to skip heap page fetches, and in any case, the benefit of
     848             :      * using a physical tlist instead would be minimal.
     849             :      */
     850       95112 :     if (IsA(path, BitmapHeapPath) &&
     851        4418 :         path->pathtarget->exprs == NIL)
     852        1486 :         return false;
     853             : 
     854             :     /*
     855             :      * Can't do it if any system columns or whole-row Vars are requested.
     856             :      * (This could possibly be fixed but would take some fragile assumptions
     857             :      * in setrefs.c, I think.)
     858             :      */
     859      618014 :     for (i = rel->min_attr; i <= 0; i++)
     860             :     {
     861      538738 :         if (!bms_is_empty(rel->attr_needed[i - rel->min_attr]))
     862        9932 :             return false;
     863             :     }
     864             : 
     865             :     /*
     866             :      * Can't do it if the rel is required to emit any placeholder expressions,
     867             :      * either.
     868             :      */
     869       79796 :     foreach(lc, root->placeholder_list)
     870             :     {
     871         602 :         PlaceHolderInfo *phinfo = (PlaceHolderInfo *) lfirst(lc);
     872             : 
     873        1180 :         if (bms_nonempty_difference(phinfo->ph_needed, rel->relids) &&
     874         578 :             bms_is_subset(phinfo->ph_eval_at, rel->relids))
     875          82 :             return false;
     876             :     }
     877             : 
     878             :     /*
     879             :      * Also, can't do it if CP_LABEL_TLIST is specified and path is requested
     880             :      * to emit any sort/group columns that are not simple Vars.  (If they are
     881             :      * simple Vars, they should appear in the physical tlist, and
     882             :      * apply_pathtarget_labeling_to_tlist will take care of getting them
     883             :      * labeled again.)  We also have to check that no two sort/group columns
     884             :      * are the same Var, else that element of the physical tlist would need
     885             :      * conflicting ressortgroupref labels.
     886             :      */
     887       79194 :     if ((flags & CP_LABEL_TLIST) && path->pathtarget->sortgrouprefs)
     888             :     {
     889         948 :         Bitmapset  *sortgroupatts = NULL;
     890             : 
     891         948 :         i = 0;
     892        2582 :         foreach(lc, path->pathtarget->exprs)
     893             :         {
     894        1762 :             Expr       *expr = (Expr *) lfirst(lc);
     895             : 
     896        1762 :             if (path->pathtarget->sortgrouprefs[i])
     897             :             {
     898        1354 :                 if (expr && IsA(expr, Var))
     899        1226 :                 {
     900        1236 :                     int         attno = ((Var *) expr)->varattno;
     901             : 
     902        1236 :                     attno -= FirstLowInvalidHeapAttributeNumber;
     903        1236 :                     if (bms_is_member(attno, sortgroupatts))
     904         138 :                         return false;
     905        1226 :                     sortgroupatts = bms_add_member(sortgroupatts, attno);
     906             :                 }
     907             :                 else
     908         118 :                     return false;
     909             :             }
     910        1634 :             i++;
     911             :         }
     912             :     }
     913             : 
     914       79066 :     return true;
     915             : }
     916             : 
     917             : /*
     918             :  * get_gating_quals
     919             :  *    See if there are pseudoconstant quals in a node's quals list
     920             :  *
     921             :  * If the node's quals list includes any pseudoconstant quals,
     922             :  * return just those quals.
     923             :  */
     924             : static List *
     925      320274 : get_gating_quals(PlannerInfo *root, List *quals)
     926             : {
     927             :     /* No need to look if we know there are no pseudoconstants */
     928      320274 :     if (!root->hasPseudoConstantQuals)
     929      317478 :         return NIL;
     930             : 
     931             :     /* Sort into desirable execution order while still in RestrictInfo form */
     932        2796 :     quals = order_qual_clauses(root, quals);
     933             : 
     934             :     /* Pull out any pseudoconstant quals from the RestrictInfo list */
     935        2796 :     return extract_actual_clauses(quals, true);
     936             : }
     937             : 
     938             : /*
     939             :  * create_gating_plan
     940             :  *    Deal with pseudoconstant qual clauses
     941             :  *
     942             :  * Add a gating Result node atop the already-built plan.
     943             :  */
     944             : static Plan *
     945        2536 : create_gating_plan(PlannerInfo *root, Path *path, Plan *plan,
     946             :                    List *gating_quals)
     947             : {
     948             :     Plan       *gplan;
     949             :     Plan       *splan;
     950             : 
     951             :     Assert(gating_quals);
     952             : 
     953             :     /*
     954             :      * We might have a trivial Result plan already.  Stacking one Result atop
     955             :      * another is silly, so if that applies, just discard the input plan.
     956             :      * (We're assuming its targetlist is uninteresting; it should be either
     957             :      * the same as the result of build_path_tlist, or a simplified version.)
     958             :      */
     959        2536 :     splan = plan;
     960        2536 :     if (IsA(plan, Result))
     961             :     {
     962          24 :         Result     *rplan = (Result *) plan;
     963             : 
     964          48 :         if (rplan->plan.lefttree == NULL &&
     965          24 :             rplan->resconstantqual == NULL)
     966          24 :             splan = NULL;
     967             :     }
     968             : 
     969             :     /*
     970             :      * Since we need a Result node anyway, always return the path's requested
     971             :      * tlist; that's never a wrong choice, even if the parent node didn't ask
     972             :      * for CP_EXACT_TLIST.
     973             :      */
     974        2536 :     gplan = (Plan *) make_result(build_path_tlist(root, path),
     975             :                                  (Node *) gating_quals,
     976             :                                  splan);
     977             : 
     978             :     /*
     979             :      * Notice that we don't change cost or size estimates when doing gating.
     980             :      * The costs of qual eval were already included in the subplan's cost.
     981             :      * Leaving the size alone amounts to assuming that the gating qual will
     982             :      * succeed, which is the conservative estimate for planning upper queries.
     983             :      * We certainly don't want to assume the output size is zero (unless the
     984             :      * gating qual is actually constant FALSE, and that case is dealt with in
     985             :      * clausesel.c).  Interpolating between the two cases is silly, because it
     986             :      * doesn't reflect what will really happen at runtime, and besides which
     987             :      * in most cases we have only a very bad idea of the probability of the
     988             :      * gating qual being true.
     989             :      */
     990        2536 :     copy_plan_costsize(gplan, plan);
     991             : 
     992             :     /* Gating quals could be unsafe, so better use the Path's safety flag */
     993        2536 :     gplan->parallel_safe = path->parallel_safe;
     994             : 
     995        2536 :     return gplan;
     996             : }
     997             : 
     998             : /*
     999             :  * create_join_plan
    1000             :  *    Create a join plan for 'best_path' and (recursively) plans for its
    1001             :  *    inner and outer paths.
    1002             :  */
    1003             : static Plan *
    1004       60208 : create_join_plan(PlannerInfo *root, JoinPath *best_path)
    1005             : {
    1006             :     Plan       *plan;
    1007             :     List       *gating_clauses;
    1008             : 
    1009       60208 :     switch (best_path->path.pathtype)
    1010             :     {
    1011             :         case T_MergeJoin:
    1012        2106 :             plan = (Plan *) create_mergejoin_plan(root,
    1013             :                                                   (MergePath *) best_path);
    1014        2106 :             break;
    1015             :         case T_HashJoin:
    1016       26632 :             plan = (Plan *) create_hashjoin_plan(root,
    1017             :                                                  (HashPath *) best_path);
    1018       26632 :             break;
    1019             :         case T_NestLoop:
    1020       31470 :             plan = (Plan *) create_nestloop_plan(root,
    1021             :                                                  (NestPath *) best_path);
    1022       31470 :             break;
    1023             :         default:
    1024           0 :             elog(ERROR, "unrecognized node type: %d",
    1025             :                  (int) best_path->path.pathtype);
    1026             :             plan = NULL;        /* keep compiler quiet */
    1027             :             break;
    1028             :     }
    1029             : 
    1030             :     /*
    1031             :      * If there are any pseudoconstant clauses attached to this node, insert a
    1032             :      * gating Result node that evaluates the pseudoconstants as one-time
    1033             :      * quals.
    1034             :      */
    1035       60208 :     gating_clauses = get_gating_quals(root, best_path->joinrestrictinfo);
    1036       60208 :     if (gating_clauses)
    1037          12 :         plan = create_gating_plan(root, (Path *) best_path, plan,
    1038             :                                   gating_clauses);
    1039             : 
    1040             : #ifdef NOT_USED
    1041             : 
    1042             :     /*
    1043             :      * * Expensive function pullups may have pulled local predicates * into
    1044             :      * this path node.  Put them in the qpqual of the plan node. * JMH,
    1045             :      * 6/15/92
    1046             :      */
    1047             :     if (get_loc_restrictinfo(best_path) != NIL)
    1048             :         set_qpqual((Plan) plan,
    1049             :                    list_concat(get_qpqual((Plan) plan),
    1050             :                                get_actual_clauses(get_loc_restrictinfo(best_path))));
    1051             : #endif
    1052             : 
    1053       60208 :     return plan;
    1054             : }
    1055             : 
    1056             : /*
    1057             :  * create_append_plan
    1058             :  *    Create an Append plan for 'best_path' and (recursively) plans
    1059             :  *    for its subpaths.
    1060             :  *
    1061             :  *    Returns a Plan node.
    1062             :  */
    1063             : static Plan *
    1064        9394 : create_append_plan(PlannerInfo *root, AppendPath *best_path, int flags)
    1065             : {
    1066             :     Append     *plan;
    1067        9394 :     List       *tlist = build_path_tlist(root, &best_path->path);
    1068        9394 :     int         orig_tlist_length = list_length(tlist);
    1069        9394 :     bool        tlist_was_changed = false;
    1070        9394 :     List       *pathkeys = best_path->path.pathkeys;
    1071        9394 :     List       *subplans = NIL;
    1072             :     ListCell   *subpaths;
    1073        9394 :     RelOptInfo *rel = best_path->path.parent;
    1074        9394 :     PartitionPruneInfo *partpruneinfo = NULL;
    1075        9394 :     int         nodenumsortkeys = 0;
    1076        9394 :     AttrNumber *nodeSortColIdx = NULL;
    1077        9394 :     Oid        *nodeSortOperators = NULL;
    1078        9394 :     Oid        *nodeCollations = NULL;
    1079        9394 :     bool       *nodeNullsFirst = NULL;
    1080             : 
    1081             :     /*
    1082             :      * The subpaths list could be empty, if every child was proven empty by
    1083             :      * constraint exclusion.  In that case generate a dummy plan that returns
    1084             :      * no rows.
    1085             :      *
    1086             :      * Note that an AppendPath with no members is also generated in certain
    1087             :      * cases where there was no appending construct at all, but we know the
    1088             :      * relation is empty (see set_dummy_rel_pathlist and mark_dummy_rel).
    1089             :      */
    1090        9394 :     if (best_path->subpaths == NIL)
    1091             :     {
    1092             :         /* Generate a Result plan with constant-FALSE gating qual */
    1093             :         Plan       *plan;
    1094             : 
    1095         368 :         plan = (Plan *) make_result(tlist,
    1096         368 :                                     (Node *) list_make1(makeBoolConst(false,
    1097             :                                                                       false)),
    1098             :                                     NULL);
    1099             : 
    1100         368 :         copy_generic_path_info(plan, (Path *) best_path);
    1101             : 
    1102         368 :         return plan;
    1103             :     }
    1104             : 
    1105             :     /*
    1106             :      * Otherwise build an Append plan.  Note that if there's just one child,
    1107             :      * the Append is pretty useless; but we wait till setrefs.c to get rid of
    1108             :      * it.  Doing so here doesn't work because the varno of the child scan
    1109             :      * plan won't match the parent-rel Vars it'll be asked to emit.
    1110             :      *
    1111             :      * We don't have the actual creation of the Append node split out into a
    1112             :      * separate make_xxx function.  This is because we want to run
    1113             :      * prepare_sort_from_pathkeys on it before we do so on the individual
    1114             :      * child plans, to make cross-checking the sort info easier.
    1115             :      */
    1116        9026 :     plan = makeNode(Append);
    1117        9026 :     plan->plan.targetlist = tlist;
    1118        9026 :     plan->plan.qual = NIL;
    1119        9026 :     plan->plan.lefttree = NULL;
    1120        9026 :     plan->plan.righttree = NULL;
    1121             : 
    1122        9026 :     if (pathkeys != NIL)
    1123             :     {
    1124             :         /*
    1125             :          * Compute sort column info, and adjust the Append's tlist as needed.
    1126             :          * Because we pass adjust_tlist_in_place = true, we may ignore the
    1127             :          * function result; it must be the same plan node.  However, we then
    1128             :          * need to detect whether any tlist entries were added.
    1129             :          */
    1130         104 :         (void) prepare_sort_from_pathkeys((Plan *) plan, pathkeys,
    1131         104 :                                           best_path->path.parent->relids,
    1132             :                                           NULL,
    1133             :                                           true,
    1134             :                                           &nodenumsortkeys,
    1135             :                                           &nodeSortColIdx,
    1136             :                                           &nodeSortOperators,
    1137             :                                           &nodeCollations,
    1138             :                                           &nodeNullsFirst);
    1139         104 :         tlist_was_changed = (orig_tlist_length != list_length(plan->plan.targetlist));
    1140             :     }
    1141             : 
    1142             :     /* Build the plan for each child */
    1143       28264 :     foreach(subpaths, best_path->subpaths)
    1144             :     {
    1145       19238 :         Path       *subpath = (Path *) lfirst(subpaths);
    1146             :         Plan       *subplan;
    1147             : 
    1148             :         /* Must insist that all children return the same tlist */
    1149       19238 :         subplan = create_plan_recurse(root, subpath, CP_EXACT_TLIST);
    1150             : 
    1151             :         /*
    1152             :          * For ordered Appends, we must insert a Sort node if subplan isn't
    1153             :          * sufficiently ordered.
    1154             :          */
    1155       19238 :         if (pathkeys != NIL)
    1156             :         {
    1157             :             int         numsortkeys;
    1158             :             AttrNumber *sortColIdx;
    1159             :             Oid        *sortOperators;
    1160             :             Oid        *collations;
    1161             :             bool       *nullsFirst;
    1162             : 
    1163             :             /*
    1164             :              * Compute sort column info, and adjust subplan's tlist as needed.
    1165             :              * We must apply prepare_sort_from_pathkeys even to subplans that
    1166             :              * don't need an explicit sort, to make sure they are returning
    1167             :              * the same sort key columns the Append expects.
    1168             :              */
    1169         536 :             subplan = prepare_sort_from_pathkeys(subplan, pathkeys,
    1170         268 :                                                  subpath->parent->relids,
    1171             :                                                  nodeSortColIdx,
    1172             :                                                  false,
    1173             :                                                  &numsortkeys,
    1174             :                                                  &sortColIdx,
    1175             :                                                  &sortOperators,
    1176             :                                                  &collations,
    1177             :                                                  &nullsFirst);
    1178             : 
    1179             :             /*
    1180             :              * Check that we got the same sort key information.  We just
    1181             :              * Assert that the sortops match, since those depend only on the
    1182             :              * pathkeys; but it seems like a good idea to check the sort
    1183             :              * column numbers explicitly, to ensure the tlists match up.
    1184             :              */
    1185             :             Assert(numsortkeys == nodenumsortkeys);
    1186         268 :             if (memcmp(sortColIdx, nodeSortColIdx,
    1187             :                        numsortkeys * sizeof(AttrNumber)) != 0)
    1188           0 :                 elog(ERROR, "Append child's targetlist doesn't match Append");
    1189             :             Assert(memcmp(sortOperators, nodeSortOperators,
    1190             :                           numsortkeys * sizeof(Oid)) == 0);
    1191             :             Assert(memcmp(collations, nodeCollations,
    1192             :                           numsortkeys * sizeof(Oid)) == 0);
    1193             :             Assert(memcmp(nullsFirst, nodeNullsFirst,
    1194             :                           numsortkeys * sizeof(bool)) == 0);
    1195             : 
    1196             :             /* Now, insert a Sort node if subplan isn't sufficiently ordered */
    1197         268 :             if (!pathkeys_contained_in(pathkeys, subpath->pathkeys))
    1198             :             {
    1199           4 :                 Sort       *sort = make_sort(subplan, numsortkeys,
    1200             :                                              sortColIdx, sortOperators,
    1201             :                                              collations, nullsFirst);
    1202             : 
    1203           4 :                 label_sort_with_costsize(root, sort, best_path->limit_tuples);
    1204           4 :                 subplan = (Plan *) sort;
    1205             :             }
    1206             :         }
    1207             : 
    1208       19238 :         subplans = lappend(subplans, subplan);
    1209             :     }
    1210             : 
    1211             :     /*
    1212             :      * If any quals exist, they may be useful to perform further partition
    1213             :      * pruning during execution.  Gather information needed by the executor to
    1214             :      * do partition pruning.
    1215             :      */
    1216       18040 :     if (enable_partition_pruning &&
    1217       16478 :         rel->reloptkind == RELOPT_BASEREL &&
    1218        7464 :         best_path->partitioned_rels != NIL)
    1219             :     {
    1220             :         List       *prunequal;
    1221             : 
    1222        4640 :         prunequal = extract_actual_clauses(rel->baserestrictinfo, false);
    1223             : 
    1224        4640 :         if (best_path->path.param_info)
    1225             :         {
    1226          82 :             List       *prmquals = best_path->path.param_info->ppi_clauses;
    1227             : 
    1228          82 :             prmquals = extract_actual_clauses(prmquals, false);
    1229          82 :             prmquals = (List *) replace_nestloop_params(root,
    1230             :                                                         (Node *) prmquals);
    1231             : 
    1232          82 :             prunequal = list_concat(prunequal, prmquals);
    1233             :         }
    1234             : 
    1235        4640 :         if (prunequal != NIL)
    1236        4014 :             partpruneinfo =
    1237        4014 :                 make_partition_pruneinfo(root, rel,
    1238             :                                          best_path->subpaths,
    1239             :                                          best_path->partitioned_rels,
    1240             :                                          prunequal);
    1241             :     }
    1242             : 
    1243        9026 :     plan->appendplans = subplans;
    1244        9026 :     plan->first_partial_plan = best_path->first_partial_path;
    1245        9026 :     plan->part_prune_info = partpruneinfo;
    1246             : 
    1247        9026 :     copy_generic_path_info(&plan->plan, (Path *) best_path);
    1248             : 
    1249             :     /*
    1250             :      * If prepare_sort_from_pathkeys added sort columns, but we were told to
    1251             :      * produce either the exact tlist or a narrow tlist, we should get rid of
    1252             :      * the sort columns again.  We must inject a projection node to do so.
    1253             :      */
    1254        9026 :     if (tlist_was_changed && (flags & (CP_EXACT_TLIST | CP_SMALL_TLIST)))
    1255             :     {
    1256           0 :         tlist = list_truncate(list_copy(plan->plan.targetlist),
    1257             :                               orig_tlist_length);
    1258           0 :         return inject_projection_plan((Plan *) plan, tlist,
    1259           0 :                                       plan->plan.parallel_safe);
    1260             :     }
    1261             :     else
    1262        9026 :         return (Plan *) plan;
    1263             : }
    1264             : 
    1265             : /*
    1266             :  * create_merge_append_plan
    1267             :  *    Create a MergeAppend plan for 'best_path' and (recursively) plans
    1268             :  *    for its subpaths.
    1269             :  *
    1270             :  *    Returns a Plan node.
    1271             :  */
    1272             : static Plan *
    1273         236 : create_merge_append_plan(PlannerInfo *root, MergeAppendPath *best_path,
    1274             :                          int flags)
    1275             : {
    1276         236 :     MergeAppend *node = makeNode(MergeAppend);
    1277         236 :     Plan       *plan = &node->plan;
    1278         236 :     List       *tlist = build_path_tlist(root, &best_path->path);
    1279         236 :     int         orig_tlist_length = list_length(tlist);
    1280             :     bool        tlist_was_changed;
    1281         236 :     List       *pathkeys = best_path->path.pathkeys;
    1282         236 :     List       *subplans = NIL;
    1283             :     ListCell   *subpaths;
    1284         236 :     RelOptInfo *rel = best_path->path.parent;
    1285         236 :     PartitionPruneInfo *partpruneinfo = NULL;
    1286             : 
    1287             :     /*
    1288             :      * We don't have the actual creation of the MergeAppend node split out
    1289             :      * into a separate make_xxx function.  This is because we want to run
    1290             :      * prepare_sort_from_pathkeys on it before we do so on the individual
    1291             :      * child plans, to make cross-checking the sort info easier.
    1292             :      */
    1293         236 :     copy_generic_path_info(plan, (Path *) best_path);
    1294         236 :     plan->targetlist = tlist;
    1295         236 :     plan->qual = NIL;
    1296         236 :     plan->lefttree = NULL;
    1297         236 :     plan->righttree = NULL;
    1298             : 
    1299             :     /*
    1300             :      * Compute sort column info, and adjust MergeAppend's tlist as needed.
    1301             :      * Because we pass adjust_tlist_in_place = true, we may ignore the
    1302             :      * function result; it must be the same plan node.  However, we then need
    1303             :      * to detect whether any tlist entries were added.
    1304             :      */
    1305         472 :     (void) prepare_sort_from_pathkeys(plan, pathkeys,
    1306         236 :                                       best_path->path.parent->relids,
    1307             :                                       NULL,
    1308             :                                       true,
    1309             :                                       &node->numCols,
    1310             :                                       &node->sortColIdx,
    1311             :                                       &node->sortOperators,
    1312             :                                       &node->collations,
    1313             :                                       &node->nullsFirst);
    1314         236 :     tlist_was_changed = (orig_tlist_length != list_length(plan->targetlist));
    1315             : 
    1316             :     /*
    1317             :      * Now prepare the child plans.  We must apply prepare_sort_from_pathkeys
    1318             :      * even to subplans that don't need an explicit sort, to make sure they
    1319             :      * are returning the same sort key columns the MergeAppend expects.
    1320             :      */
    1321         948 :     foreach(subpaths, best_path->subpaths)
    1322             :     {
    1323         712 :         Path       *subpath = (Path *) lfirst(subpaths);
    1324             :         Plan       *subplan;
    1325             :         int         numsortkeys;
    1326             :         AttrNumber *sortColIdx;
    1327             :         Oid        *sortOperators;
    1328             :         Oid        *collations;
    1329             :         bool       *nullsFirst;
    1330             : 
    1331             :         /* Build the child plan */
    1332             :         /* Must insist that all children return the same tlist */
    1333         712 :         subplan = create_plan_recurse(root, subpath, CP_EXACT_TLIST);
    1334             : 
    1335             :         /* Compute sort column info, and adjust subplan's tlist as needed */
    1336         712 :         subplan = prepare_sort_from_pathkeys(subplan, pathkeys,
    1337         712 :                                              subpath->parent->relids,
    1338         712 :                                              node->sortColIdx,
    1339             :                                              false,
    1340             :                                              &numsortkeys,
    1341             :                                              &sortColIdx,
    1342             :                                              &sortOperators,
    1343             :                                              &collations,
    1344             :                                              &nullsFirst);
    1345             : 
    1346             :         /*
    1347             :          * Check that we got the same sort key information.  We just Assert
    1348             :          * that the sortops match, since those depend only on the pathkeys;
    1349             :          * but it seems like a good idea to check the sort column numbers
    1350             :          * explicitly, to ensure the tlists really do match up.
    1351             :          */
    1352             :         Assert(numsortkeys == node->numCols);
    1353         712 :         if (memcmp(sortColIdx, node->sortColIdx,
    1354             :                    numsortkeys * sizeof(AttrNumber)) != 0)
    1355           0 :             elog(ERROR, "MergeAppend child's targetlist doesn't match MergeAppend");
    1356             :         Assert(memcmp(sortOperators, node->sortOperators,
    1357             :                       numsortkeys * sizeof(Oid)) == 0);
    1358             :         Assert(memcmp(collations, node->collations,
    1359             :                       numsortkeys * sizeof(Oid)) == 0);
    1360             :         Assert(memcmp(nullsFirst, node->nullsFirst,
    1361             :                       numsortkeys * sizeof(bool)) == 0);
    1362             : 
    1363             :         /* Now, insert a Sort node if subplan isn't sufficiently ordered */
    1364         712 :         if (!pathkeys_contained_in(pathkeys, subpath->pathkeys))
    1365             :         {
    1366          40 :             Sort       *sort = make_sort(subplan, numsortkeys,
    1367             :                                          sortColIdx, sortOperators,
    1368             :                                          collations, nullsFirst);
    1369             : 
    1370          40 :             label_sort_with_costsize(root, sort, best_path->limit_tuples);
    1371          40 :             subplan = (Plan *) sort;
    1372             :         }
    1373             : 
    1374         712 :         subplans = lappend(subplans, subplan);
    1375             :     }
    1376             : 
    1377             :     /*
    1378             :      * If any quals exist, they may be useful to perform further partition
    1379             :      * pruning during execution.  Gather information needed by the executor to
    1380             :      * do partition pruning.
    1381             :      */
    1382         472 :     if (enable_partition_pruning &&
    1383         416 :         rel->reloptkind == RELOPT_BASEREL &&
    1384         180 :         best_path->partitioned_rels != NIL)
    1385             :     {
    1386             :         List       *prunequal;
    1387             : 
    1388          36 :         prunequal = extract_actual_clauses(rel->baserestrictinfo, false);
    1389             : 
    1390          36 :         if (best_path->path.param_info)
    1391             :         {
    1392           0 :             List       *prmquals = best_path->path.param_info->ppi_clauses;
    1393             : 
    1394           0 :             prmquals = extract_actual_clauses(prmquals, false);
    1395           0 :             prmquals = (List *) replace_nestloop_params(root,
    1396             :                                                         (Node *) prmquals);
    1397             : 
    1398           0 :             prunequal = list_concat(prunequal, prmquals);
    1399             :         }
    1400             : 
    1401          36 :         if (prunequal != NIL)
    1402           8 :             partpruneinfo = make_partition_pruneinfo(root, rel,
    1403             :                                                      best_path->subpaths,
    1404             :                                                      best_path->partitioned_rels,
    1405             :                                                      prunequal);
    1406             :     }
    1407             : 
    1408         236 :     node->mergeplans = subplans;
    1409         236 :     node->part_prune_info = partpruneinfo;
    1410             : 
    1411             :     /*
    1412             :      * If prepare_sort_from_pathkeys added sort columns, but we were told to
    1413             :      * produce either the exact tlist or a narrow tlist, we should get rid of
    1414             :      * the sort columns again.  We must inject a projection node to do so.
    1415             :      */
    1416         236 :     if (tlist_was_changed && (flags & (CP_EXACT_TLIST | CP_SMALL_TLIST)))
    1417             :     {
    1418           0 :         tlist = list_truncate(list_copy(plan->targetlist), orig_tlist_length);
    1419           0 :         return inject_projection_plan(plan, tlist, plan->parallel_safe);
    1420             :     }
    1421             :     else
    1422         236 :         return plan;
    1423             : }
    1424             : 
    1425             : /*
    1426             :  * create_group_result_plan
    1427             :  *    Create a Result plan for 'best_path'.
    1428             :  *    This is only used for degenerate grouping cases.
    1429             :  *
    1430             :  *    Returns a Plan node.
    1431             :  */
    1432             : static Result *
    1433      112330 : create_group_result_plan(PlannerInfo *root, GroupResultPath *best_path)
    1434             : {
    1435             :     Result     *plan;
    1436             :     List       *tlist;
    1437             :     List       *quals;
    1438             : 
    1439      112330 :     tlist = build_path_tlist(root, &best_path->path);
    1440             : 
    1441             :     /* best_path->quals is just bare clauses */
    1442      112330 :     quals = order_qual_clauses(root, best_path->quals);
    1443             : 
    1444      112330 :     plan = make_result(tlist, (Node *) quals, NULL);
    1445             : 
    1446      112330 :     copy_generic_path_info(&plan->plan, (Path *) best_path);
    1447             : 
    1448      112330 :     return plan;
    1449             : }
    1450             : 
    1451             : /*
    1452             :  * create_project_set_plan
    1453             :  *    Create a ProjectSet plan for 'best_path'.
    1454             :  *
    1455             :  *    Returns a Plan node.
    1456             :  */
    1457             : static ProjectSet *
    1458        3686 : create_project_set_plan(PlannerInfo *root, ProjectSetPath *best_path)
    1459             : {
    1460             :     ProjectSet *plan;
    1461             :     Plan       *subplan;
    1462             :     List       *tlist;
    1463             : 
    1464             :     /* Since we intend to project, we don't need to constrain child tlist */
    1465        3686 :     subplan = create_plan_recurse(root, best_path->subpath, 0);
    1466             : 
    1467        3686 :     tlist = build_path_tlist(root, &best_path->path);
    1468             : 
    1469        3686 :     plan = make_project_set(tlist, subplan);
    1470             : 
    1471        3686 :     copy_generic_path_info(&plan->plan, (Path *) best_path);
    1472             : 
    1473        3686 :     return plan;
    1474             : }
    1475             : 
    1476             : /*
    1477             :  * create_material_plan
    1478             :  *    Create a Material plan for 'best_path' and (recursively) plans
    1479             :  *    for its subpaths.
    1480             :  *
    1481             :  *    Returns a Plan node.
    1482             :  */
    1483             : static Material *
    1484        2656 : create_material_plan(PlannerInfo *root, MaterialPath *best_path, int flags)
    1485             : {
    1486             :     Material   *plan;
    1487             :     Plan       *subplan;
    1488             : 
    1489             :     /*
    1490             :      * We don't want any excess columns in the materialized tuples, so request
    1491             :      * a smaller tlist.  Otherwise, since Material doesn't project, tlist
    1492             :      * requirements pass through.
    1493             :      */
    1494        2656 :     subplan = create_plan_recurse(root, best_path->subpath,
    1495             :                                   flags | CP_SMALL_TLIST);
    1496             : 
    1497        2656 :     plan = make_material(subplan);
    1498             : 
    1499        2656 :     copy_generic_path_info(&plan->plan, (Path *) best_path);
    1500             : 
    1501        2656 :     return plan;
    1502             : }
    1503             : 
    1504             : /*
    1505             :  * create_unique_plan
    1506             :  *    Create a Unique plan for 'best_path' and (recursively) plans
    1507             :  *    for its subpaths.
    1508             :  *
    1509             :  *    Returns a Plan node.
    1510             :  */
    1511             : static Plan *
    1512         200 : create_unique_plan(PlannerInfo *root, UniquePath *best_path, int flags)
    1513             : {
    1514             :     Plan       *plan;
    1515             :     Plan       *subplan;
    1516             :     List       *in_operators;
    1517             :     List       *uniq_exprs;
    1518             :     List       *newtlist;
    1519             :     int         nextresno;
    1520             :     bool        newitems;
    1521             :     int         numGroupCols;
    1522             :     AttrNumber *groupColIdx;
    1523             :     Oid        *groupCollations;
    1524             :     int         groupColPos;
    1525             :     ListCell   *l;
    1526             : 
    1527             :     /* Unique doesn't project, so tlist requirements pass through */
    1528         200 :     subplan = create_plan_recurse(root, best_path->subpath, flags);
    1529             : 
    1530             :     /* Done if we don't need to do any actual unique-ifying */
    1531         200 :     if (best_path->umethod == UNIQUE_PATH_NOOP)
    1532           0 :         return subplan;
    1533             : 
    1534             :     /*
    1535             :      * As constructed, the subplan has a "flat" tlist containing just the Vars
    1536             :      * needed here and at upper levels.  The values we are supposed to
    1537             :      * unique-ify may be expressions in these variables.  We have to add any
    1538             :      * such expressions to the subplan's tlist.
    1539             :      *
    1540             :      * The subplan may have a "physical" tlist if it is a simple scan plan. If
    1541             :      * we're going to sort, this should be reduced to the regular tlist, so
    1542             :      * that we don't sort more data than we need to.  For hashing, the tlist
    1543             :      * should be left as-is if we don't need to add any expressions; but if we
    1544             :      * do have to add expressions, then a projection step will be needed at
    1545             :      * runtime anyway, so we may as well remove unneeded items. Therefore
    1546             :      * newtlist starts from build_path_tlist() not just a copy of the
    1547             :      * subplan's tlist; and we don't install it into the subplan unless we are
    1548             :      * sorting or stuff has to be added.
    1549             :      */
    1550         200 :     in_operators = best_path->in_operators;
    1551         200 :     uniq_exprs = best_path->uniq_exprs;
    1552             : 
    1553             :     /* initialize modified subplan tlist as just the "required" vars */
    1554         200 :     newtlist = build_path_tlist(root, &best_path->path);
    1555         200 :     nextresno = list_length(newtlist) + 1;
    1556         200 :     newitems = false;
    1557             : 
    1558         416 :     foreach(l, uniq_exprs)
    1559             :     {
    1560         216 :         Expr       *uniqexpr = lfirst(l);
    1561             :         TargetEntry *tle;
    1562             : 
    1563         216 :         tle = tlist_member(uniqexpr, newtlist);
    1564         216 :         if (!tle)
    1565             :         {
    1566          24 :             tle = makeTargetEntry((Expr *) uniqexpr,
    1567             :                                   nextresno,
    1568             :                                   NULL,
    1569             :                                   false);
    1570          24 :             newtlist = lappend(newtlist, tle);
    1571          24 :             nextresno++;
    1572          24 :             newitems = true;
    1573             :         }
    1574             :     }
    1575             : 
    1576             :     /* Use change_plan_targetlist in case we need to insert a Result node */
    1577         200 :     if (newitems || best_path->umethod == UNIQUE_PATH_SORT)
    1578          26 :         subplan = change_plan_targetlist(subplan, newtlist,
    1579          26 :                                          best_path->path.parallel_safe);
    1580             : 
    1581             :     /*
    1582             :      * Build control information showing which subplan output columns are to
    1583             :      * be examined by the grouping step.  Unfortunately we can't merge this
    1584             :      * with the previous loop, since we didn't then know which version of the
    1585             :      * subplan tlist we'd end up using.
    1586             :      */
    1587         200 :     newtlist = subplan->targetlist;
    1588         200 :     numGroupCols = list_length(uniq_exprs);
    1589         200 :     groupColIdx = (AttrNumber *) palloc(numGroupCols * sizeof(AttrNumber));
    1590         200 :     groupCollations = (Oid *) palloc(numGroupCols * sizeof(Oid));
    1591             : 
    1592         200 :     groupColPos = 0;
    1593         416 :     foreach(l, uniq_exprs)
    1594             :     {
    1595         216 :         Expr       *uniqexpr = lfirst(l);
    1596             :         TargetEntry *tle;
    1597             : 
    1598         216 :         tle = tlist_member(uniqexpr, newtlist);
    1599         216 :         if (!tle)               /* shouldn't happen */
    1600           0 :             elog(ERROR, "failed to find unique expression in subplan tlist");
    1601         216 :         groupColIdx[groupColPos] = tle->resno;
    1602         216 :         groupCollations[groupColPos] = exprCollation((Node *) tle->expr);
    1603         216 :         groupColPos++;
    1604             :     }
    1605             : 
    1606         200 :     if (best_path->umethod == UNIQUE_PATH_HASH)
    1607             :     {
    1608             :         Oid        *groupOperators;
    1609             : 
    1610             :         /*
    1611             :          * Get the hashable equality operators for the Agg node to use.
    1612             :          * Normally these are the same as the IN clause operators, but if
    1613             :          * those are cross-type operators then the equality operators are the
    1614             :          * ones for the IN clause operators' RHS datatype.
    1615             :          */
    1616         198 :         groupOperators = (Oid *) palloc(numGroupCols * sizeof(Oid));
    1617         198 :         groupColPos = 0;
    1618         412 :         foreach(l, in_operators)
    1619             :         {
    1620         214 :             Oid         in_oper = lfirst_oid(l);
    1621             :             Oid         eq_oper;
    1622             : 
    1623         214 :             if (!get_compatible_hash_operators(in_oper, NULL, &eq_oper))
    1624           0 :                 elog(ERROR, "could not find compatible hash operator for operator %u",
    1625             :                      in_oper);
    1626         214 :             groupOperators[groupColPos++] = eq_oper;
    1627             :         }
    1628             : 
    1629             :         /*
    1630             :          * Since the Agg node is going to project anyway, we can give it the
    1631             :          * minimum output tlist, without any stuff we might have added to the
    1632             :          * subplan tlist.
    1633             :          */
    1634         198 :         plan = (Plan *) make_agg(build_path_tlist(root, &best_path->path),
    1635             :                                  NIL,
    1636             :                                  AGG_HASHED,
    1637             :                                  AGGSPLIT_SIMPLE,
    1638             :                                  numGroupCols,
    1639             :                                  groupColIdx,
    1640             :                                  groupOperators,
    1641             :                                  groupCollations,
    1642             :                                  NIL,
    1643             :                                  NIL,
    1644             :                                  best_path->path.rows,
    1645             :                                  subplan);
    1646             :     }
    1647             :     else
    1648             :     {
    1649           2 :         List       *sortList = NIL;
    1650             :         Sort       *sort;
    1651             : 
    1652             :         /* Create an ORDER BY list to sort the input compatibly */
    1653           2 :         groupColPos = 0;
    1654           4 :         foreach(l, in_operators)
    1655             :         {
    1656           2 :             Oid         in_oper = lfirst_oid(l);
    1657             :             Oid         sortop;
    1658             :             Oid         eqop;
    1659             :             TargetEntry *tle;
    1660             :             SortGroupClause *sortcl;
    1661             : 
    1662           2 :             sortop = get_ordering_op_for_equality_op(in_oper, false);
    1663           2 :             if (!OidIsValid(sortop))    /* shouldn't happen */
    1664           0 :                 elog(ERROR, "could not find ordering operator for equality operator %u",
    1665             :                      in_oper);
    1666             : 
    1667             :             /*
    1668             :              * The Unique node will need equality operators.  Normally these
    1669             :              * are the same as the IN clause operators, but if those are
    1670             :              * cross-type operators then the equality operators are the ones
    1671             :              * for the IN clause operators' RHS datatype.
    1672             :              */
    1673           2 :             eqop = get_equality_op_for_ordering_op(sortop, NULL);
    1674           2 :             if (!OidIsValid(eqop))  /* shouldn't happen */
    1675           0 :                 elog(ERROR, "could not find equality operator for ordering operator %u",
    1676             :                      sortop);
    1677             : 
    1678           2 :             tle = get_tle_by_resno(subplan->targetlist,
    1679           2 :                                    groupColIdx[groupColPos]);
    1680             :             Assert(tle != NULL);
    1681             : 
    1682           2 :             sortcl = makeNode(SortGroupClause);
    1683           2 :             sortcl->tleSortGroupRef = assignSortGroupRef(tle,
    1684             :                                                          subplan->targetlist);
    1685           2 :             sortcl->eqop = eqop;
    1686           2 :             sortcl->sortop = sortop;
    1687           2 :             sortcl->nulls_first = false;
    1688           2 :             sortcl->hashable = false;    /* no need to make this accurate */
    1689           2 :             sortList = lappend(sortList, sortcl);
    1690           2 :             groupColPos++;
    1691             :         }
    1692           2 :         sort = make_sort_from_sortclauses(sortList, subplan);
    1693           2 :         label_sort_with_costsize(root, sort, -1.0);
    1694           2 :         plan = (Plan *) make_unique_from_sortclauses((Plan *) sort, sortList);
    1695             :     }
    1696             : 
    1697             :     /* Copy cost data from Path to Plan */
    1698         200 :     copy_generic_path_info(plan, &best_path->path);
    1699             : 
    1700         200 :     return plan;
    1701             : }
    1702             : 
    1703             : /*
    1704             :  * create_gather_plan
    1705             :  *
    1706             :  *    Create a Gather plan for 'best_path' and (recursively) plans
    1707             :  *    for its subpaths.
    1708             :  */
    1709             : static Gather *
    1710         488 : create_gather_plan(PlannerInfo *root, GatherPath *best_path)
    1711             : {
    1712             :     Gather     *gather_plan;
    1713             :     Plan       *subplan;
    1714             :     List       *tlist;
    1715             : 
    1716             :     /*
    1717             :      * Although the Gather node can project, we prefer to push down such work
    1718             :      * to its child node, so demand an exact tlist from the child.
    1719             :      */
    1720         488 :     subplan = create_plan_recurse(root, best_path->subpath, CP_EXACT_TLIST);
    1721             : 
    1722         488 :     tlist = build_path_tlist(root, &best_path->path);
    1723             : 
    1724         488 :     gather_plan = make_gather(tlist,
    1725             :                               NIL,
    1726             :                               best_path->num_workers,
    1727             :                               assign_special_exec_param(root),
    1728         488 :                               best_path->single_copy,
    1729             :                               subplan);
    1730             : 
    1731         488 :     copy_generic_path_info(&gather_plan->plan, &best_path->path);
    1732             : 
    1733             :     /* use parallel mode for parallel plans. */
    1734         488 :     root->glob->parallelModeNeeded = true;
    1735             : 
    1736         488 :     return gather_plan;
    1737             : }
    1738             : 
    1739             : /*
    1740             :  * create_gather_merge_plan
    1741             :  *
    1742             :  *    Create a Gather Merge plan for 'best_path' and (recursively)
    1743             :  *    plans for its subpaths.
    1744             :  */
    1745             : static GatherMerge *
    1746         136 : create_gather_merge_plan(PlannerInfo *root, GatherMergePath *best_path)
    1747             : {
    1748             :     GatherMerge *gm_plan;
    1749             :     Plan       *subplan;
    1750         136 :     List       *pathkeys = best_path->path.pathkeys;
    1751         136 :     List       *tlist = build_path_tlist(root, &best_path->path);
    1752             : 
    1753             :     /* As with Gather, it's best to project away columns in the workers. */
    1754         136 :     subplan = create_plan_recurse(root, best_path->subpath, CP_EXACT_TLIST);
    1755             : 
    1756             :     /* Create a shell for a GatherMerge plan. */
    1757         136 :     gm_plan = makeNode(GatherMerge);
    1758         136 :     gm_plan->plan.targetlist = tlist;
    1759         136 :     gm_plan->num_workers = best_path->num_workers;
    1760         136 :     copy_generic_path_info(&gm_plan->plan, &best_path->path);
    1761             : 
    1762             :     /* Assign the rescan Param. */
    1763         136 :     gm_plan->rescan_param = assign_special_exec_param(root);
    1764             : 
    1765             :     /* Gather Merge is pointless with no pathkeys; use Gather instead. */
    1766             :     Assert(pathkeys != NIL);
    1767             : 
    1768             :     /* Compute sort column info, and adjust subplan's tlist as needed */
    1769         272 :     subplan = prepare_sort_from_pathkeys(subplan, pathkeys,
    1770         136 :                                          best_path->subpath->parent->relids,
    1771         136 :                                          gm_plan->sortColIdx,
    1772             :                                          false,
    1773             :                                          &gm_plan->numCols,
    1774             :                                          &gm_plan->sortColIdx,
    1775             :                                          &gm_plan->sortOperators,
    1776             :                                          &gm_plan->collations,
    1777             :                                          &gm_plan->nullsFirst);
    1778             : 
    1779             : 
    1780             :     /* Now, insert a Sort node if subplan isn't sufficiently ordered */
    1781         136 :     if (!pathkeys_contained_in(pathkeys, best_path->subpath->pathkeys))
    1782           0 :         subplan = (Plan *) make_sort(subplan, gm_plan->numCols,
    1783             :                                      gm_plan->sortColIdx,
    1784             :                                      gm_plan->sortOperators,
    1785             :                                      gm_plan->collations,
    1786             :                                      gm_plan->nullsFirst);
    1787             : 
    1788             :     /* Now insert the subplan under GatherMerge. */
    1789         136 :     gm_plan->plan.lefttree = subplan;
    1790             : 
    1791             :     /* use parallel mode for parallel plans. */
    1792         136 :     root->glob->parallelModeNeeded = true;
    1793             : 
    1794         136 :     return gm_plan;
    1795             : }
    1796             : 
    1797             : /*
    1798             :  * create_projection_plan
    1799             :  *
    1800             :  *    Create a plan tree to do a projection step and (recursively) plans
    1801             :  *    for its subpaths.  We may need a Result node for the projection,
    1802             :  *    but sometimes we can just let the subplan do the work.
    1803             :  */
    1804             : static Plan *
    1805      213056 : create_projection_plan(PlannerInfo *root, ProjectionPath *best_path, int flags)
    1806             : {
    1807             :     Plan       *plan;
    1808             :     Plan       *subplan;
    1809             :     List       *tlist;
    1810      213056 :     bool        needs_result_node = false;
    1811             : 
    1812             :     /*
    1813             :      * Convert our subpath to a Plan and determine whether we need a Result
    1814             :      * node.
    1815             :      *
    1816             :      * In most cases where we don't need to project, creation_projection_path
    1817             :      * will have set dummypp, but not always.  First, some createplan.c
    1818             :      * routines change the tlists of their nodes.  (An example is that
    1819             :      * create_merge_append_plan might add resjunk sort columns to a
    1820             :      * MergeAppend.)  Second, create_projection_path has no way of knowing
    1821             :      * what path node will be placed on top of the projection path and
    1822             :      * therefore can't predict whether it will require an exact tlist. For
    1823             :      * both of these reasons, we have to recheck here.
    1824             :      */
    1825      213056 :     if (use_physical_tlist(root, &best_path->path, flags))
    1826             :     {
    1827             :         /*
    1828             :          * Our caller doesn't really care what tlist we return, so we don't
    1829             :          * actually need to project.  However, we may still need to ensure
    1830             :          * proper sortgroupref labels, if the caller cares about those.
    1831             :          */
    1832         294 :         subplan = create_plan_recurse(root, best_path->subpath, 0);
    1833         294 :         tlist = subplan->targetlist;
    1834         294 :         if (flags & CP_LABEL_TLIST)
    1835          96 :             apply_pathtarget_labeling_to_tlist(tlist,
    1836             :                                                best_path->path.pathtarget);
    1837             :     }
    1838      212762 :     else if (is_projection_capable_path(best_path->subpath))
    1839             :     {
    1840             :         /*
    1841             :          * Our caller requires that we return the exact tlist, but no separate
    1842             :          * result node is needed because the subpath is projection-capable.
    1843             :          * Tell create_plan_recurse that we're going to ignore the tlist it
    1844             :          * produces.
    1845             :          */
    1846      206780 :         subplan = create_plan_recurse(root, best_path->subpath,
    1847             :                                       CP_IGNORE_TLIST);
    1848      206780 :         tlist = build_path_tlist(root, &best_path->path);
    1849             :     }
    1850             :     else
    1851             :     {
    1852             :         /*
    1853             :          * It looks like we need a result node, unless by good fortune the
    1854             :          * requested tlist is exactly the one the child wants to produce.
    1855             :          */
    1856        5982 :         subplan = create_plan_recurse(root, best_path->subpath, 0);
    1857        5982 :         tlist = build_path_tlist(root, &best_path->path);
    1858        5982 :         needs_result_node = !tlist_same_exprs(tlist, subplan->targetlist);
    1859             :     }
    1860             : 
    1861             :     /*
    1862             :      * If we make a different decision about whether to include a Result node
    1863             :      * than create_projection_path did, we'll have made slightly wrong cost
    1864             :      * estimates; but label the plan with the cost estimates we actually used,
    1865             :      * not "corrected" ones.  (XXX this could be cleaned up if we moved more
    1866             :      * of the sortcolumn setup logic into Path creation, but that would add
    1867             :      * expense to creating Paths we might end up not using.)
    1868             :      */
    1869      213056 :     if (!needs_result_node)
    1870             :     {
    1871             :         /* Don't need a separate Result, just assign tlist to subplan */
    1872      212256 :         plan = subplan;
    1873      212256 :         plan->targetlist = tlist;
    1874             : 
    1875             :         /* Label plan with the estimated costs we actually used */
    1876      212256 :         plan->startup_cost = best_path->path.startup_cost;
    1877      212256 :         plan->total_cost = best_path->path.total_cost;
    1878      212256 :         plan->plan_rows = best_path->path.rows;
    1879      212256 :         plan->plan_width = best_path->path.pathtarget->width;
    1880      212256 :         plan->parallel_safe = best_path->path.parallel_safe;
    1881             :         /* ... but don't change subplan's parallel_aware flag */
    1882             :     }
    1883             :     else
    1884             :     {
    1885             :         /* We need a Result node */
    1886         800 :         plan = (Plan *) make_result(tlist, NULL, subplan);
    1887             : 
    1888         800 :         copy_generic_path_info(plan, (Path *) best_path);
    1889             :     }
    1890             : 
    1891      213056 :     return plan;
    1892             : }
    1893             : 
    1894             : /*
    1895             :  * inject_projection_plan
    1896             :  *    Insert a Result node to do a projection step.
    1897             :  *
    1898             :  * This is used in a few places where we decide on-the-fly that we need a
    1899             :  * projection step as part of the tree generated for some Path node.
    1900             :  * We should try to get rid of this in favor of doing it more honestly.
    1901             :  *
    1902             :  * One reason it's ugly is we have to be told the right parallel_safe marking
    1903             :  * to apply (since the tlist might be unsafe even if the child plan is safe).
    1904             :  */
    1905             : static Plan *
    1906          16 : inject_projection_plan(Plan *subplan, List *tlist, bool parallel_safe)
    1907             : {
    1908             :     Plan       *plan;
    1909             : 
    1910          16 :     plan = (Plan *) make_result(tlist, NULL, subplan);
    1911             : 
    1912             :     /*
    1913             :      * In principle, we should charge tlist eval cost plus cpu_per_tuple per
    1914             :      * row for the Result node.  But the former has probably been factored in
    1915             :      * already and the latter was not accounted for during Path construction,
    1916             :      * so being formally correct might just make the EXPLAIN output look less
    1917             :      * consistent not more so.  Hence, just copy the subplan's cost.
    1918             :      */
    1919          16 :     copy_plan_costsize(plan, subplan);
    1920          16 :     plan->parallel_safe = parallel_safe;
    1921             : 
    1922          16 :     return plan;
    1923             : }
    1924             : 
    1925             : /*
    1926             :  * change_plan_targetlist
    1927             :  *    Externally available wrapper for inject_projection_plan.
    1928             :  *
    1929             :  * This is meant for use by FDW plan-generation functions, which might
    1930             :  * want to adjust the tlist computed by some subplan tree.  In general,
    1931             :  * a Result node is needed to compute the new tlist, but we can optimize
    1932             :  * some cases.
    1933             :  *
    1934             :  * In most cases, tlist_parallel_safe can just be passed as the parallel_safe
    1935             :  * flag of the FDW's own Path node.
    1936             :  */
    1937             : Plan *
    1938          66 : change_plan_targetlist(Plan *subplan, List *tlist, bool tlist_parallel_safe)
    1939             : {
    1940             :     /*
    1941             :      * If the top plan node can't do projections and its existing target list
    1942             :      * isn't already what we need, we need to add a Result node to help it
    1943             :      * along.
    1944             :      */
    1945          72 :     if (!is_projection_capable_plan(subplan) &&
    1946           6 :         !tlist_same_exprs(tlist, subplan->targetlist))
    1947           0 :         subplan = inject_projection_plan(subplan, tlist,
    1948           0 :                                          subplan->parallel_safe &&
    1949             :                                          tlist_parallel_safe);
    1950             :     else
    1951             :     {
    1952             :         /* Else we can just replace the plan node's tlist */
    1953          66 :         subplan->targetlist = tlist;
    1954          66 :         subplan->parallel_safe &= tlist_parallel_safe;
    1955             :     }
    1956          66 :     return subplan;
    1957             : }
    1958             : 
    1959             : /*
    1960             :  * create_sort_plan
    1961             :  *
    1962             :  *    Create a Sort plan for 'best_path' and (recursively) plans
    1963             :  *    for its subpaths.
    1964             :  */
    1965             : static Sort *
    1966       29058 : create_sort_plan(PlannerInfo *root, SortPath *best_path, int flags)
    1967             : {
    1968             :     Sort       *plan;
    1969             :     Plan       *subplan;
    1970             : 
    1971             :     /*
    1972             :      * We don't want any excess columns in the sorted tuples, so request a
    1973             :      * smaller tlist.  Otherwise, since Sort doesn't project, tlist
    1974             :      * requirements pass through.
    1975             :      */
    1976       29058 :     subplan = create_plan_recurse(root, best_path->subpath,
    1977             :                                   flags | CP_SMALL_TLIST);
    1978             : 
    1979             :     /*
    1980             :      * make_sort_from_pathkeys() indirectly calls find_ec_member_for_tle(),
    1981             :      * which will ignore any child EC members that don't belong to the given
    1982             :      * relids. Thus, if this sort path is based on a child relation, we must
    1983             :      * pass its relids.
    1984             :      */
    1985       29290 :     plan = make_sort_from_pathkeys(subplan, best_path->path.pathkeys,
    1986       57972 :                                    IS_OTHER_REL(best_path->subpath->parent) ?
    1987         232 :                                    best_path->path.parent->relids : NULL);
    1988             : 
    1989       29058 :     copy_generic_path_info(&plan->plan, (Path *) best_path);
    1990             : 
    1991       29058 :     return plan;
    1992             : }
    1993             : 
    1994             : /*
    1995             :  * create_group_plan
    1996             :  *
    1997             :  *    Create a Group plan for 'best_path' and (recursively) plans
    1998             :  *    for its subpaths.
    1999             :  */
    2000             : static Group *
    2001         138 : create_group_plan(PlannerInfo *root, GroupPath *best_path)
    2002             : {
    2003             :     Group      *plan;
    2004             :     Plan       *subplan;
    2005             :     List       *tlist;
    2006             :     List       *quals;
    2007             : 
    2008             :     /*
    2009             :      * Group can project, so no need to be terribly picky about child tlist,
    2010             :      * but we do need grouping columns to be available
    2011             :      */
    2012         138 :     subplan = create_plan_recurse(root, best_path->subpath, CP_LABEL_TLIST);
    2013             : 
    2014         138 :     tlist = build_path_tlist(root, &best_path->path);
    2015             : 
    2016         138 :     quals = order_qual_clauses(root, best_path->qual);
    2017             : 
    2018         276 :     plan = make_group(tlist,
    2019             :                       quals,
    2020         138 :                       list_length(best_path->groupClause),
    2021             :                       extract_grouping_cols(best_path->groupClause,
    2022             :                                             subplan->targetlist),
    2023             :                       extract_grouping_ops(best_path->groupClause),
    2024             :                       extract_grouping_collations(best_path->groupClause,
    2025             :                                                   subplan->targetlist),
    2026             :                       subplan);
    2027             : 
    2028         138 :     copy_generic_path_info(&plan->plan, (Path *) best_path);
    2029             : 
    2030         138 :     return plan;
    2031             : }
    2032             : 
    2033             : /*
    2034             :  * create_upper_unique_plan
    2035             :  *
    2036             :  *    Create a Unique plan for 'best_path' and (recursively) plans
    2037             :  *    for its subpaths.
    2038             :  */
    2039             : static Unique *
    2040         324 : create_upper_unique_plan(PlannerInfo *root, UpperUniquePath *best_path, int flags)
    2041             : {
    2042             :     Unique     *plan;
    2043             :     Plan       *subplan;
    2044             : 
    2045             :     /*
    2046             :      * Unique doesn't project, so tlist requirements pass through; moreover we
    2047             :      * need grouping columns to be labeled.
    2048             :      */
    2049         324 :     subplan = create_plan_recurse(root, best_path->subpath,
    2050             :                                   flags | CP_LABEL_TLIST);
    2051             : 
    2052         324 :     plan = make_unique_from_pathkeys(subplan,
    2053             :                                      best_path->path.pathkeys,
    2054             :                                      best_path->numkeys);
    2055             : 
    2056         324 :     copy_generic_path_info(&plan->plan, (Path *) best_path);
    2057             : 
    2058         324 :     return plan;
    2059             : }
    2060             : 
    2061             : /*
    2062             :  * create_agg_plan
    2063             :  *
    2064             :  *    Create an Agg plan for 'best_path' and (recursively) plans
    2065             :  *    for its subpaths.
    2066             :  */
    2067             : static Agg *
    2068       24388 : create_agg_plan(PlannerInfo *root, AggPath *best_path)
    2069             : {
    2070             :     Agg        *plan;
    2071             :     Plan       *subplan;
    2072             :     List       *tlist;
    2073             :     List       *quals;
    2074             : 
    2075             :     /*
    2076             :      * Agg can project, so no need to be terribly picky about child tlist, but
    2077             :      * we do need grouping columns to be available
    2078             :      */
    2079       24388 :     subplan = create_plan_recurse(root, best_path->subpath, CP_LABEL_TLIST);
    2080             : 
    2081       24388 :     tlist = build_path_tlist(root, &best_path->path);
    2082             : 
    2083       24388 :     quals = order_qual_clauses(root, best_path->qual);
    2084             : 
    2085       48776 :     plan = make_agg(tlist, quals,
    2086             :                     best_path->aggstrategy,
    2087             :                     best_path->aggsplit,
    2088       24388 :                     list_length(best_path->groupClause),
    2089             :                     extract_grouping_cols(best_path->groupClause,
    2090             :                                           subplan->targetlist),
    2091             :                     extract_grouping_ops(best_path->groupClause),
    2092             :                     extract_grouping_collations(best_path->groupClause,
    2093             :                                                 subplan->targetlist),
    2094             :                     NIL,
    2095             :                     NIL,
    2096             :                     best_path->numGroups,
    2097             :                     subplan);
    2098             : 
    2099       24388 :     copy_generic_path_info(&plan->plan, (Path *) best_path);
    2100             : 
    2101       24388 :     return plan;
    2102             : }
    2103             : 
    2104             : /*
    2105             :  * Given a groupclause for a collection of grouping sets, produce the
    2106             :  * corresponding groupColIdx.
    2107             :  *
    2108             :  * root->grouping_map maps the tleSortGroupRef to the actual column position in
    2109             :  * the input tuple. So we get the ref from the entries in the groupclause and
    2110             :  * look them up there.
    2111             :  */
    2112             : static AttrNumber *
    2113         820 : remap_groupColIdx(PlannerInfo *root, List *groupClause)
    2114             : {
    2115         820 :     AttrNumber *grouping_map = root->grouping_map;
    2116             :     AttrNumber *new_grpColIdx;
    2117             :     ListCell   *lc;
    2118             :     int         i;
    2119             : 
    2120             :     Assert(grouping_map);
    2121             : 
    2122         820 :     new_grpColIdx = palloc0(sizeof(AttrNumber) * list_length(groupClause));
    2123             : 
    2124         820 :     i = 0;
    2125        1904 :     foreach(lc, groupClause)
    2126             :     {
    2127        1084 :         SortGroupClause *clause = lfirst(lc);
    2128             : 
    2129        1084 :         new_grpColIdx[i++] = grouping_map[clause->tleSortGroupRef];
    2130             :     }
    2131             : 
    2132         820 :     return new_grpColIdx;
    2133             : }
    2134             : 
    2135             : /*
    2136             :  * create_groupingsets_plan
    2137             :  *    Create a plan for 'best_path' and (recursively) plans
    2138             :  *    for its subpaths.
    2139             :  *
    2140             :  *    What we emit is an Agg plan with some vestigial Agg and Sort nodes
    2141             :  *    hanging off the side.  The top Agg implements the last grouping set
    2142             :  *    specified in the GroupingSetsPath, and any additional grouping sets
    2143             :  *    each give rise to a subsidiary Agg and Sort node in the top Agg's
    2144             :  *    "chain" list.  These nodes don't participate in the plan directly,
    2145             :  *    but they are a convenient way to represent the required data for
    2146             :  *    the extra steps.
    2147             :  *
    2148             :  *    Returns a Plan node.
    2149             :  */
    2150             : static Plan *
    2151         424 : create_groupingsets_plan(PlannerInfo *root, GroupingSetsPath *best_path)
    2152             : {
    2153             :     Agg        *plan;
    2154             :     Plan       *subplan;
    2155         424 :     List       *rollups = best_path->rollups;
    2156             :     AttrNumber *grouping_map;
    2157             :     int         maxref;
    2158             :     List       *chain;
    2159             :     ListCell   *lc;
    2160             : 
    2161             :     /* Shouldn't get here without grouping sets */
    2162             :     Assert(root->parse->groupingSets);
    2163             :     Assert(rollups != NIL);
    2164             : 
    2165             :     /*
    2166             :      * Agg can project, so no need to be terribly picky about child tlist, but
    2167             :      * we do need grouping columns to be available
    2168             :      */
    2169         424 :     subplan = create_plan_recurse(root, best_path->subpath, CP_LABEL_TLIST);
    2170             : 
    2171             :     /*
    2172             :      * Compute the mapping from tleSortGroupRef to column index in the child's
    2173             :      * tlist.  First, identify max SortGroupRef in groupClause, for array
    2174             :      * sizing.
    2175             :      */
    2176         424 :     maxref = 0;
    2177        1312 :     foreach(lc, root->parse->groupClause)
    2178             :     {
    2179         888 :         SortGroupClause *gc = (SortGroupClause *) lfirst(lc);
    2180             : 
    2181         888 :         if (gc->tleSortGroupRef > maxref)
    2182         864 :             maxref = gc->tleSortGroupRef;
    2183             :     }
    2184             : 
    2185         424 :     grouping_map = (AttrNumber *) palloc0((maxref + 1) * sizeof(AttrNumber));
    2186             : 
    2187             :     /* Now look up the column numbers in the child's tlist */
    2188        1312 :     foreach(lc, root->parse->groupClause)
    2189             :     {
    2190         888 :         SortGroupClause *gc = (SortGroupClause *) lfirst(lc);
    2191         888 :         TargetEntry *tle = get_sortgroupclause_tle(gc, subplan->targetlist);
    2192             : 
    2193         888 :         grouping_map[gc->tleSortGroupRef] = tle->resno;
    2194             :     }
    2195             : 
    2196             :     /*
    2197             :      * During setrefs.c, we'll need the grouping_map to fix up the cols lists
    2198             :      * in GroupingFunc nodes.  Save it for setrefs.c to use.
    2199             :      *
    2200             :      * This doesn't work if we're in an inheritance subtree (see notes in
    2201             :      * create_modifytable_plan).  Fortunately we can't be because there would
    2202             :      * never be grouping in an UPDATE/DELETE; but let's Assert that.
    2203             :      */
    2204             :     Assert(root->inhTargetKind == INHKIND_NONE);
    2205             :     Assert(root->grouping_map == NULL);
    2206         424 :     root->grouping_map = grouping_map;
    2207             : 
    2208             :     /*
    2209             :      * Generate the side nodes that describe the other sort and group
    2210             :      * operations besides the top one.  Note that we don't worry about putting
    2211             :      * accurate cost estimates in the side nodes; only the topmost Agg node's
    2212             :      * costs will be shown by EXPLAIN.
    2213             :      */
    2214         424 :     chain = NIL;
    2215         424 :     if (list_length(rollups) > 1)
    2216             :     {
    2217         248 :         bool        is_first_sort = ((RollupData *) linitial(rollups))->is_hashed;
    2218             : 
    2219         644 :         for_each_cell(lc, rollups, list_second_cell(rollups))
    2220             :         {
    2221         396 :             RollupData *rollup = lfirst(lc);
    2222             :             AttrNumber *new_grpColIdx;
    2223         396 :             Plan       *sort_plan = NULL;
    2224             :             Plan       *agg_plan;
    2225             :             AggStrategy strat;
    2226             : 
    2227         396 :             new_grpColIdx = remap_groupColIdx(root, rollup->groupClause);
    2228             : 
    2229         396 :             if (!rollup->is_hashed && !is_first_sort)
    2230             :             {
    2231         128 :                 sort_plan = (Plan *)
    2232         128 :                     make_sort_from_groupcols(rollup->groupClause,
    2233             :                                              new_grpColIdx,
    2234             :                                              subplan);
    2235             :             }
    2236             : 
    2237         396 :             if (!rollup->is_hashed)
    2238         220 :                 is_first_sort = false;
    2239             : 
    2240         396 :             if (rollup->is_hashed)
    2241         176 :                 strat = AGG_HASHED;
    2242         220 :             else if (list_length(linitial(rollup->gsets)) == 0)
    2243          64 :                 strat = AGG_PLAIN;
    2244             :             else
    2245         156 :                 strat = AGG_SORTED;
    2246             : 
    2247         792 :             agg_plan = (Plan *) make_agg(NIL,
    2248             :                                          NIL,
    2249             :                                          strat,
    2250             :                                          AGGSPLIT_SIMPLE,
    2251         396 :                                          list_length((List *) linitial(rollup->gsets)),
    2252             :                                          new_grpColIdx,
    2253             :                                          extract_grouping_ops(rollup->groupClause),
    2254             :                                          extract_grouping_collations(rollup->groupClause, subplan->targetlist),
    2255             :                                          rollup->gsets,
    2256             :                                          NIL,
    2257             :                                          rollup->numGroups,
    2258             :                                          sort_plan);
    2259             : 
    2260             :             /*
    2261             :              * Remove stuff we don't need to avoid bloating debug output.
    2262             :              */
    2263         396 :             if (sort_plan)
    2264             :             {
    2265         128 :                 sort_plan->targetlist = NIL;
    2266         128 :                 sort_plan->lefttree = NULL;
    2267             :             }
    2268             : 
    2269         396 :             chain = lappend(chain, agg_plan);
    2270             :         }
    2271             :     }
    2272             : 
    2273             :     /*
    2274             :      * Now make the real Agg node
    2275             :      */
    2276             :     {
    2277         424 :         RollupData *rollup = linitial(rollups);
    2278             :         AttrNumber *top_grpColIdx;
    2279             :         int         numGroupCols;
    2280             : 
    2281         424 :         top_grpColIdx = remap_groupColIdx(root, rollup->groupClause);
    2282             : 
    2283         424 :         numGroupCols = list_length((List *) linitial(rollup->gsets));
    2284             : 
    2285         424 :         plan = make_agg(build_path_tlist(root, &best_path->path),
    2286             :                         best_path->qual,
    2287             :                         best_path->aggstrategy,
    2288             :                         AGGSPLIT_SIMPLE,
    2289             :                         numGroupCols,
    2290             :                         top_grpColIdx,
    2291             :                         extract_grouping_ops(rollup->groupClause),
    2292             :                         extract_grouping_collations(rollup->groupClause, subplan->targetlist),
    2293             :                         rollup->gsets,
    2294             :                         chain,
    2295             :                         rollup->numGroups,
    2296             :                         subplan);
    2297             : 
    2298             :         /* Copy cost data from Path to Plan */
    2299         424 :         copy_generic_path_info(&plan->plan, &best_path->path);
    2300             :     }
    2301             : 
    2302         424 :     return (Plan *) plan;
    2303             : }
    2304             : 
    2305             : /*
    2306             :  * create_minmaxagg_plan
    2307             :  *
    2308             :  *    Create a Result plan for 'best_path' and (recursively) plans
    2309             :  *    for its subpaths.
    2310             :  */
    2311             : static Result *
    2312         336 : create_minmaxagg_plan(PlannerInfo *root, MinMaxAggPath *best_path)
    2313             : {
    2314             :     Result     *plan;
    2315             :     List       *tlist;
    2316             :     ListCell   *lc;
    2317             : 
    2318             :     /* Prepare an InitPlan for each aggregate's subquery. */
    2319         696 :     foreach(lc, best_path->mmaggregates)
    2320             :     {
    2321         360 :         MinMaxAggInfo *mminfo = (MinMaxAggInfo *) lfirst(lc);
    2322         360 :         PlannerInfo *subroot = mminfo->subroot;
    2323         360 :         Query      *subparse = subroot->parse;
    2324             :         Plan       *plan;
    2325             : 
    2326             :         /*
    2327             :          * Generate the plan for the subquery. We already have a Path, but we
    2328             :          * have to convert it to a Plan and attach a LIMIT node above it.
    2329             :          * Since we are entering a different planner context (subroot),
    2330             :          * recurse to create_plan not create_plan_recurse.
    2331             :          */
    2332         360 :         plan = create_plan(subroot, mminfo->path);
    2333             : 
    2334         360 :         plan = (Plan *) make_limit(plan,
    2335             :                                    subparse->limitOffset,
    2336             :                                    subparse->limitCount);
    2337             : 
    2338             :         /* Must apply correct cost/width data to Limit node */
    2339         360 :         plan->startup_cost = mminfo->path->startup_cost;
    2340         360 :         plan->total_cost = mminfo->pathcost;
    2341         360 :         plan->plan_rows = 1;
    2342         360 :         plan->plan_width = mminfo->path->pathtarget->width;
    2343         360 :         plan->parallel_aware = false;
    2344         360 :         plan->parallel_safe = mminfo->path->parallel_safe;
    2345             : 
    2346             :         /* Convert the plan into an InitPlan in the outer query. */
    2347         360 :         SS_make_initplan_from_plan(root, subroot, plan, mminfo->param);
    2348             :     }
    2349             : 
    2350             :     /* Generate the output plan --- basically just a Result */
    2351         336 :     tlist = build_path_tlist(root, &best_path->path);
    2352             : 
    2353         336 :     plan = make_result(tlist, (Node *) best_path->quals, NULL);
    2354             : 
    2355         336 :     copy_generic_path_info(&plan->plan, (Path *) best_path);
    2356             : 
    2357             :     /*
    2358             :      * During setrefs.c, we'll need to replace references to the Agg nodes
    2359             :      * with InitPlan output params.  (We can't just do that locally in the
    2360             :      * MinMaxAgg node, because path nodes above here may have Agg references
    2361             :      * as well.)  Save the mmaggregates list to tell setrefs.c to do that.
    2362             :      *
    2363             :      * This doesn't work if we're in an inheritance subtree (see notes in
    2364             :      * create_modifytable_plan).  Fortunately we can't be because there would
    2365             :      * never be aggregates in an UPDATE/DELETE; but let's Assert that.
    2366             :      */
    2367             :     Assert(root->inhTargetKind == INHKIND_NONE);
    2368             :     Assert(root->minmax_aggs == NIL);
    2369         336 :     root->minmax_aggs = best_path->mmaggregates;
    2370             : 
    2371         336 :     return plan;
    2372             : }
    2373             : 
    2374             : /*
    2375             :  * create_windowagg_plan
    2376             :  *
    2377             :  *    Create a WindowAgg plan for 'best_path' and (recursively) plans
    2378             :  *    for its subpaths.
    2379             :  */
    2380             : static WindowAgg *
    2381        1160 : create_windowagg_plan(PlannerInfo *root, WindowAggPath *best_path)
    2382             : {
    2383             :     WindowAgg  *plan;
    2384        1160 :     WindowClause *wc = best_path->winclause;
    2385        1160 :     int         numPart = list_length(wc->partitionClause);
    2386        1160 :     int         numOrder = list_length(wc->orderClause);
    2387             :     Plan       *subplan;
    2388             :     List       *tlist;
    2389             :     int         partNumCols;
    2390             :     AttrNumber *partColIdx;
    2391             :     Oid        *partOperators;
    2392             :     Oid        *partCollations;
    2393             :     int         ordNumCols;
    2394             :     AttrNumber *ordColIdx;
    2395             :     Oid        *ordOperators;
    2396             :     Oid        *ordCollations;
    2397             :     ListCell   *lc;
    2398             : 
    2399             :     /*
    2400             :      * Choice of tlist here is motivated by the fact that WindowAgg will be
    2401             :      * storing the input rows of window frames in a tuplestore; it therefore
    2402             :      * behooves us to request a small tlist to avoid wasting space. We do of
    2403             :      * course need grouping columns to be available.
    2404             :      */
    2405        1160 :     subplan = create_plan_recurse(root, best_path->subpath,
    2406             :                                   CP_LABEL_TLIST | CP_SMALL_TLIST);
    2407             : 
    2408        1160 :     tlist = build_path_tlist(root, &best_path->path);
    2409             : 
    2410             :     /*
    2411             :      * Convert SortGroupClause lists into arrays of attr indexes and equality
    2412             :      * operators, as wanted by executor.  (Note: in principle, it's possible
    2413             :      * to drop some of the sort columns, if they were proved redundant by
    2414             :      * pathkey logic.  However, it doesn't seem worth going out of our way to
    2415             :      * optimize such cases.  In any case, we must *not* remove the ordering
    2416             :      * column for RANGE OFFSET cases, as the executor needs that for in_range
    2417             :      * tests even if it's known to be equal to some partitioning column.)
    2418             :      */
    2419        1160 :     partColIdx = (AttrNumber *) palloc(sizeof(AttrNumber) * numPart);
    2420        1160 :     partOperators = (Oid *) palloc(sizeof(Oid) * numPart);
    2421        1160 :     partCollations = (Oid *) palloc(sizeof(Oid) * numPart);
    2422             : 
    2423        1160 :     partNumCols = 0;
    2424        1512 :     foreach(lc, wc->partitionClause)
    2425             :     {
    2426         352 :         SortGroupClause *sgc = (SortGroupClause *) lfirst(lc);
    2427         352 :         TargetEntry *tle = get_sortgroupclause_tle(sgc, subplan->targetlist);
    2428             : 
    2429             :         Assert(OidIsValid(sgc->eqop));
    2430         352 :         partColIdx[partNumCols] = tle->resno;
    2431         352 :         partOperators[partNumCols] = sgc->eqop;
    2432         352 :         partCollations[partNumCols] = exprCollation((Node *) tle->expr);
    2433         352 :         partNumCols++;
    2434             :     }
    2435             : 
    2436        1160 :     ordColIdx = (AttrNumber *) palloc(sizeof(AttrNumber) * numOrder);
    2437        1160 :     ordOperators = (Oid *) palloc(sizeof(Oid) * numOrder);
    2438        1160 :     ordCollations = (Oid *) palloc(sizeof(Oid) * numOrder);
    2439             : 
    2440        1160 :     ordNumCols = 0;
    2441        2216 :     foreach(lc, wc->orderClause)
    2442             :     {
    2443        1056 :         SortGroupClause *sgc = (SortGroupClause *) lfirst(lc);
    2444        1056 :         TargetEntry *tle = get_sortgroupclause_tle(sgc, subplan->targetlist);
    2445             : 
    2446             :         Assert(OidIsValid(sgc->eqop));
    2447        1056 :         ordColIdx[ordNumCols] = tle->resno;
    2448        1056 :         ordOperators[ordNumCols] = sgc->eqop;
    2449        1056 :         ordCollations[ordNumCols] = exprCollation((Node *) tle->expr);
    2450        1056 :         ordNumCols++;
    2451             :     }
    2452             : 
    2453             :     /* And finally we can make the WindowAgg node */
    2454        2320 :     plan = make_windowagg(tlist,
    2455             :                           wc->winref,
    2456             :                           partNumCols,
    2457             :                           partColIdx,
    2458             :                           partOperators,
    2459             :                           partCollations,
    2460             :                           ordNumCols,
    2461             :                           ordColIdx,
    2462             :                           ordOperators,
    2463             :                           ordCollations,
    2464             :                           wc->frameOptions,
    2465             :                           wc->startOffset,
    2466             :                           wc->endOffset,
    2467             :                           wc->startInRangeFunc,
    2468             :                           wc->endInRangeFunc,
    2469             :                           wc->inRangeColl,
    2470        1160 :                           wc->inRangeAsc,
    2471        1160 :                           wc->inRangeNullsFirst,
    2472             :                           subplan);
    2473             : 
    2474        1160 :     copy_generic_path_info(&plan->plan, (Path *) best_path);
    2475             : 
    2476        1160 :     return plan;
    2477             : }
    2478             : 
    2479             : /*
    2480             :  * create_setop_plan
    2481             :  *
    2482             :  *    Create a SetOp plan for 'best_path' and (recursively) plans
    2483             :  *    for its subpaths.
    2484             :  */
    2485             : static SetOp *
    2486         208 : create_setop_plan(PlannerInfo *root, SetOpPath *best_path, int flags)
    2487             : {
    2488             :     SetOp      *plan;
    2489             :     Plan       *subplan;
    2490             :     long        numGroups;
    2491             : 
    2492             :     /*
    2493             :      * SetOp doesn't project, so tlist requirements pass through; moreover we
    2494             :      * need grouping columns to be labeled.
    2495             :      */
    2496         208 :     subplan = create_plan_recurse(root, best_path->subpath,
    2497             :                                   flags | CP_LABEL_TLIST);
    2498             : 
    2499             :     /* Convert numGroups to long int --- but 'ware overflow! */
    2500         208 :     numGroups = (long) Min(best_path->numGroups, (double) LONG_MAX);
    2501             : 
    2502         416 :     plan = make_setop(best_path->cmd,
    2503             :                       best_path->strategy,
    2504             :                       subplan,
    2505             :                       best_path->distinctList,
    2506         208 :                       best_path->flagColIdx,
    2507             :                       best_path->firstFlag,
    2508             :                       numGroups);
    2509             : 
    2510         208 :     copy_generic_path_info(&plan->plan, (Path *) best_path);
    2511             : 
    2512         208 :     return plan;
    2513             : }
    2514             : 
    2515             : /*
    2516             :  * create_recursiveunion_plan
    2517             :  *
    2518             :  *    Create a RecursiveUnion plan for 'best_path' and (recursively) plans
    2519             :  *    for its subpaths.
    2520             :  */
    2521             : static RecursiveUnion *
    2522         320 : create_recursiveunion_plan(PlannerInfo *root, RecursiveUnionPath *best_path)
    2523             : {
    2524             :     RecursiveUnion *plan;
    2525             :     Plan       *leftplan;
    2526             :     Plan       *rightplan;
    2527             :     List       *tlist;
    2528             :     long        numGroups;
    2529             : 
    2530             :     /* Need both children to produce same tlist, so force it */
    2531         320 :     leftplan = create_plan_recurse(root, best_path->leftpath, CP_EXACT_TLIST);
    2532         320 :     rightplan = create_plan_recurse(root, best_path->rightpath, CP_EXACT_TLIST);
    2533             : 
    2534         320 :     tlist = build_path_tlist(root, &best_path->path);
    2535             : 
    2536             :     /* Convert numGroups to long int --- but 'ware overflow! */
    2537         320 :     numGroups = (long) Min(best_path->numGroups, (double) LONG_MAX);
    2538             : 
    2539         320 :     plan = make_recursive_union(tlist,
    2540             :                                 leftplan,
    2541             :                                 rightplan,
    2542             :                                 best_path->wtParam,
    2543             :                                 best_path->distinctList,
    2544             :                                 numGroups);
    2545             : 
    2546         320 :     copy_generic_path_info(&plan->plan, (Path *) best_path);
    2547             : 
    2548         320 :     return plan;
    2549             : }
    2550             : 
    2551             : /*
    2552             :  * create_lockrows_plan
    2553             :  *
    2554             :  *    Create a LockRows plan for 'best_path' and (recursively) plans
    2555             :  *    for its subpaths.
    2556             :  */
    2557             : static LockRows *
    2558        4840 : create_lockrows_plan(PlannerInfo *root, LockRowsPath *best_path,
    2559             :                      int flags)
    2560             : {
    2561             :     LockRows   *plan;
    2562             :     Plan       *subplan;
    2563             : 
    2564             :     /* LockRows doesn't project, so tlist requirements pass through */
    2565        4840 :     subplan = create_plan_recurse(root, best_path->subpath, flags);
    2566             : 
    2567        4840 :     plan = make_lockrows(subplan, best_path->rowMarks, best_path->epqParam);
    2568             : 
    2569        4840 :     copy_generic_path_info(&plan->plan, (Path *) best_path);
    2570             : 
    2571        4840 :     return plan;
    2572             : }
    2573             : 
    2574             : /*
    2575             :  * create_modifytable_plan
    2576             :  *    Create a ModifyTable plan for 'best_path'.
    2577             :  *
    2578             :  *    Returns a Plan node.
    2579             :  */
    2580             : static ModifyTable *
    2581       69372 : create_modifytable_plan(PlannerInfo *root, ModifyTablePath *best_path)
    2582             : {
    2583             :     ModifyTable *plan;
    2584       69372 :     List       *subplans = NIL;
    2585             :     ListCell   *subpaths,
    2586             :                *subroots;
    2587             : 
    2588             :     /* Build the plan for each input path */
    2589      139914 :     forboth(subpaths, best_path->subpaths,
    2590             :             subroots, best_path->subroots)
    2591             :     {
    2592       70542 :         Path       *subpath = (Path *) lfirst(subpaths);
    2593       70542 :         PlannerInfo *subroot = (PlannerInfo *) lfirst(subroots);
    2594             :         Plan       *subplan;
    2595             : 
    2596             :         /*
    2597             :          * In an inherited UPDATE/DELETE, reference the per-child modified
    2598             :          * subroot while creating Plans from Paths for the child rel.  This is
    2599             :          * a kluge, but otherwise it's too hard to ensure that Plan creation
    2600             :          * functions (particularly in FDWs) don't depend on the contents of
    2601             :          * "root" matching what they saw at Path creation time.  The main
    2602             :          * downside is that creation functions for Plans that might appear
    2603             :          * below a ModifyTable cannot expect to modify the contents of "root"
    2604             :          * and have it "stick" for subsequent processing such as setrefs.c.
    2605             :          * That's not great, but it seems better than the alternative.
    2606             :          */
    2607       70542 :         subplan = create_plan_recurse(subroot, subpath, CP_EXACT_TLIST);
    2608             : 
    2609             :         /* Transfer resname/resjunk labeling, too, to keep executor happy */
    2610       70542 :         apply_tlist_labeling(subplan->targetlist, subroot->processed_tlist);
    2611             : 
    2612       70542 :         subplans = lappend(subplans, subplan);
    2613             :     }
    2614             : 
    2615      208116 :     plan = make_modifytable(root,
    2616             :                             best_path->operation,
    2617       69372 :                             best_path->canSetTag,
    2618             :                             best_path->nominalRelation,
    2619             :                             best_path->rootRelation,
    2620       69372 :                             best_path->partColsUpdated,
    2621             :                             best_path->resultRelations,
    2622             :                             subplans,
    2623             :                             best_path->subroots,
    2624             :                             best_path->withCheckOptionLists,
    2625             :                             best_path->returningLists,
    2626             :                             best_path->rowMarks,
    2627             :                             best_path->onconflict,
    2628             :                             best_path->epqParam);
    2629             : 
    2630       69252 :     copy_generic_path_info(&plan->plan, &best_path->path);
    2631             : 
    2632       69252 :     return plan;
    2633             : }
    2634             : 
    2635             : /*
    2636             :  * create_limit_plan
    2637             :  *
    2638             :  *    Create a Limit plan for 'best_path' and (recursively) plans
    2639             :  *    for its subpaths.
    2640             :  */
    2641             : static Limit *
    2642        2716 : create_limit_plan(PlannerInfo *root, LimitPath *best_path, int flags)
    2643             : {
    2644             :     Limit      *plan;
    2645             :     Plan       *subplan;
    2646             : 
    2647             :     /* Limit doesn't project, so tlist requirements pass through */
    2648        2716 :     subplan = create_plan_recurse(root, best_path->subpath, flags);
    2649             : 
    2650        2716 :     plan = make_limit(subplan,
    2651             :                       best_path->limitOffset,
    2652             :                       best_path->limitCount);
    2653             : 
    2654        2716 :     copy_generic_path_info(&plan->plan, (Path *) best_path);
    2655             : 
    2656        2716 :     return plan;
    2657             : }
    2658             : 
    2659             : 
    2660             : /*****************************************************************************
    2661             :  *
    2662             :  *  BASE-RELATION SCAN METHODS
    2663             :  *
    2664             :  *****************************************************************************/
    2665             : 
    2666             : 
    2667             : /*
    2668             :  * create_seqscan_plan
    2669             :  *   Returns a seqscan plan for the base relation scanned by 'best_path'
    2670             :  *   with restriction clauses 'scan_clauses' and targetlist 'tlist'.
    2671             :  */
    2672             : static SeqScan *
    2673      114992 : create_seqscan_plan(PlannerInfo *root, Path *best_path,
    2674             :                     List *tlist, List *scan_clauses)
    2675             : {
    2676             :     SeqScan    *scan_plan;
    2677      114992 :     Index       scan_relid = best_path->parent->relid;
    2678             : 
    2679             :     /* it should be a base rel... */
    2680             :     Assert(scan_relid > 0);
    2681             :     Assert(best_path->parent->rtekind == RTE_RELATION);
    2682             : 
    2683             :     /* Sort clauses into best execution order */
    2684      114992 :     scan_clauses = order_qual_clauses(root, scan_clauses);
    2685             : 
    2686             :     /* Reduce RestrictInfo list to bare expressions; ignore pseudoconstants */
    2687      114992 :     scan_clauses = extract_actual_clauses(scan_clauses, false);
    2688             : 
    2689             :     /* Replace any outer-relation variables with nestloop params */
    2690      114992 :     if (best_path->param_info)
    2691             :     {
    2692         204 :         scan_clauses = (List *)
    2693             :             replace_nestloop_params(root, (Node *) scan_clauses);
    2694             :     }
    2695             : 
    2696      114992 :     scan_plan = make_seqscan(tlist,
    2697             :                              scan_clauses,
    2698             :                              scan_relid);
    2699             : 
    2700      114992 :     copy_generic_path_info(&scan_plan->plan, best_path);
    2701             : 
    2702      114992 :     return scan_plan;
    2703             : }
    2704             : 
    2705             : /*
    2706             :  * create_samplescan_plan
    2707             :  *   Returns a samplescan plan for the base relation scanned by 'best_path'
    2708             :  *   with restriction clauses 'scan_clauses' and targetlist 'tlist'.
    2709             :  */
    2710             : static SampleScan *
    2711         180 : create_samplescan_plan(PlannerInfo *root, Path *best_path,
    2712             :                        List *tlist, List *scan_clauses)
    2713             : {
    2714             :     SampleScan *scan_plan;
    2715         180 :     Index       scan_relid = best_path->parent->relid;
    2716             :     RangeTblEntry *rte;
    2717             :     TableSampleClause *tsc;
    2718             : 
    2719             :     /* it should be a base rel with a tablesample clause... */
    2720             :     Assert(scan_relid > 0);
    2721         180 :     rte = planner_rt_fetch(scan_relid, root);
    2722             :     Assert(rte->rtekind == RTE_RELATION);
    2723         180 :     tsc = rte->tablesample;
    2724             :     Assert(tsc != NULL);
    2725             : 
    2726             :     /* Sort clauses into best execution order */
    2727         180 :     scan_clauses = order_qual_clauses(root, scan_clauses);
    2728             : 
    2729             :     /* Reduce RestrictInfo list to bare expressions; ignore pseudoconstants */
    2730         180 :     scan_clauses = extract_actual_clauses(scan_clauses, false);
    2731             : 
    2732             :     /* Replace any outer-relation variables with nestloop params */
    2733         180 :     if (best_path->param_info)
    2734             :     {
    2735          12 :         scan_clauses = (List *)
    2736             :             replace_nestloop_params(root, (Node *) scan_clauses);
    2737          12 :         tsc = (TableSampleClause *)
    2738             :             replace_nestloop_params(root, (Node *) tsc);
    2739             :     }
    2740             : 
    2741         180 :     scan_plan = make_samplescan(tlist,
    2742             :                                 scan_clauses,
    2743             :                                 scan_relid,
    2744             :                                 tsc);
    2745             : 
    2746         180 :     copy_generic_path_info(&scan_plan->scan.plan, best_path);
    2747             : 
    2748         180 :     return scan_plan;
    2749             : }
    2750             : 
    2751             : /*
    2752             :  * create_indexscan_plan
    2753             :  *    Returns an indexscan plan for the base relation scanned by 'best_path'
    2754             :  *    with restriction clauses 'scan_clauses' and targetlist 'tlist'.
    2755             :  *
    2756             :  * We use this for both plain IndexScans and IndexOnlyScans, because the
    2757             :  * qual preprocessing work is the same for both.  Note that the caller tells
    2758             :  * us which to build --- we don't look at best_path->path.pathtype, because
    2759             :  * create_bitmap_subplan needs to be able to override the prior decision.
    2760             :  */
    2761             : static Scan *
    2762      100300 : create_indexscan_plan(PlannerInfo *root,
    2763             :                       IndexPath *best_path,
    2764             :                       List *tlist,
    2765             :                       List *scan_clauses,
    2766             :                       bool indexonly)
    2767             : {
    2768             :     Scan       *scan_plan;
    2769      100300 :     List       *indexclauses = best_path->indexclauses;
    2770      100300 :     List       *indexorderbys = best_path->indexorderbys;
    2771      100300 :     Index       baserelid = best_path->path.parent->relid;
    2772      100300 :     Oid         indexoid = best_path->indexinfo->indexoid;
    2773             :     List       *qpqual;
    2774             :     List       *stripped_indexquals;
    2775             :     List       *fixed_indexquals;
    2776             :     List       *fixed_indexorderbys;
    2777      100300 :     List       *indexorderbyops = NIL;
    2778             :     ListCell   *l;
    2779             : 
    2780             :     /* it should be a base rel... */
    2781             :     Assert(baserelid > 0);
    2782             :     Assert(best_path->path.parent->rtekind == RTE_RELATION);
    2783             : 
    2784             :     /*
    2785             :      * Extract the index qual expressions (stripped of RestrictInfos) from the
    2786             :      * IndexClauses list, and prepare a copy with index Vars substituted for
    2787             :      * table Vars.  (This step also does replace_nestloop_params on the
    2788             :      * fixed_indexquals.)
    2789             :      */
    2790      100300 :     fix_indexqual_references(root, best_path,
    2791             :                              &stripped_indexquals,
    2792             :                              &fixed_indexquals);
    2793             : 
    2794             :     /*
    2795             :      * Likewise fix up index attr references in the ORDER BY expressions.
    2796             :      */
    2797      100300 :     fixed_indexorderbys = fix_indexorderby_references(root, best_path);
    2798             : 
    2799             :     /*
    2800             :      * The qpqual list must contain all restrictions not automatically handled
    2801             :      * by the index, other than pseudoconstant clauses which will be handled
    2802             :      * by a separate gating plan node.  All the predicates in the indexquals
    2803             :      * will be checked (either by the index itself, or by nodeIndexscan.c),
    2804             :      * but if there are any "special" operators involved then they must be
    2805             :      * included in qpqual.  The upshot is that qpqual must contain
    2806             :      * scan_clauses minus whatever appears in indexquals.
    2807             :      *
    2808             :      * is_redundant_with_indexclauses() detects cases where a scan clause is
    2809             :      * present in the indexclauses list or is generated from the same
    2810             :      * EquivalenceClass as some indexclause, and is therefore redundant with
    2811             :      * it, though not equal.  (The latter happens when indxpath.c prefers a
    2812             :      * different derived equality than what generate_join_implied_equalities
    2813             :      * picked for a parameterized scan's ppi_clauses.)  Note that it will not
    2814             :      * match to lossy index clauses, which is critical because we have to
    2815             :      * include the original clause in qpqual in that case.
    2816             :      *
    2817             :      * In some situations (particularly with OR'd index conditions) we may
    2818             :      * have scan_clauses that are not equal to, but are logically implied by,
    2819             :      * the index quals; so we also try a predicate_implied_by() check to see
    2820             :      * if we can discard quals that way.  (predicate_implied_by assumes its
    2821             :      * first input contains only immutable functions, so we have to check
    2822             :      * that.)
    2823             :      *
    2824             :      * Note: if you change this bit of code you should also look at
    2825             :      * extract_nonindex_conditions() in costsize.c.
    2826             :      */
    2827      100300 :     qpqual = NIL;
    2828      214556 :     foreach(l, scan_clauses)
    2829             :     {
    2830      114256 :         RestrictInfo *rinfo = lfirst_node(RestrictInfo, l);
    2831             : 
    2832      114256 :         if (rinfo->pseudoconstant)
    2833         506 :             continue;           /* we may drop pseudoconstants here */
    2834      113750 :         if (is_redundant_with_indexclauses(rinfo, indexclauses))
    2835       89156 :             continue;           /* dup or derived from same EquivalenceClass */
    2836       47300 :         if (!contain_mutable_functions((Node *) rinfo->clause) &&
    2837       22706 :             predicate_implied_by(list_make1(rinfo->clause), stripped_indexquals,
    2838             :                                  false))
    2839         100 :             continue;           /* provably implied by indexquals */
    2840       24494 :         qpqual = lappend(qpqual, rinfo);
    2841             :     }
    2842             : 
    2843             :     /* Sort clauses into best execution order */
    2844      100300 :     qpqual = order_qual_clauses(root, qpqual);
    2845             : 
    2846             :     /* Reduce RestrictInfo list to bare expressions; ignore pseudoconstants */
    2847      100300 :     qpqual = extract_actual_clauses(qpqual, false);
    2848             : 
    2849             :     /*
    2850             :      * We have to replace any outer-relation variables with nestloop params in
    2851             :      * the indexqualorig, qpqual, and indexorderbyorig expressions.  A bit
    2852             :      * annoying to have to do this separately from the processing in
    2853             :      * fix_indexqual_references --- rethink this when generalizing the inner
    2854             :      * indexscan support.  But note we can't really do this earlier because
    2855             :      * it'd break the comparisons to predicates above ... (or would it?  Those
    2856             :      * wouldn't have outer refs)
    2857             :      */
    2858      100300 :     if (best_path->path.param_info)
    2859             :     {
    2860       17092 :         stripped_indexquals = (List *)
    2861       17092 :             replace_nestloop_params(root, (Node *) stripped_indexquals);
    2862       17092 :         qpqual = (List *)
    2863             :             replace_nestloop_params(root, (Node *) qpqual);
    2864       17092 :         indexorderbys = (List *)
    2865             :             replace_nestloop_params(root, (Node *) indexorderbys);
    2866             :     }
    2867             : 
    2868             :     /*
    2869             :      * If there are ORDER BY expressions, look up the sort operators for their
    2870             :      * result datatypes.
    2871             :      */
    2872      100300 :     if (indexorderbys)
    2873             :     {
    2874             :         ListCell   *pathkeyCell,
    2875             :                    *exprCell;
    2876             : 
    2877             :         /*
    2878             :          * PathKey contains OID of the btree opfamily we're sorting by, but
    2879             :          * that's not quite enough because we need the expression's datatype
    2880             :          * to look up the sort operator in the operator family.
    2881             :          */
    2882             :         Assert(list_length(best_path->path.pathkeys) == list_length(indexorderbys));
    2883         496 :         forboth(pathkeyCell, best_path->path.pathkeys, exprCell, indexorderbys)
    2884             :         {
    2885         250 :             PathKey    *pathkey = (PathKey *) lfirst(pathkeyCell);
    2886         250 :             Node       *expr = (Node *) lfirst(exprCell);
    2887         250 :             Oid         exprtype = exprType(expr);
    2888             :             Oid         sortop;
    2889             : 
    2890             :             /* Get sort operator from opfamily */
    2891         250 :             sortop = get_opfamily_member(pathkey->pk_opfamily,
    2892             :                                          exprtype,
    2893             :                                          exprtype,
    2894         250 :                                          pathkey->pk_strategy);
    2895         250 :             if (!OidIsValid(sortop))
    2896           0 :                 elog(ERROR, "missing operator %d(%u,%u) in opfamily %u",
    2897             :                      pathkey->pk_strategy, exprtype, exprtype, pathkey->pk_opfamily);
    2898         250 :             indexorderbyops = lappend_oid(indexorderbyops, sortop);
    2899             :         }
    2900             :     }
    2901             : 
    2902             :     /* Finally ready to build the plan node */
    2903      100300 :     if (indexonly)
    2904       16092 :         scan_plan = (Scan *) make_indexonlyscan(tlist,
    2905             :                                                 qpqual,
    2906             :                                                 baserelid,
    2907             :                                                 indexoid,
    2908             :                                                 fixed_indexquals,
    2909             :                                                 fixed_indexorderbys,
    2910        8046 :                                                 best_path->indexinfo->indextlist,
    2911             :                                                 best_path->indexscandir);
    2912             :     else
    2913       92254 :         scan_plan = (Scan *) make_indexscan(tlist,
    2914             :                                             qpqual,
    2915             :                                             baserelid,
    2916             :                                             indexoid,
    2917             :                                             fixed_indexquals,
    2918             :                                             stripped_indexquals,
    2919             :                                             fixed_indexorderbys,
    2920             :                                             indexorderbys,
    2921             :                                             indexorderbyops,
    2922             :                                             best_path->indexscandir);
    2923             : 
    2924      100300 :     copy_generic_path_info(&scan_plan->plan, &best_path->path);
    2925             : 
    2926      100300 :     return scan_plan;
    2927             : }
    2928             : 
    2929             : /*
    2930             :  * create_bitmap_scan_plan
    2931             :  *    Returns a bitmap scan plan for the base relation scanned by 'best_path'
    2932             :  *    with restriction clauses 'scan_clauses' and targetlist 'tlist'.
    2933             :  */
    2934             : static BitmapHeapScan *
    2935       19314 : create_bitmap_scan_plan(PlannerInfo *root,
    2936             :                         BitmapHeapPath *best_path,
    2937             :                         List *tlist,
    2938             :                         List *scan_clauses)
    2939             : {
    2940       19314 :     Index       baserelid = best_path->path.parent->relid;
    2941             :     Plan       *bitmapqualplan;
    2942             :     List       *bitmapqualorig;
    2943             :     List       *indexquals;
    2944             :     List       *indexECs;
    2945             :     List       *qpqual;
    2946             :     ListCell   *l;
    2947             :     BitmapHeapScan *scan_plan;
    2948             : 
    2949             :     /* it should be a base rel... */
    2950             :     Assert(baserelid > 0);
    2951             :     Assert(best_path->path.parent->rtekind == RTE_RELATION);
    2952             : 
    2953             :     /* Process the bitmapqual tree into a Plan tree and qual lists */
    2954       19314 :     bitmapqualplan = create_bitmap_subplan(root, best_path->bitmapqual,
    2955             :                                            &bitmapqualorig, &indexquals,
    2956             :                                            &indexECs);
    2957             : 
    2958       19314 :     if (best_path->path.parallel_aware)
    2959          12 :         bitmap_subplan_mark_shared(bitmapqualplan);
    2960             : 
    2961             :     /*
    2962             :      * The qpqual list must contain all restrictions not automatically handled
    2963             :      * by the index, other than pseudoconstant clauses which will be handled
    2964             :      * by a separate gating plan node.  All the predicates in the indexquals
    2965             :      * will be checked (either by the index itself, or by
    2966             :      * nodeBitmapHeapscan.c), but if there are any "special" operators
    2967             :      * involved then they must be added to qpqual.  The upshot is that qpqual
    2968             :      * must contain scan_clauses minus whatever appears in indexquals.
    2969             :      *
    2970             :      * This loop is similar to the comparable code in create_indexscan_plan(),
    2971             :      * but with some differences because it has to compare the scan clauses to
    2972             :      * stripped (no RestrictInfos) indexquals.  See comments there for more
    2973             :      * info.
    2974             :      *
    2975             :      * In normal cases simple equal() checks will be enough to spot duplicate
    2976             :      * clauses, so we try that first.  We next see if the scan clause is
    2977             :      * redundant with any top-level indexqual by virtue of being generated
    2978             :      * from the same EC.  After that, try predicate_implied_by().
    2979             :      *
    2980             :      * Unlike create_indexscan_plan(), the predicate_implied_by() test here is
    2981             :      * useful for getting rid of qpquals that are implied by index predicates,
    2982             :      * because the predicate conditions are included in the "indexquals"
    2983             :      * returned by create_bitmap_subplan().  Bitmap scans have to do it that
    2984             :      * way because predicate conditions need to be rechecked if the scan
    2985             :      * becomes lossy, so they have to be included in bitmapqualorig.
    2986             :      */
    2987       19314 :     qpqual = NIL;
    2988       40156 :     foreach(l, scan_clauses)
    2989             :     {
    2990       20842 :         RestrictInfo *rinfo = lfirst_node(RestrictInfo, l);
    2991       20842 :         Node       *clause = (Node *) rinfo->clause;
    2992             : 
    2993       20842 :         if (rinfo->pseudoconstant)
    2994           0 :             continue;           /* we may drop pseudoconstants here */
    2995       20842 :         if (list_member(indexquals, clause))
    2996       19538 :             continue;           /* simple duplicate */
    2997        1304 :         if (rinfo->parent_ec && list_member_ptr(indexECs, rinfo->parent_ec))
    2998         112 :             continue;           /* derived from same EquivalenceClass */
    2999        2340 :         if (!contain_mutable_functions(clause) &&
    3000        1148 :             predicate_implied_by(list_make1(clause), indexquals, false))
    3001          80 :             continue;           /* provably implied by indexquals */
    3002        1112 :         qpqual = lappend(qpqual, rinfo);
    3003             :     }
    3004             : 
    3005             :     /* Sort clauses into best execution order */
    3006       19314 :     qpqual = order_qual_clauses(root, qpqual);
    3007             : 
    3008             :     /* Reduce RestrictInfo list to bare expressions; ignore pseudoconstants */
    3009       19314 :     qpqual = extract_actual_clauses(qpqual, false);
    3010             : 
    3011             :     /*
    3012             :      * When dealing with special operators, we will at this point have
    3013             :      * duplicate clauses in qpqual and bitmapqualorig.  We may as well drop
    3014             :      * 'em from bitmapqualorig, since there's no point in making the tests
    3015             :      * twice.
    3016             :      */
    3017       19314 :     bitmapqualorig = list_difference_ptr(bitmapqualorig, qpqual);
    3018             : 
    3019             :     /*
    3020             :      * We have to replace any outer-relation variables with nestloop params in
    3021             :      * the qpqual and bitmapqualorig expressions.  (This was already done for
    3022             :      * expressions attached to plan nodes in the bitmapqualplan tree.)
    3023             :      */
    3024       19314 :     if (best_path->path.param_info)
    3025             :     {
    3026         536 :         qpqual = (List *)
    3027             :             replace_nestloop_params(root, (Node *) qpqual);
    3028         536 :         bitmapqualorig = (List *)
    3029         536 :             replace_nestloop_params(root, (Node *) bitmapqualorig);
    3030             :     }
    3031             : 
    3032             :     /* Finally ready to build the plan node */
    3033       19314 :     scan_plan = make_bitmap_heapscan(tlist,
    3034             :                                      qpqual,
    3035             :                                      bitmapqualplan,
    3036             :                                      bitmapqualorig,
    3037             :                                      baserelid);
    3038             : 
    3039       19314 :     copy_generic_path_info(&scan_plan->scan.plan, &best_path->path);
    3040             : 
    3041       19314 :     return scan_plan;
    3042             : }
    3043             : 
    3044             : /*
    3045             :  * Given a bitmapqual tree, generate the Plan tree that implements it
    3046             :  *
    3047             :  * As byproducts, we also return in *qual and *indexqual the qual lists
    3048             :  * (in implicit-AND form, without RestrictInfos) describing the original index
    3049             :  * conditions and the generated indexqual conditions.  (These are the same in
    3050             :  * simple cases, but when special index operators are involved, the former
    3051             :  * list includes the special conditions while the latter includes the actual
    3052             :  * indexable conditions derived from them.)  Both lists include partial-index
    3053             :  * predicates, because we have to recheck predicates as well as index
    3054             :  * conditions if the bitmap scan becomes lossy.
    3055             :  *
    3056             :  * In addition, we return a list of EquivalenceClass pointers for all the
    3057             :  * top-level indexquals that were possibly-redundantly derived from ECs.
    3058             :  * This allows removal of scan_clauses that are redundant with such quals.
    3059             :  * (We do not attempt to detect such redundancies for quals that are within
    3060             :  * OR subtrees.  This could be done in a less hacky way if we returned the
    3061             :  * indexquals in RestrictInfo form, but that would be slower and still pretty
    3062             :  * messy, since we'd have to build new RestrictInfos in many cases.)
    3063             :  */
    3064             : static Plan *
    3065       19630 : create_bitmap_subplan(PlannerInfo *root, Path *bitmapqual,
    3066             :                       List **qual, List **indexqual, List **indexECs)
    3067             : {
    3068             :     Plan       *plan;
    3069             : 
    3070       19630 :     if (IsA(bitmapqual, BitmapAndPath))
    3071             :     {
    3072          44 :         BitmapAndPath *apath = (BitmapAndPath *) bitmapqual;
    3073          44 :         List       *subplans = NIL;
    3074          44 :         List       *subquals = NIL;
    3075          44 :         List       *subindexquals = NIL;
    3076          44 :         List       *subindexECs = NIL;
    3077             :         ListCell   *l;
    3078             : 
    3079             :         /*
    3080             :          * There may well be redundant quals among the subplans, since a
    3081             :          * top-level WHERE qual might have gotten used to form several
    3082             :          * different index quals.  We don't try exceedingly hard to eliminate
    3083             :          * redundancies, but we do eliminate obvious duplicates by using
    3084             :          * list_concat_unique.
    3085             :          */
    3086         132 :         foreach(l, apath->bitmapquals)
    3087             :         {
    3088             :             Plan       *subplan;
    3089             :             List       *subqual;
    3090             :             List       *subindexqual;
    3091             :             List       *subindexEC;
    3092             : 
    3093          88 :             subplan = create_bitmap_subplan(root, (Path *) lfirst(l),
    3094             :                                             &subqual, &subindexqual,
    3095             :                                             &subindexEC);
    3096          88 :             subplans = lappend(subplans, subplan);
    3097          88 :             subquals = list_concat_unique(subquals, subqual);
    3098          88 :             subindexquals = list_concat_unique(subindexquals, subindexqual);
    3099             :             /* Duplicates in indexECs aren't worth getting rid of */
    3100          88 :             subindexECs = list_concat(subindexECs, subindexEC);
    3101             :         }
    3102          44 :         plan = (Plan *) make_bitmap_and(subplans);
    3103          44 :         plan->startup_cost = apath->path.startup_cost;
    3104          44 :         plan->total_cost = apath->path.total_cost;
    3105          44 :         plan->plan_rows =
    3106          44 :             clamp_row_est(apath->bitmapselectivity * apath->path.parent->tuples);
    3107          44 :         plan->plan_width = 0;    /* meaningless */
    3108          44 :         plan->parallel_aware = false;
    3109          44 :         plan->parallel_safe = apath->path.parallel_safe;
    3110          44 :         *qual = subquals;
    3111          44 :         *indexqual = subindexquals;
    3112          44 :         *indexECs = subindexECs;
    3113             :     }
    3114       19586 :     else if (IsA(bitmapqual, BitmapOrPath))
    3115             :     {
    3116         104 :         BitmapOrPath *opath = (BitmapOrPath *) bitmapqual;
    3117         104 :         List       *subplans = NIL;
    3118         104 :         List       *subquals = NIL;
    3119         104 :         List       *subindexquals = NIL;
    3120         104 :         bool        const_true_subqual = false;
    3121         104 :         bool        const_true_subindexqual = false;
    3122             :         ListCell   *l;
    3123             : 
    3124             :         /*
    3125             :          * Here, we only detect qual-free subplans.  A qual-free subplan would
    3126             :          * cause us to generate "... OR true ..."  which we may as well reduce
    3127             :          * to just "true".  We do not try to eliminate redundant subclauses
    3128             :          * because (a) it's not as likely as in the AND case, and (b) we might
    3129             :          * well be working with hundreds or even thousands of OR conditions,
    3130             :          * perhaps from a long IN list.  The performance of list_append_unique
    3131             :          * would be unacceptable.
    3132             :          */
    3133         332 :         foreach(l, opath->bitmapquals)
    3134             :         {
    3135             :             Plan       *subplan;
    3136             :             List       *subqual;
    3137             :             List       *subindexqual;
    3138             :             List       *subindexEC;
    3139             : 
    3140         228 :             subplan = create_bitmap_subplan(root, (Path *) lfirst(l),
    3141             :                                             &subqual, &subindexqual,
    3142             :                                             &subindexEC);
    3143         228 :             subplans = lappend(subplans, subplan);
    3144         228 :             if (subqual == NIL)
    3145           0 :                 const_true_subqual = true;
    3146         228 :             else if (!const_true_subqual)
    3147         456 :                 subquals = lappend(subquals,
    3148         228 :                                    make_ands_explicit(subqual));
    3149         228 :             if (subindexqual == NIL)
    3150           0 :                 const_true_subindexqual = true;
    3151         228 :             else if (!const_true_subindexqual)
    3152         456 :                 subindexquals = lappend(subindexquals,
    3153         228 :                                         make_ands_explicit(subindexqual));
    3154             :         }
    3155             : 
    3156             :         /*
    3157             :          * In the presence of ScalarArrayOpExpr quals, we might have built
    3158             :          * BitmapOrPaths with just one subpath; don't add an OR step.
    3159             :          */
    3160         104 :         if (list_length(subplans) == 1)
    3161             :         {
    3162           0 :             plan = (Plan *) linitial(subplans);
    3163             :         }
    3164             :         else
    3165             :         {
    3166         104 :             plan = (Plan *) make_bitmap_or(subplans);
    3167         104 :             plan->startup_cost = opath->path.startup_cost;
    3168         104 :             plan->total_cost = opath->path.total_cost;
    3169         104 :             plan->plan_rows =
    3170         104 :                 clamp_row_est(opath->bitmapselectivity * opath->path.parent->tuples);
    3171         104 :             plan->plan_width = 0;    /* meaningless */
    3172         104 :             plan->parallel_aware = false;
    3173         104 :             plan->parallel_safe = opath->path.parallel_safe;
    3174             :         }
    3175             : 
    3176             :         /*
    3177             :          * If there were constant-TRUE subquals, the OR reduces to constant
    3178             :          * TRUE.  Also, avoid generating one-element ORs, which could happen
    3179             :          * due to redundancy elimination or ScalarArrayOpExpr quals.
    3180             :          */
    3181         104 :         if (const_true_subqual)
    3182           0 :             *qual = NIL;
    3183         104 :         else if (list_length(subquals) <= 1)
    3184           0 :             *qual = subquals;
    3185             :         else
    3186         104 :             *qual = list_make1(make_orclause(subquals));
    3187         104 :         if (const_true_subindexqual)
    3188           0 :             *indexqual = NIL;
    3189         104 :         else if (list_length(subindexquals) <= 1)
    3190           0 :             *indexqual = subindexquals;
    3191             :         else
    3192         104 :             *indexqual = list_make1(make_orclause(subindexquals));
    3193         104 :         *indexECs = NIL;
    3194             :     }
    3195       19482 :     else if (IsA(bitmapqual, IndexPath))
    3196             :     {
    3197       19482 :         IndexPath  *ipath = (IndexPath *) bitmapqual;
    3198             :         IndexScan  *iscan;
    3199             :         List       *subquals;
    3200             :         List       *subindexquals;
    3201             :         List       *subindexECs;
    3202             :         ListCell   *l;
    3203             : 
    3204             :         /* Use the regular indexscan plan build machinery... */
    3205       19482 :         iscan = castNode(IndexScan,
    3206             :                          create_indexscan_plan(root, ipath,
    3207             :                                                NIL, NIL, false));
    3208             :         /* then convert to a bitmap indexscan */
    3209       19482 :         plan = (Plan *) make_bitmap_indexscan(iscan->scan.scanrelid,
    3210             :                                               iscan->indexid,
    3211             :                                               iscan->indexqual,
    3212             :                                               iscan->indexqualorig);
    3213             :         /* and set its cost/width fields appropriately */
    3214       19482 :         plan->startup_cost = 0.0;
    3215       19482 :         plan->total_cost = ipath->indextotalcost;
    3216       19482 :         plan->plan_rows =
    3217       19482 :             clamp_row_est(ipath->indexselectivity * ipath->path.parent->tuples);
    3218       19482 :         plan->plan_width = 0;    /* meaningless */
    3219       19482 :         plan->parallel_aware = false;
    3220       19482 :         plan->parallel_safe = ipath->path.parallel_safe;
    3221             :         /* Extract original index clauses, actual index quals, relevant ECs */
    3222       19482 :         subquals = NIL;
    3223       19482 :         subindexquals = NIL;
    3224       19482 :         subindexECs = NIL;
    3225       39410 :         foreach(l, ipath->indexclauses)
    3226             :         {
    3227       19928 :             IndexClause *iclause = (IndexClause *) lfirst(l);
    3228       19928 :             RestrictInfo *rinfo = iclause->rinfo;
    3229             : 
    3230             :             Assert(!rinfo->pseudoconstant);
    3231       19928 :             subquals = lappend(subquals, rinfo->clause);
    3232       19928 :             subindexquals = list_concat(subindexquals,
    3233       19928 :                                         get_actual_clauses(iclause->indexquals));
    3234       19928 :             if (rinfo->parent_ec)
    3235         112 :                 subindexECs = lappend(subindexECs, rinfo->parent_ec);
    3236             :         }
    3237             :         /* We can add any index predicate conditions, too */
    3238       19606 :         foreach(l, ipath->indexinfo->indpred)
    3239             :         {
    3240         124 :             Expr       *pred = (Expr *) lfirst(l);
    3241             : 
    3242             :             /*
    3243             :              * We know that the index predicate must have been implied by the
    3244             :              * query condition as a whole, but it may or may not be implied by
    3245             :              * the conditions that got pushed into the bitmapqual.  Avoid
    3246             :              * generating redundant conditions.
    3247             :              */
    3248         124 :             if (!predicate_implied_by(list_make1(pred), subquals, false))
    3249             :             {
    3250         104 :                 subquals = lappend(subquals, pred);
    3251         104 :                 subindexquals = lappend(subindexquals, pred);
    3252             :             }
    3253             :         }
    3254       19482 :         *qual = subquals;
    3255       19482 :         *indexqual = subindexquals;
    3256       19482 :         *indexECs = subindexECs;
    3257             :     }
    3258             :     else
    3259             :     {
    3260           0 :         elog(ERROR, "unrecognized node type: %d", nodeTag(bitmapqual));
    3261             :         plan = NULL;            /* keep compiler quiet */
    3262             :     }
    3263             : 
    3264       19630 :     return plan;
    3265             : }
    3266             : 
    3267             : /*
    3268             :  * create_tidscan_plan
    3269             :  *   Returns a tidscan plan for the base relation scanned by 'best_path'
    3270             :  *   with restriction clauses 'scan_clauses' and targetlist 'tlist'.
    3271             :  */
    3272             : static TidScan *
    3273         410 : create_tidscan_plan(PlannerInfo *root, TidPath *best_path,
    3274             :                     List *tlist, List *scan_clauses)
    3275             : {
    3276             :     TidScan    *scan_plan;
    3277         410 :     Index       scan_relid = best_path->path.parent->relid;
    3278         410 :     List       *tidquals = best_path->tidquals;
    3279             : 
    3280             :     /* it should be a base rel... */
    3281             :     Assert(scan_relid > 0);
    3282             :     Assert(best_path->path.parent->rtekind == RTE_RELATION);
    3283             : 
    3284             :     /*
    3285             :      * The qpqual list must contain all restrictions not enforced by the
    3286             :      * tidquals list.  Since tidquals has OR semantics, we have to be careful
    3287             :      * about matching it up to scan_clauses.  It's convenient to handle the
    3288             :      * single-tidqual case separately from the multiple-tidqual case.  In the
    3289             :      * single-tidqual case, we look through the scan_clauses while they are
    3290             :      * still in RestrictInfo form, and drop any that are redundant with the
    3291             :      * tidqual.
    3292             :      *
    3293             :      * In normal cases simple pointer equality checks will be enough to spot
    3294             :      * duplicate RestrictInfos, so we try that first.
    3295             :      *
    3296             :      * Another common case is that a scan_clauses entry is generated from the
    3297             :      * same EquivalenceClass as some tidqual, and is therefore redundant with
    3298             :      * it, though not equal.
    3299             :      *
    3300             :      * Unlike indexpaths, we don't bother with predicate_implied_by(); the
    3301             :      * number of cases where it could win are pretty small.
    3302             :      */
    3303         410 :     if (list_length(tidquals) == 1)
    3304             :     {
    3305         394 :         List       *qpqual = NIL;
    3306             :         ListCell   *l;
    3307             : 
    3308         836 :         foreach(l, scan_clauses)
    3309             :         {
    3310         442 :             RestrictInfo *rinfo = lfirst_node(RestrictInfo, l);
    3311             : 
    3312         442 :             if (rinfo->pseudoconstant)
    3313           0 :                 continue;       /* we may drop pseudoconstants here */
    3314         442 :             if (list_member_ptr(tidquals, rinfo))
    3315         386 :                 continue;       /* simple duplicate */
    3316          56 :             if (is_redundant_derived_clause(rinfo, tidquals))
    3317           8 :                 continue;       /* derived from same EquivalenceClass */
    3318          48 :             qpqual = lappend(qpqual, rinfo);
    3319             :         }
    3320         394 :         scan_clauses = qpqual;
    3321             :     }
    3322             : 
    3323             :     /* Sort clauses into best execution order */
    3324         410 :     scan_clauses = order_qual_clauses(root, scan_clauses);
    3325             : 
    3326             :     /* Reduce RestrictInfo lists to bare expressions; ignore pseudoconstants */
    3327         410 :     tidquals = extract_actual_clauses(tidquals, false);
    3328         410 :     scan_clauses = extract_actual_clauses(scan_clauses, false);
    3329             : 
    3330             :     /*
    3331             :      * If we have multiple tidquals, it's more convenient to remove duplicate
    3332             :      * scan_clauses after stripping the RestrictInfos.  In this situation,
    3333             :      * because the tidquals represent OR sub-clauses, they could not have come
    3334             :      * from EquivalenceClasses so we don't have to worry about matching up
    3335             :      * non-identical clauses.  On the other hand, because tidpath.c will have
    3336             :      * extracted those sub-clauses from some OR clause and built its own list,
    3337             :      * we will certainly not have pointer equality to any scan clause.  So
    3338             :      * convert the tidquals list to an explicit OR clause and see if we can
    3339             :      * match it via equal() to any scan clause.
    3340             :      */
    3341         410 :     if (list_length(tidquals) > 1)
    3342          16 :         scan_clauses = list_difference(scan_clauses,
    3343          16 :                                        list_make1(make_orclause(tidquals)));
    3344             : 
    3345             :     /* Replace any outer-relation variables with nestloop params */
    3346         410 :     if (best_path->path.param_info)
    3347             :     {
    3348          16 :         tidquals = (List *)
    3349             :             replace_nestloop_params(root, (Node *) tidquals);
    3350          16 :         scan_clauses = (List *)
    3351             :             replace_nestloop_params(root, (Node *) scan_clauses);
    3352             :     }
    3353             : 
    3354         410 :     scan_plan = make_tidscan(tlist,
    3355             :                              scan_clauses,
    3356             :                              scan_relid,
    3357             :                              tidquals);
    3358             : 
    3359         410 :     copy_generic_path_info(&scan_plan->scan.plan, &best_path->path);
    3360             : 
    3361         410 :     return scan_plan;
    3362             : }
    3363             : 
    3364             : /*
    3365             :  * create_subqueryscan_plan
    3366             :  *   Returns a subqueryscan plan for the base relation scanned by 'best_path'
    3367             :  *   with restriction clauses 'scan_clauses' and targetlist 'tlist'.
    3368             :  */
    3369             : static SubqueryScan *
    3370        8278 : create_subqueryscan_plan(PlannerInfo *root, SubqueryScanPath *best_path,
    3371             :                          List *tlist, List *scan_clauses)
    3372             : {
    3373             :     SubqueryScan *scan_plan;
    3374        8278 :     RelOptInfo *rel = best_path->path.parent;
    3375        8278 :     Index       scan_relid = rel->relid;
    3376             :     Plan       *subplan;
    3377             : 
    3378             :     /* it should be a subquery base rel... */
    3379             :     Assert(scan_relid > 0);
    3380             :     Assert(rel->rtekind == RTE_SUBQUERY);
    3381             : 
    3382             :     /*
    3383             :      * Recursively create Plan from Path for subquery.  Since we are entering
    3384             :      * a different planner context (subroot), recurse to create_plan not
    3385             :      * create_plan_recurse.
    3386             :      */
    3387        8278 :     subplan = create_plan(rel->subroot, best_path->subpath);
    3388             : 
    3389             :     /* Sort clauses into best execution order */
    3390        8278 :     scan_clauses = order_qual_clauses(root, scan_clauses);
    3391             : 
    3392             :     /* Reduce RestrictInfo list to bare expressions; ignore pseudoconstants */
    3393        8278 :     scan_clauses = extract_actual_clauses(scan_clauses, false);
    3394             : 
    3395             :     /* Replace any outer-relation variables with nestloop params */
    3396        8278 :     if (best_path->path.param_info)
    3397             :     {
    3398         192 :         scan_clauses = (List *)
    3399             :             replace_nestloop_params(root, (Node *) scan_clauses);
    3400         192 :         process_subquery_nestloop_params(root,
    3401             :                                          rel->subplan_params);
    3402             :     }
    3403             : 
    3404        8278 :     scan_plan = make_subqueryscan(tlist,
    3405             :                                   scan_clauses,
    3406             :                                   scan_relid,
    3407             :                                   subplan);
    3408             : 
    3409        8278 :     copy_generic_path_info(&scan_plan->scan.plan, &best_path->path);
    3410             : 
    3411        8278 :     return scan_plan;
    3412             : }
    3413             : 
    3414             : /*
    3415             :  * create_functionscan_plan
    3416             :  *   Returns a functionscan plan for the base relation scanned by 'best_path'
    3417             :  *   with restriction clauses 'scan_clauses' and targetlist 'tlist'.
    3418             :  */
    3419             : static FunctionScan *
    3420       28676 : create_functionscan_plan(PlannerInfo *root, Path *best_path,
    3421             :                          List *tlist, List *scan_clauses)
    3422             : {
    3423             :     FunctionScan *scan_plan;
    3424       28676 :     Index       scan_relid = best_path->parent->relid;
    3425             :     RangeTblEntry *rte;
    3426             :     List       *functions;
    3427             : 
    3428             :     /* it should be a function base rel... */
    3429             :     Assert(scan_relid > 0);
    3430       28676 :     rte = planner_rt_fetch(scan_relid, root);
    3431             :     Assert(rte->rtekind == RTE_FUNCTION);
    3432       28676 :     functions = rte->functions;
    3433             : 
    3434             :     /* Sort clauses into best execution order */
    3435       28676 :     scan_clauses = order_qual_clauses(root, scan_clauses);
    3436             : 
    3437             :     /* Reduce RestrictInfo list to bare expressions; ignore pseudoconstants */
    3438       28676 :     scan_clauses = extract_actual_clauses(scan_clauses, false);
    3439             : 
    3440             :     /* Replace any outer-relation variables with nestloop params */
    3441       28676 :     if (best_path->param_info)
    3442             :     {
    3443         342 :         scan_clauses = (List *)
    3444             :             replace_nestloop_params(root, (Node *) scan_clauses);
    3445             :         /* The function expressions could contain nestloop params, too */
    3446         342 :         functions = (List *) replace_nestloop_params(root, (Node *) functions);
    3447             :     }
    3448             : 
    3449       28676 :     scan_plan = make_functionscan(tlist, scan_clauses, scan_relid,
    3450       28676 :                                   functions, rte->funcordinality);
    3451             : 
    3452       28676 :     copy_generic_path_info(&scan_plan->scan.plan, best_path);
    3453             : 
    3454       28676 :     return scan_plan;
    3455             : }
    3456             : 
    3457             : /*
    3458             :  * create_tablefuncscan_plan
    3459             :  *   Returns a tablefuncscan plan for the base relation scanned by 'best_path'
    3460             :  *   with restriction clauses 'scan_clauses' and targetlist 'tlist'.
    3461             :  */
    3462             : static TableFuncScan *
    3463         144 : create_tablefuncscan_plan(PlannerInfo *root, Path *best_path,
    3464             :                           List *tlist, List *scan_clauses)
    3465             : {
    3466             :     TableFuncScan *scan_plan;
    3467         144 :     Index       scan_relid = best_path->parent->relid;
    3468             :     RangeTblEntry *rte;
    3469             :     TableFunc  *tablefunc;
    3470             : 
    3471             :     /* it should be a function base rel... */
    3472             :     Assert(scan_relid > 0);
    3473         144 :     rte = planner_rt_fetch(scan_relid, root);
    3474             :     Assert(rte->rtekind == RTE_TABLEFUNC);
    3475         144 :     tablefunc = rte->tablefunc;
    3476             : 
    3477             :     /* Sort clauses into best execution order */
    3478         144 :     scan_clauses = order_qual_clauses(root, scan_clauses);
    3479             : 
    3480             :     /* Reduce RestrictInfo list to bare expressions; ignore pseudoconstants */
    3481         144 :     scan_clauses = extract_actual_clauses(scan_clauses, false);
    3482             : 
    3483             :     /* Replace any outer-relation variables with nestloop params */
    3484         144 :     if (best_path->param_info)
    3485             :     {
    3486          96 :         scan_clauses = (List *)
    3487             :             replace_nestloop_params(root, (Node *) scan_clauses);
    3488             :         /* The function expressions could contain nestloop params, too */
    3489          96 :         tablefunc = (TableFunc *) replace_nestloop_params(root, (Node *) tablefunc);
    3490             :     }
    3491             : 
    3492         144 :     scan_plan = make_tablefuncscan(tlist, scan_clauses, scan_relid,
    3493             :                                    tablefunc);
    3494             : 
    3495         144 :     copy_generic_path_info(&scan_plan->scan.plan, best_path);
    3496             : 
    3497         144 :     return scan_plan;
    3498             : }
    3499             : 
    3500             : /*
    3501             :  * create_valuesscan_plan
    3502             :  *   Returns a valuesscan plan for the base relation scanned by 'best_path'
    3503             :  *   with restriction clauses 'scan_clauses' and targetlist 'tlist'.
    3504             :  */
    3505             : static ValuesScan *
    3506        3792 : create_valuesscan_plan(PlannerInfo *root, Path *best_path,
    3507             :                        List *tlist, List *scan_clauses)
    3508             : {
    3509             :     ValuesScan *scan_plan;
    3510        3792 :     Index       scan_relid = best_path->parent->relid;
    3511             :     RangeTblEntry *rte;
    3512             :     List       *values_lists;
    3513             : 
    3514             :     /* it should be a values base rel... */
    3515             :     Assert(scan_relid > 0);
    3516        3792 :     rte = planner_rt_fetch(scan_relid, root);
    3517             :     Assert(rte->rtekind == RTE_VALUES);
    3518        3792 :     values_lists = rte->values_lists;
    3519             : 
    3520             :     /* Sort clauses into best execution order */
    3521        3792 :     scan_clauses = order_qual_clauses(root, scan_clauses);
    3522             : 
    3523             :     /* Reduce RestrictInfo list to bare expressions; ignore pseudoconstants */
    3524        3792 :     scan_clauses = extract_actual_clauses(scan_clauses, false);
    3525             : 
    3526             :     /* Replace any outer-relation variables with nestloop params */
    3527        3792 :     if (best_path->param_info)
    3528             :     {
    3529          28 :         scan_clauses = (List *)
    3530             :             replace_nestloop_params(root, (Node *) scan_clauses);
    3531             :         /* The values lists could contain nestloop params, too */
    3532          28 :         values_lists = (List *)
    3533             :             replace_nestloop_params(root, (Node *) values_lists);
    3534             :     }
    3535             : 
    3536        3792 :     scan_plan = make_valuesscan(tlist, scan_clauses, scan_relid,
    3537             :                                 values_lists);
    3538             : 
    3539        3792 :     copy_generic_path_info(&scan_plan->scan.plan, best_path);
    3540             : 
    3541        3792 :     return scan_plan;
    3542             : }
    3543             : 
    3544             : /*
    3545             :  * create_ctescan_plan
    3546             :  *   Returns a ctescan plan for the base relation scanned by 'best_path'
    3547             :  *   with restriction clauses 'scan_clauses' and targetlist 'tlist'.
    3548             :  */
    3549             : static CteScan *
    3550         876 : create_ctescan_plan(PlannerInfo *root, Path *best_path,
    3551             :                     List *tlist, List *scan_clauses)
    3552             : {
    3553             :     CteScan    *scan_plan;
    3554         876 :     Index       scan_relid = best_path->parent->relid;
    3555             :     RangeTblEntry *rte;
    3556         876 :     SubPlan    *ctesplan = NULL;
    3557             :     int         plan_id;
    3558             :     int         cte_param_id;
    3559             :     PlannerInfo *cteroot;
    3560             :     Index       levelsup;
    3561             :     int         ndx;
    3562             :     ListCell   *lc;
    3563             : 
    3564             :     Assert(scan_relid > 0);
    3565         876 :     rte = planner_rt_fetch(scan_relid, root);
    3566             :     Assert(rte->rtekind == RTE_CTE);
    3567             :     Assert(!rte->self_reference);
    3568             : 
    3569             :     /*
    3570             :      * Find the referenced CTE, and locate the SubPlan previously made for it.
    3571             :      */
    3572         876 :     levelsup = rte->ctelevelsup;
    3573         876 :     cteroot = root;
    3574        2024 :     while (levelsup-- > 0)
    3575             :     {
    3576         272 :         cteroot = cteroot->parent_root;
    3577         272 :         if (!cteroot)           /* shouldn't happen */
    3578           0 :             elog(ERROR, "bad levelsup for CTE \"%s\"", rte->ctename);
    3579             :     }
    3580             : 
    3581             :     /*
    3582             :      * Note: cte_plan_ids can be shorter than cteList, if we are still working
    3583             :      * on planning the CTEs (ie, this is a side-reference from another CTE).
    3584             :      * So we mustn't use forboth here.
    3585             :      */
    3586         876 :     ndx = 0;
    3587         998 :     foreach(lc, cteroot->parse->cteList)
    3588             :     {
    3589         998 :         CommonTableExpr *cte = (CommonTableExpr *) lfirst(lc);
    3590             : 
    3591         998 :         if (strcmp(cte->ctename, rte->ctename) == 0)
    3592         876 :             break;
    3593         122 :         ndx++;
    3594             :     }
    3595         876 :     if (lc == NULL)             /* shouldn't happen */
    3596           0 :         elog(ERROR, "could not find CTE \"%s\"", rte->ctename);
    3597         876 :     if (ndx >= list_length(cteroot->cte_plan_ids))
    3598           0 :         elog(ERROR, "could not find plan for CTE \"%s\"", rte->ctename);
    3599         876 :     plan_id = list_nth_int(cteroot->cte_plan_ids, ndx);
    3600             :     Assert(plan_id > 0);
    3601         960 :     foreach(lc, cteroot->init_plans)
    3602             :     {
    3603         960 :         ctesplan = (SubPlan *) lfirst(lc);
    3604         960 :         if (ctesplan->plan_id == plan_id)
    3605         876 :             break;
    3606             :     }
    3607         876 :     if (lc == NULL)             /* shouldn't happen */
    3608           0 :         elog(ERROR, "could not find plan for CTE \"%s\"", rte->ctename);
    3609             : 
    3610             :     /*
    3611             :      * We need the CTE param ID, which is the sole member of the SubPlan's
    3612             :      * setParam list.
    3613             :      */
    3614         876 :     cte_param_id = linitial_int(ctesplan->setParam);
    3615             : 
    3616             :     /* Sort clauses into best execution order */
    3617         876 :     scan_clauses = order_qual_clauses(root, scan_clauses);
    3618             : 
    3619             :     /* Reduce RestrictInfo list to bare expressions; ignore pseudoconstants */
    3620         876 :     scan_clauses = extract_actual_clauses(scan_clauses, false);
    3621             : 
    3622             :     /* Replace any outer-relation variables with nestloop params */
    3623         876 :     if (best_path->param_info)
    3624             :     {
    3625           0 :         scan_clauses = (List *)
    3626             :             replace_nestloop_params(root, (Node *) scan_clauses);
    3627             :     }
    3628             : 
    3629         876 :     scan_plan = make_ctescan(tlist, scan_clauses, scan_relid,
    3630             :                              plan_id, cte_param_id);
    3631             : 
    3632         876 :     copy_generic_path_info(&scan_plan->scan.plan, best_path);
    3633             : 
    3634         876 :     return scan_plan;
    3635             : }
    3636             : 
    3637             : /*
    3638             :  * create_namedtuplestorescan_plan
    3639             :  *   Returns a tuplestorescan plan for the base relation scanned by
    3640             :  *  'best_path' with restriction clauses 'scan_clauses' and targetlist
    3641             :  *  'tlist'.
    3642             :  */
    3643             : static NamedTuplestoreScan *
    3644         256 : create_namedtuplestorescan_plan(PlannerInfo *root, Path *best_path,
    3645             :                                 List *tlist, List *scan_clauses)
    3646             : {
    3647             :     NamedTuplestoreScan *scan_plan;
    3648         256 :     Index       scan_relid = best_path->parent->relid;
    3649             :     RangeTblEntry *rte;
    3650             : 
    3651             :     Assert(scan_relid > 0);
    3652         256 :     rte = planner_rt_fetch(scan_relid, root);
    3653             :     Assert(rte->rtekind == RTE_NAMEDTUPLESTORE);
    3654             : 
    3655             :     /* Sort clauses into best execution order */
    3656         256 :     scan_clauses = order_qual_clauses(root, scan_clauses);
    3657             : 
    3658             :     /* Reduce RestrictInfo list to bare expressions; ignore pseudoconstants */
    3659         256 :     scan_clauses = extract_actual_clauses(scan_clauses, false);
    3660             : 
    3661             :     /* Replace any outer-relation variables with nestloop params */
    3662         256 :     if (best_path->param_info)
    3663             :     {
    3664           0 :         scan_clauses = (List *)
    3665             :             replace_nestloop_params(root, (Node *) scan_clauses);
    3666             :     }
    3667             : 
    3668         256 :     scan_plan = make_namedtuplestorescan(tlist, scan_clauses, scan_relid,
    3669             :                                          rte->enrname);
    3670             : 
    3671         256 :     copy_generic_path_info(&scan_plan->scan.plan, best_path);
    3672             : 
    3673         256 :     return scan_plan;
    3674             : }
    3675             : 
    3676             : /*
    3677             :  * create_resultscan_plan
    3678             :  *   Returns a Result plan for the RTE_RESULT base relation scanned by
    3679             :  *  'best_path' with restriction clauses 'scan_clauses' and targetlist
    3680             :  *  'tlist'.
    3681             :  */
    3682             : static Result *
    3683         590 : create_resultscan_plan(PlannerInfo *root, Path *best_path,
    3684             :                        List *tlist, List *scan_clauses)
    3685             : {
    3686             :     Result     *scan_plan;
    3687         590 :     Index       scan_relid = best_path->parent->relid;
    3688             :     RangeTblEntry *rte PG_USED_FOR_ASSERTS_ONLY;
    3689             : 
    3690             :     Assert(scan_relid > 0);
    3691         590 :     rte = planner_rt_fetch(scan_relid, root);
    3692             :     Assert(rte->rtekind == RTE_RESULT);
    3693             : 
    3694             :     /* Sort clauses into best execution order */
    3695         590 :     scan_clauses = order_qual_clauses(root, scan_clauses);
    3696             : 
    3697             :     /* Reduce RestrictInfo list to bare expressions; ignore pseudoconstants */
    3698         590 :     scan_clauses = extract_actual_clauses(scan_clauses, false);
    3699             : 
    3700             :     /* Replace any outer-relation variables with nestloop params */
    3701         590 :     if (best_path->param_info)
    3702             :     {
    3703          60 :         scan_clauses = (List *)
    3704             :             replace_nestloop_params(root, (Node *) scan_clauses);
    3705             :     }
    3706             : 
    3707         590 :     scan_plan = make_result(tlist, (Node *) scan_clauses, NULL);
    3708             : 
    3709         590 :     copy_generic_path_info(&scan_plan->plan, best_path);
    3710             : 
    3711         590 :     return scan_plan;
    3712             : }
    3713             : 
    3714             : /*
    3715             :  * create_worktablescan_plan
    3716             :  *   Returns a worktablescan plan for the base relation scanned by 'best_path'
    3717             :  *   with restriction clauses 'scan_clauses' and targetlist 'tlist'.
    3718             :  */
    3719             : static WorkTableScan *
    3720         320 : create_worktablescan_plan(PlannerInfo *root, Path *best_path,
    3721             :                           List *tlist, List *scan_clauses)
    3722             : {
    3723             :     WorkTableScan *scan_plan;
    3724         320 :     Index       scan_relid = best_path->parent->relid;
    3725             :     RangeTblEntry *rte;
    3726             :     Index       levelsup;
    3727             :     PlannerInfo *cteroot;
    3728             : 
    3729             :     Assert(scan_relid > 0);
    3730         320 :     rte = planner_rt_fetch(scan_relid, root);
    3731             :     Assert(rte->rtekind == RTE_CTE);
    3732             :     Assert(rte->self_reference);
    3733             : 
    3734             :     /*
    3735             :      * We need to find the worktable param ID, which is in the plan level
    3736             :      * that's processing the recursive UNION, which is one level *below* where
    3737             :      * the CTE comes from.
    3738             :      */
    3739         320 :     levelsup = rte->ctelevelsup;
    3740         320 :     if (levelsup == 0)          /* shouldn't happen */
    3741           0 :         elog(ERROR, "bad levelsup for CTE \"%s\"", rte->ctename);
    3742         320 :     levelsup--;
    3743         320 :     cteroot = root;
    3744         996 :     while (levelsup-- > 0)
    3745             :     {
    3746         356 :         cteroot = cteroot->parent_root;
    3747         356 :         if (!cteroot)           /* shouldn't happen */
    3748           0 :             elog(ERROR, "bad levelsup for CTE \"%s\"", rte->ctename);
    3749             :     }
    3750         320 :     if (cteroot->wt_param_id < 0) /* shouldn't happen */
    3751           0 :         elog(ERROR, "could not find param ID for CTE \"%s\"", rte->ctename);
    3752             : 
    3753             :     /* Sort clauses into best execution order */
    3754         320 :     scan_clauses = order_qual_clauses(root, scan_clauses);
    3755             : 
    3756             :     /* Reduce RestrictInfo list to bare expressions; ignore pseudoconstants */
    3757         320 :     scan_clauses = extract_actual_clauses(scan_clauses, false);
    3758             : 
    3759             :     /* Replace any outer-relation variables with nestloop params */
    3760         320 :     if (best_path->param_info)
    3761             :     {
    3762           0 :         scan_clauses = (List *)
    3763             :             replace_nestloop_params(root, (Node *) scan_clauses);
    3764             :     }
    3765             : 
    3766         320 :     scan_plan = make_worktablescan(tlist, scan_clauses, scan_relid,
    3767             :                                    cteroot->wt_param_id);
    3768             : 
    3769         320 :     copy_generic_path_info(&scan_plan->scan.plan, best_path);
    3770             : 
    3771         320 :     return scan_plan;
    3772             : }
    3773             : 
    3774             : /*
    3775             :  * create_foreignscan_plan
    3776             :  *   Returns a foreignscan plan for the relation scanned by 'best_path'
    3777             :  *   with restriction clauses 'scan_clauses' and targetlist 'tlist'.
    3778             :  */
    3779             : static ForeignScan *
    3780        1420 : create_foreignscan_plan(PlannerInfo *root, ForeignPath *best_path,
    3781             :                         List *tlist, List *scan_clauses)
    3782             : {
    3783             :     ForeignScan *scan_plan;
    3784        1420 :     RelOptInfo *rel = best_path->path.parent;
    3785        1420 :     Index       scan_relid = rel->relid;
    3786        1420 :     Oid         rel_oid = InvalidOid;
    3787        1420 :     Plan       *outer_plan = NULL;
    3788             : 
    3789             :     Assert(rel->fdwroutine != NULL);
    3790             : 
    3791             :     /* transform the child path if any */
    3792        1420 :     if (best_path->fdw_outerpath)
    3793          40 :         outer_plan = create_plan_recurse(root, best_path->fdw_outerpath,
    3794             :                                          CP_EXACT_TLIST);
    3795             : 
    3796             :     /*
    3797             :      * If we're scanning a base relation, fetch its OID.  (Irrelevant if
    3798             :      * scanning a join relation.)
    3799             :      */
    3800        1420 :     if (scan_relid > 0)
    3801             :     {
    3802             :         RangeTblEntry *rte;
    3803             : 
    3804             :         Assert(rel->rtekind == RTE_RELATION);
    3805         980 :         rte = planner_rt_fetch(scan_relid, root);
    3806             :         Assert(rte->rtekind == RTE_RELATION);
    3807         980 :         rel_oid = rte->relid;
    3808             :     }
    3809             : 
    3810             :     /*
    3811             :      * Sort clauses into best execution order.  We do this first since the FDW
    3812             :      * might have more info than we do and wish to adjust the ordering.
    3813             :      */
    3814        1420 :     scan_clauses = order_qual_clauses(root, scan_clauses);
    3815             : 
    3816             :     /*
    3817             :      * Let the FDW perform its processing on the restriction clauses and
    3818             :      * generate the plan node.  Note that the FDW might remove restriction
    3819             :      * clauses that it intends to execute remotely, or even add more (if it
    3820             :      * has selected some join clauses for remote use but also wants them
    3821             :      * rechecked locally).
    3822             :      */
    3823        1420 :     scan_plan = rel->fdwroutine->GetForeignPlan(root, rel, rel_oid,
    3824             :                                                 best_path,
    3825             :                                                 tlist, scan_clauses,
    3826             :                                                 outer_plan);
    3827             : 
    3828             :     /* Copy cost data from Path to Plan; no need to make FDW do this */
    3829        1420 :     copy_generic_path_info(&scan_plan->scan.plan, &best_path->path);
    3830             : 
    3831             :     /* Copy foreign server OID; likewise, no need to make FDW do this */
    3832        1420 :     scan_plan->fs_server = rel->serverid;
    3833             : 
    3834             :     /*
    3835             :      * Likewise, copy the relids that are represented by this foreign scan. An
    3836             :      * upper rel doesn't have relids set, but it covers all the base relations
    3837             :      * participating in the underlying scan, so use root's all_baserels.
    3838             :      */
    3839        1420 :     if (rel->reloptkind == RELOPT_UPPER_REL)
    3840         190 :         scan_plan->fs_relids = root->all_baserels;
    3841             :     else
    3842        1230 :         scan_plan->fs_relids = best_path->path.parent->relids;
    3843             : 
    3844             :     /*
    3845             :      * If this is a foreign join, and to make it valid to push down we had to
    3846             :      * assume that the current user is the same as some user explicitly named
    3847             :      * in the query, mark the finished plan as depending on the current user.
    3848             :      */
    3849        1420 :     if (rel->useridiscurrent)
    3850           4 :         root->glob->dependsOnRole = true;
    3851             : 
    3852             :     /*
    3853             :      * Replace any outer-relation variables with nestloop params in the qual,
    3854             :      * fdw_exprs and fdw_recheck_quals expressions.  We do this last so that
    3855             :      * the FDW doesn't have to be involved.  (Note that parts of fdw_exprs or
    3856             :      * fdw_recheck_quals could have come from join clauses, so doing this
    3857             :      * beforehand on the scan_clauses wouldn't work.)  We assume
    3858             :      * fdw_scan_tlist contains no such variables.
    3859             :      */
    3860        1420 :     if (best_path->path.param_info)
    3861             :     {
    3862          12 :         scan_plan->scan.plan.qual = (List *)
    3863          12 :             replace_nestloop_params(root, (Node *) scan_plan->scan.plan.qual);
    3864          12 :         scan_plan->fdw_exprs = (List *)
    3865          12 :             replace_nestloop_params(root, (Node *) scan_plan->fdw_exprs);
    3866          12 :         scan_plan->fdw_recheck_quals = (List *)
    3867          12 :             replace_nestloop_params(root,
    3868          12 :                                     (Node *) scan_plan->fdw_recheck_quals);
    3869             :     }
    3870             : 
    3871             :     /*
    3872             :      * If rel is a base relation, detect whether any system columns are
    3873             :      * requested from the rel.  (If rel is a join relation, rel->relid will be
    3874             :      * 0, but there can be no Var with relid 0 in the rel's targetlist or the
    3875             :      * restriction clauses, so we skip this in that case.  Note that any such
    3876             :      * columns in base relations that were joined are assumed to be contained
    3877             :      * in fdw_scan_tlist.)  This is a bit of a kluge and might go away
    3878             :      * someday, so we intentionally leave it out of the API presented to FDWs.
    3879             :      */
    3880        1420 :     scan_plan->fsSystemCol = false;
    3881        1420 :     if (scan_relid > 0)
    3882             :     {
    3883         980 :         Bitmapset  *attrs_used = NULL;
    3884             :         ListCell   *lc;
    3885             :         int         i;
    3886             : 
    3887             :         /*
    3888             :          * First, examine all the attributes needed for joins or final output.
    3889             :          * Note: we must look at rel's targetlist, not the attr_needed data,
    3890             :          * because attr_needed isn't computed for inheritance child rels.
    3891             :          */
    3892         980 :         pull_varattnos((Node *) rel->reltarget->exprs, scan_relid, &attrs_used);
    3893             : 
    3894             :         /* Add all the attributes used by restriction clauses. */
    3895        1444 :         foreach(lc, rel->baserestrictinfo)
    3896             :         {
    3897         464 :             RestrictInfo *rinfo = (RestrictInfo *) lfirst(lc);
    3898             : 
    3899         464 :             pull_varattnos((Node *) rinfo->clause, scan_relid, &attrs_used);
    3900             :         }
    3901             : 
    3902             :         /* Now, are any system columns requested from rel? */
    3903        5836 :         for (i = FirstLowInvalidHeapAttributeNumber + 1; i < 0; i++)
    3904             :         {
    3905        5250 :             if (bms_is_member(i - FirstLowInvalidHeapAttributeNumber, attrs_used))
    3906             :             {
    3907         394 :                 scan_plan->fsSystemCol = true;
    3908         394 :                 break;
    3909             :             }
    3910             :         }
    3911             : 
    3912         980 :         bms_free(attrs_used);
    3913             :     }
    3914             : 
    3915        1420 :     return scan_plan;
    3916             : }
    3917             : 
    3918             : /*
    3919             :  * create_customscan_plan
    3920             :  *
    3921             :  * Transform a CustomPath into a Plan.
    3922             :  */
    3923             : static CustomScan *
    3924           0 : create_customscan_plan(PlannerInfo *root, CustomPath *best_path,
    3925             :                        List *tlist, List *scan_clauses)
    3926             : {
    3927             :     CustomScan *cplan;
    3928           0 :     RelOptInfo *rel = best_path->path.parent;
    3929           0 :     List       *custom_plans = NIL;
    3930             :     ListCell   *lc;
    3931             : 
    3932             :     /* Recursively transform child paths. */
    3933           0 :     foreach(lc, best_path->custom_paths)
    3934             :     {
    3935           0 :         Plan       *plan = create_plan_recurse(root, (Path *) lfirst(lc),
    3936             :                                                CP_EXACT_TLIST);
    3937             : 
    3938           0 :         custom_plans = lappend(custom_plans, plan);
    3939             :     }
    3940             : 
    3941             :     /*
    3942             :      * Sort clauses into the best execution order, although custom-scan
    3943             :      * provider can reorder them again.
    3944             :      */
    3945           0 :     scan_clauses = order_qual_clauses(root, scan_clauses);
    3946             : 
    3947             :     /*
    3948             :      * Invoke custom plan provider to create the Plan node represented by the
    3949             :      * CustomPath.
    3950             :      */
    3951           0 :     cplan = castNode(CustomScan,
    3952             :                      best_path->methods->PlanCustomPath(root,
    3953             :                                                         rel,
    3954             :                                                         best_path,
    3955             :                                                         tlist,
    3956             :                                                         scan_clauses,
    3957             :                                                         custom_plans));
    3958             : 
    3959             :     /*
    3960             :      * Copy cost data from Path to Plan; no need to make custom-plan providers
    3961             :      * do this
    3962             :      */
    3963           0 :     copy_generic_path_info(&cplan->scan.plan, &best_path->path);
    3964             : 
    3965             :     /* Likewise, copy the relids that are represented by this custom scan */
    3966           0 :     cplan->custom_relids = best_path->path.parent->relids;
    3967             : 
    3968             :     /*
    3969             :      * Replace any outer-relation variables with nestloop params in the qual
    3970             :      * and custom_exprs expressions.  We do this last so that the custom-plan
    3971             :      * provider doesn't have to be involved.  (Note that parts of custom_exprs
    3972             :      * could have come from join clauses, so doing this beforehand on the
    3973             :      * scan_clauses wouldn't work.)  We assume custom_scan_tlist contains no
    3974             :      * such variables.
    3975             :      */
    3976           0 :     if (best_path->path.param_info)
    3977             :     {
    3978           0 :         cplan->scan.plan.qual = (List *)
    3979           0 :             replace_nestloop_params(root, (Node *) cplan->scan.plan.qual);
    3980           0 :         cplan->custom_exprs = (List *)
    3981           0 :             replace_nestloop_params(root, (Node *) cplan->custom_exprs);
    3982             :     }
    3983             : 
    3984           0 :     return cplan;
    3985             : }
    3986             : 
    3987             : 
    3988             : /*****************************************************************************
    3989             :  *
    3990             :  *  JOIN METHODS
    3991             :  *
    3992             :  *****************************************************************************/
    3993             : 
    3994             : static NestLoop *
    3995       31470 : create_nestloop_plan(PlannerInfo *root,
    3996             :                      NestPath *best_path)
    3997             : {
    3998             :     NestLoop   *join_plan;
    3999             :     Plan       *outer_plan;
    4000             :     Plan       *inner_plan;
    4001       31470 :     List       *tlist = build_path_tlist(root, &best_path->path);
    4002       31470 :     List       *joinrestrictclauses = best_path->joinrestrictinfo;
    4003             :     List       *joinclauses;
    4004             :     List       *otherclauses;
    4005             :     Relids      outerrelids;
    4006             :     List       *nestParams;
    4007       31470 :     Relids      saveOuterRels = root->curOuterRels;
    4008             : 
    4009             :     /* NestLoop can project, so no need to be picky about child tlists */
    4010       31470 :     outer_plan = create_plan_recurse(root, best_path->outerjoinpath, 0);
    4011             : 
    4012             :     /* For a nestloop, include outer relids in curOuterRels for inner side */
    4013       31470 :     root->curOuterRels = bms_union(root->curOuterRels,
    4014       31470 :                                    best_path->outerjoinpath->parent->relids);
    4015             : 
    4016       31470 :     inner_plan = create_plan_recurse(root, best_path->innerjoinpath, 0);
    4017             : 
    4018             :     /* Restore curOuterRels */
    4019       31470 :     bms_free(root->curOuterRels);
    4020       31470 :     root->curOuterRels = saveOuterRels;
    4021             : 
    4022             :     /* Sort join qual clauses into best execution order */
    4023       31470 :     joinrestrictclauses = order_qual_clauses(root, joinrestrictclauses);
    4024             : 
    4025             :     /* Get the join qual clauses (in plain expression form) */
    4026             :     /* Any pseudoconstant clauses are ignored here */
    4027       31470 :     if (IS_OUTER_JOIN(best_path->jointype))
    4028             :     {
    4029       14990 :         extract_actual_join_clauses(joinrestrictclauses,
    4030       14990 :                                     best_path->path.parent->relids,
    4031             :                                     &joinclauses, &otherclauses);
    4032             :     }
    4033             :     else
    4034             :     {
    4035             :         /* We can treat all clauses alike for an inner join */
    4036       16480 :         joinclauses = extract_actual_clauses(joinrestrictclauses, false);
    4037       16480 :         otherclauses = NIL;
    4038             :     }
    4039             : 
    4040             :     /* Replace any outer-relation variables with nestloop params */
    4041       31470 :     if (best_path->path.param_info)
    4042             :     {
    4043         380 :         joinclauses = (List *)
    4044         380 :             replace_nestloop_params(root, (Node *) joinclauses);
    4045         380 :         otherclauses = (List *)
    4046         380 :             replace_nestloop_params(root, (Node *) otherclauses);
    4047             :     }
    4048             : 
    4049             :     /*
    4050             :      * Identify any nestloop parameters that should be supplied by this join
    4051             :      * node, and remove them from root->curOuterParams.
    4052             :      */
    4053       31470 :     outerrelids = best_path->outerjoinpath->parent->relids;
    4054       31470 :     nestParams = identify_current_nestloop_params(root, outerrelids);
    4055             : 
    4056       31470 :     join_plan = make_nestloop(tlist,
    4057             :                               joinclauses,
    4058             :                               otherclauses,
    4059             :                               nestParams,
    4060             :                               outer_plan,
    4061             :                               inner_plan,
    4062             :                               best_path->jointype,
    4063       31470 :                               best_path->inner_unique);
    4064             : 
    4065       31470 :     copy_generic_path_info(&join_plan->join.plan, &best_path->path);
    4066             : 
    4067       31470 :     return join_plan;
    4068             : }
    4069             : 
    4070             : static MergeJoin *
    4071        2106 : create_mergejoin_plan(PlannerInfo *root,
    4072             :                       MergePath *best_path)
    4073             : {
    4074             :     MergeJoin  *join_plan;
    4075             :     Plan       *outer_plan;
    4076             :     Plan       *inner_plan;
    4077        2106 :     List       *tlist = build_path_tlist(root, &best_path->jpath.path);
    4078             :     List       *joinclauses;
    4079             :     List       *otherclauses;
    4080             :     List       *mergeclauses;
    4081             :     List       *outerpathkeys;
    4082             :     List       *innerpathkeys;
    4083             :     int         nClauses;
    4084             :     Oid        *mergefamilies;
    4085             :     Oid        *mergecollations;
    4086             :     int        *mergestrategies;
    4087             :     bool       *mergenullsfirst;
    4088             :     PathKey    *opathkey;
    4089             :     EquivalenceClass *opeclass;
    4090             :     int         i;
    4091             :     ListCell   *lc;
    4092             :     ListCell   *lop;
    4093             :     ListCell   *lip;
    4094        2106 :     Path       *outer_path = best_path->jpath.outerjoinpath;
    4095        2106 :     Path       *inner_path = best_path->jpath.innerjoinpath;
    4096             : 
    4097             :     /*
    4098             :      * MergeJoin can project, so we don't have to demand exact tlists from the
    4099             :      * inputs.  However, if we're intending to sort an input's result, it's
    4100             :      * best to request a small tlist so we aren't sorting more data than
    4101             :      * necessary.
    4102             :      */
    4103        2106 :     outer_plan = create_plan_recurse(root, best_path->jpath.outerjoinpath,
    4104        2106 :                                      (best_path->outersortkeys != NIL) ? CP_SMALL_TLIST : 0);
    4105             : 
    4106        2106 :     inner_plan = create_plan_recurse(root, best_path->jpath.innerjoinpath,
    4107        2106 :                                      (best_path->innersortkeys != NIL) ? CP_SMALL_TLIST : 0);
    4108             : 
    4109             :     /* Sort join qual clauses into best execution order */
    4110             :     /* NB: do NOT reorder the mergeclauses */
    4111        2106 :     joinclauses = order_qual_clauses(root, best_path->jpath.joinrestrictinfo);
    4112             : 
    4113             :     /* Get the join qual clauses (in plain expression form) */
    4114             :     /* Any pseudoconstant clauses are ignored here */
    4115        2106 :     if (IS_OUTER_JOIN(best_path->jpath.jointype))
    4116             :     {
    4117        1248 :         extract_actual_join_clauses(joinclauses,
    4118        1248 :                                     best_path->jpath.path.parent->relids,
    4119             :                                     &joinclauses, &otherclauses);
    4120             :     }
    4121             :     else
    4122             :     {
    4123             :         /* We can treat all clauses alike for an inner join */
    4124         858 :         joinclauses = extract_actual_clauses(joinclauses, false);
    4125         858 :         otherclauses = NIL;
    4126             :     }
    4127             : 
    4128             :     /*
    4129             :      * Remove the mergeclauses from the list of join qual clauses, leaving the
    4130             :      * list of quals that must be checked as qpquals.
    4131             :      */
    4132        2106 :     mergeclauses = get_actual_clauses(best_path->path_mergeclauses);
    4133        2106 :     joinclauses = list_difference(joinclauses, mergeclauses);
    4134             : 
    4135             :     /*
    4136             :      * Replace any outer-relation variables with nestloop params.  There
    4137             :      * should not be any in the mergeclauses.
    4138             :      */
    4139        2106 :     if (best_path->jpath.path.param_info)
    4140             :     {
    4141           4 :         joinclauses = (List *)
    4142           4 :             replace_nestloop_params(root, (Node *) joinclauses);
    4143           4 :         otherclauses = (List *)
    4144           4 :             replace_nestloop_params(root, (Node *) otherclauses);
    4145             :     }
    4146             : 
    4147             :     /*
    4148             :      * Rearrange mergeclauses, if needed, so that the outer variable is always
    4149             :      * on the left; mark the mergeclause restrictinfos with correct
    4150             :      * outer_is_left status.
    4151             :      */
    4152        2106 :     mergeclauses = get_switched_clauses(best_path->path_mergeclauses,
    4153        2106 :                                         best_path->jpath.outerjoinpath->parent->relids);
    4154             : 
    4155             :     /*
    4156             :      * Create explicit sort nodes for the outer and inner paths if necessary.
    4157             :      */
    4158        2106 :     if (best_path->outersortkeys)
    4159             :     {
    4160        1206 :         Relids      outer_relids = outer_path->parent->relids;
    4161        1206 :         Sort       *sort = make_sort_from_pathkeys(outer_plan,
    4162             :                                                    best_path->outersortkeys,
    4163             :                                                    outer_relids);
    4164             : 
    4165        1206 :         label_sort_with_costsize(root, sort, -1.0);
    4166        1206 :         outer_plan = (Plan *) sort;
    4167        1206 :         outerpathkeys = best_path->outersortkeys;
    4168             :     }
    4169             :     else
    4170         900 :         outerpathkeys = best_path->jpath.outerjoinpath->pathkeys;
    4171             : 
    4172        2106 :     if (best_path->innersortkeys)
    4173             :     {
    4174        1780 :         Relids      inner_relids = inner_path->parent->relids;
    4175        1780 :         Sort       *sort = make_sort_from_pathkeys(inner_plan,
    4176             :                                                    best_path->innersortkeys,
    4177             :                                                    inner_relids);
    4178             : 
    4179        1780 :         label_sort_with_costsize(root, sort, -1.0);
    4180        1780 :         inner_plan = (Plan *) sort;
    4181        1780 :         innerpathkeys = best_path->innersortkeys;
    4182             :     }
    4183             :     else
    4184         326 :         innerpathkeys = best_path->jpath.innerjoinpath->pathkeys;
    4185             : 
    4186             :     /*
    4187             :      * If specified, add a materialize node to shield the inner plan from the
    4188             :      * need to handle mark/restore.
    4189             :      */
    4190        2106 :     if (best_path->materialize_inner)
    4191             :     {
    4192          78 :         Plan       *matplan = (Plan *) make_material(inner_plan);
    4193             : 
    4194             :         /*
    4195             :          * We assume the materialize will not spill to disk, and therefore
    4196             :          * charge just cpu_operator_cost per tuple.  (Keep this estimate in
    4197             :          * sync with final_cost_mergejoin.)
    4198             :          */
    4199          78 :         copy_plan_costsize(matplan, inner_plan);
    4200          78 :         matplan->total_cost += cpu_operator_cost * matplan->plan_rows;
    4201             : 
    4202          78 :         inner_plan = matplan;
    4203             :     }
    4204             : 
    4205             :     /*
    4206             :      * Compute the opfamily/collation/strategy/nullsfirst arrays needed by the
    4207             :      * executor.  The information is in the pathkeys for the two inputs, but
    4208             :      * we need to be careful about the possibility of mergeclauses sharing a
    4209             :      * pathkey, as well as the possibility that the inner pathkeys are not in
    4210             :      * an order matching the mergeclauses.
    4211             :      */
    4212        2106 :     nClauses = list_length(mergeclauses);
    4213             :     Assert(nClauses == list_length(best_path->path_mergeclauses));
    4214        2106 :     mergefamilies = (Oid *) palloc(nClauses * sizeof(Oid));
    4215        2106 :     mergecollations = (Oid *) palloc(nClauses * sizeof(Oid));
    4216        2106 :     mergestrategies = (int *) palloc(nClauses * sizeof(int));
    4217        2106 :     mergenullsfirst = (bool *) palloc(nClauses * sizeof(bool));
    4218             : 
    4219        2106 :     opathkey = NULL;
    4220        2106 :     opeclass = NULL;
    4221        2106 :     lop = list_head(outerpathkeys);
    4222        2106 :     lip = list_head(innerpathkeys);
    4223        2106 :     i = 0;
    4224        4378 :     foreach(lc, best_path->path_mergeclauses)
    4225             :     {
    4226        2272 :         RestrictInfo *rinfo = lfirst_node(RestrictInfo, lc);
    4227             :         EquivalenceClass *oeclass;
    4228             :         EquivalenceClass *ieclass;
    4229        2272 :         PathKey    *ipathkey = NULL;
    4230        2272 :         EquivalenceClass *ipeclass = NULL;
    4231        2272 :         bool        first_inner_match = false;
    4232             : 
    4233             :         /* fetch outer/inner eclass from mergeclause */
    4234        2272 :         if (rinfo->outer_is_left)
    4235             :         {
    4236        1594 :             oeclass = rinfo->left_ec;
    4237        1594 :             ieclass = rinfo->right_ec;
    4238             :         }
    4239             :         else
    4240             :         {
    4241         678 :             oeclass = rinfo->right_ec;
    4242         678 :             ieclass = rinfo->left_ec;
    4243             :         }
    4244             :         Assert(oeclass != NULL);
    4245             :         Assert(ieclass != NULL);
    4246             : 
    4247             :         /*
    4248             :          * We must identify the pathkey elements associated with this clause
    4249             :          * by matching the eclasses (which should give a unique match, since
    4250             :          * the pathkey lists should be canonical).  In typical cases the merge
    4251             :          * clauses are one-to-one with the pathkeys, but when dealing with
    4252             :          * partially redundant query conditions, things are more complicated.
    4253             :          *
    4254             :          * lop and lip reference the first as-yet-unmatched pathkey elements.
    4255             :          * If they're NULL then all pathkey elements have been matched.
    4256             :          *
    4257             :          * The ordering of the outer pathkeys should match the mergeclauses,
    4258             :          * by construction (see find_mergeclauses_for_outer_pathkeys()). There
    4259             :          * could be more than one mergeclause for the same outer pathkey, but
    4260             :          * no pathkey may be entirely skipped over.
    4261             :          */
    4262        2272 :         if (oeclass != opeclass)    /* multiple matches are not interesting */
    4263             :         {
    4264             :             /* doesn't match the current opathkey, so must match the next */
    4265        2264 :             if (lop == NULL)
    4266           0 :                 elog(ERROR, "outer pathkeys do not match mergeclauses");
    4267        2264 :             opathkey = (PathKey *) lfirst(lop);
    4268        2264 :             opeclass = opathkey->pk_eclass;
    4269        2264 :             lop = lnext(outerpathkeys, lop);
    4270        2264 :             if (oeclass != opeclass)
    4271           0 :                 elog(ERROR, "outer pathkeys do not match mergeclauses");
    4272             :         }
    4273             : 
    4274             :         /*
    4275             :          * The inner pathkeys likewise should not have skipped-over keys, but
    4276             :          * it's possible for a mergeclause to reference some earlier inner
    4277             :          * pathkey if we had redundant pathkeys.  For example we might have
    4278             :          * mergeclauses like "o.a = i.x AND o.b = i.y AND o.c = i.x".  The
    4279             :          * implied inner ordering is then "ORDER BY x, y, x", but the pathkey
    4280             :          * mechanism drops the second sort by x as redundant, and this code
    4281             :          * must cope.
    4282             :          *
    4283             :          * It's also possible for the implied inner-rel ordering to be like
    4284             :          * "ORDER BY x, y, x DESC".  We still drop the second instance of x as
    4285             :          * redundant; but this means that the sort ordering of a redundant
    4286             :          * inner pathkey should not be considered significant.  So we must
    4287             :          * detect whether this is the first clause matching an inner pathkey.
    4288             :          */
    4289        2272 :         if (lip)
    4290             :         {
    4291        2260 :             ipathkey = (PathKey *) lfirst(lip);
    4292        2260 :             ipeclass = ipathkey->pk_eclass;
    4293        2260 :             if (ieclass == ipeclass)
    4294             :             {
    4295             :                 /* successful first match to this inner pathkey */
    4296        2260 :                 lip = lnext(innerpathkeys, lip);
    4297        2260 :                 first_inner_match = true;
    4298             :             }
    4299             :         }
    4300        2272 :         if (!first_inner_match)
    4301             :         {
    4302             :             /* redundant clause ... must match something before lip */
    4303             :             ListCell   *l2;
    4304             : 
    4305          12 :             foreach(l2, innerpathkeys)
    4306             :             {
    4307          12 :                 if (l2 == lip)
    4308           0 :                     break;
    4309          12 :                 ipathkey = (PathKey *) lfirst(l2);
    4310          12 :                 ipeclass = ipathkey->pk_eclass;
    4311          12 :                 if (ieclass == ipeclass)
    4312          12 :                     break;
    4313             :             }
    4314          12 :             if (ieclass != ipeclass)
    4315           0 :                 elog(ERROR, "inner pathkeys do not match mergeclauses");
    4316             :         }
    4317             : 
    4318             :         /*
    4319             :          * The pathkeys should always match each other as to opfamily and
    4320             :          * collation (which affect equality), but if we're considering a
    4321             :          * redundant inner pathkey, its sort ordering might not match.  In
    4322             :          * such cases we may ignore the inner pathkey's sort ordering and use
    4323             :          * the outer's.  (In effect, we're lying to the executor about the
    4324             :          * sort direction of this inner column, but it does not matter since
    4325             :          * the run-time row comparisons would only reach this column when
    4326             :          * there's equality for the earlier column containing the same eclass.
    4327             :          * There could be only one value in this column for the range of inner
    4328             :          * rows having a given value in the earlier column, so it does not
    4329             :          * matter which way we imagine this column to be ordered.)  But a
    4330             :          * non-redundant inner pathkey had better match outer's ordering too.
    4331             :          */
    4332        4544 :         if (opathkey->pk_opfamily != ipathkey->pk_opfamily ||
    4333        2272 :             opathkey->pk_eclass->ec_collation != ipathkey->pk_eclass->ec_collation)
    4334           0 :             elog(ERROR, "left and right pathkeys do not match in mergejoin");
    4335        4532 :         if (first_inner_match &&
    4336        4520 :             (opathkey->pk_strategy != ipathkey->pk_strategy ||
    4337        2260 :              opathkey->pk_nulls_first != ipathkey->pk_nulls_first))
    4338           0 :             elog(ERROR, "left and right pathkeys do not match in mergejoin");
    4339             : 
    4340             :         /* OK, save info for executor */
    4341        2272 :         mergefamilies[i] = opathkey->pk_opfamily;
    4342        2272 :         mergecollations[i] = opathkey->pk_eclass->ec_collation;
    4343        2272 :         mergestrategies[i] = opathkey->pk_strategy;
    4344        2272 :         mergenullsfirst[i] = opathkey->pk_nulls_first;
    4345        2272 :         i++;
    4346             :     }
    4347             : 
    4348             :     /*
    4349             :      * Note: it is not an error if we have additional pathkey elements (i.e.,
    4350             :      * lop or lip isn't NULL here).  The input paths might be better-sorted
    4351             :      * than we need for the current mergejoin.
    4352             :      */
    4353             : 
    4354             :     /*
    4355             :      * Now we can build the mergejoin node.
    4356             :      */
    4357        4212 :     join_plan = make_mergejoin(tlist,
    4358             :                                joinclauses,
    4359             :                                otherclauses,
    4360             :                                mergeclauses,
    4361             :                                mergefamilies,
    4362             :                                mergecollations,
    4363             :                                mergestrategies,
    4364             :                                mergenullsfirst,
    4365             :                                outer_plan,
    4366             :                                inner_plan,
    4367             :                                best_path->jpath.jointype,
    4368        2106 :                                best_path->jpath.inner_unique,
    4369        2106 :                                best_path->skip_mark_restore);
    4370             : 
    4371             :     /* Costs of sort and material steps are included in path cost already */
    4372        2106 :     copy_generic_path_info(&join_plan->join.plan, &best_path->jpath.path);
    4373             : 
    4374        2106 :     return join_plan;
    4375             : }
    4376             : 
    4377             : static HashJoin *
    4378       26632 : create_hashjoin_plan(PlannerInfo *root,
    4379             :                      HashPath *best_path)
    4380             : {
    4381             :     HashJoin   *join_plan;
    4382             :     Hash       *hash_plan;
    4383             :     Plan       *outer_plan;
    4384             :     Plan       *inner_plan;
    4385       26632 :     List       *tlist = build_path_tlist(root, &best_path->jpath.path);
    4386             :     List       *joinclauses;
    4387             :     List       *otherclauses;
    4388             :     List       *hashclauses;
    4389       26632 :     List       *hashoperators = NIL;
    4390       26632 :     List       *hashcollations = NIL;
    4391       26632 :     List       *inner_hashkeys = NIL;
    4392       26632 :     List       *outer_hashkeys = NIL;
    4393       26632 :     Oid         skewTable = InvalidOid;
    4394       26632 :     AttrNumber  skewColumn = InvalidAttrNumber;
    4395       26632 :     bool        skewInherit = false;
    4396             :     ListCell   *lc;
    4397             : 
    4398             :     /*
    4399             :      * HashJoin can project, so we don't have to demand exact tlists from the
    4400             :      * inputs.  However, it's best to request a small tlist from the inner
    4401             :      * side, so that we aren't storing more data than necessary.  Likewise, if
    4402             :      * we anticipate batching, request a small tlist from the outer side so
    4403             :      * that we don't put extra data in the outer batch files.
    4404             :      */
    4405       26632 :     outer_plan = create_plan_recurse(root, best_path->jpath.outerjoinpath,
    4406       26632 :                                      (best_path->num_batches > 1) ? CP_SMALL_TLIST : 0);
    4407             : 
    4408       26632 :     inner_plan = create_plan_recurse(root, best_path->jpath.innerjoinpath,
    4409             :                                      CP_SMALL_TLIST);
    4410             : 
    4411             :     /* Sort join qual clauses into best execution order */
    4412       26632 :     joinclauses = order_qual_clauses(root, best_path->jpath.joinrestrictinfo);
    4413             :     /* There's no point in sorting the hash clauses ... */
    4414             : 
    4415             :     /* Get the join qual clauses (in plain expression form) */
    4416             :     /* Any pseudoconstant clauses are ignored here */
    4417       26632 :     if (IS_OUTER_JOIN(best_path->jpath.jointype))
    4418             :     {
    4419       14312 :         extract_actual_join_clauses(joinclauses,
    4420       14312 :                                     best_path->jpath.path.parent->relids,
    4421             :                                     &joinclauses, &otherclauses);
    4422             :     }
    4423             :     else
    4424             :     {
    4425             :         /* We can treat all clauses alike for an inner join */
    4426       12320 :         joinclauses = extract_actual_clauses(joinclauses, false);
    4427       12320 :         otherclauses = NIL;
    4428             :     }
    4429             : 
    4430             :     /*
    4431             :      * Remove the hashclauses from the list of join qual clauses, leaving the
    4432             :      * list of quals that must be checked as qpquals.
    4433             :      */
    4434       26632 :     hashclauses = get_actual_clauses(best_path->path_hashclauses);
    4435       26632 :     joinclauses = list_difference(joinclauses, hashclauses);
    4436             : 
    4437             :     /*
    4438             :      * Replace any outer-relation variables with nestloop params.  There
    4439             :      * should not be any in the hashclauses.
    4440             :      */
    4441       26632 :     if (best_path->jpath.path.param_info)
    4442             :     {
    4443         132 :         joinclauses = (List *)
    4444         132 :             replace_nestloop_params(root, (Node *) joinclauses);
    4445         132 :         otherclauses = (List *)
    4446         132 :             replace_nestloop_params(root, (Node *) otherclauses);
    4447             :     }
    4448             : 
    4449             :     /*
    4450             :      * Rearrange hashclauses, if needed, so that the outer variable is always
    4451             :      * on the left.
    4452             :      */
    4453       26632 :     hashclauses = get_switched_clauses(best_path->path_hashclauses,
    4454       26632 :                                        best_path->jpath.outerjoinpath->parent->relids);
    4455             : 
    4456             :     /*
    4457             :      * If there is a single join clause and we can identify the outer variable
    4458             :      * as a simple column reference, supply its identity for possible use in
    4459             :      * skew optimization.  (Note: in principle we could do skew optimization
    4460             :      * with multiple join clauses, but we'd have to be able to determine the
    4461             :      * most common combinations of outer values, which we don't currently have
    4462             :      * enough stats for.)
    4463             :      */
    4464       26632 :     if (list_length(hashclauses) == 1)
    4465             :     {
    4466       25504 :         OpExpr     *clause = (OpExpr *) linitial(hashclauses);
    4467             :         Node       *node;
    4468             : 
    4469             :         Assert(is_opclause(clause));
    4470       25504 :         node = (Node *) linitial(clause->args);
    4471       25504 :         if (IsA(node, RelabelType))
    4472         632 :             node = (Node *) ((RelabelType *) node)->arg;
    4473       25504 :         if (IsA(node, Var))
    4474             :         {
    4475       25342 :             Var        *var = (Var *) node;
    4476             :             RangeTblEntry *rte;
    4477             : 
    4478       25342 :             rte = root->simple_rte_array[var->varno];
    4479       25342 :             if (rte->rtekind == RTE_RELATION)
    4480             :             {
    4481       18858 :                 skewTable = rte->relid;
    4482       18858 :                 skewColumn = var->varattno;
    4483       18858 :                 skewInherit = rte->inh;
    4484             :             }
    4485             :         }
    4486             :     }
    4487             : 
    4488             :     /*
    4489             :      * Collect hash related information. The hashed expressions are
    4490             :      * deconstructed into outer/inner expressions, so they can be computed
    4491             :      * separately (inner expressions are used to build the hashtable via Hash,
    4492             :      * outer expressions to perform lookups of tuples from HashJoin's outer
    4493             :      * plan in the hashtable). Also collect operator information necessary to
    4494             :      * build the hashtable.
    4495             :      */
    4496       54598 :     foreach(lc, hashclauses)
    4497             :     {
    4498       27966 :         OpExpr     *hclause = lfirst_node(OpExpr, lc);
    4499             : 
    4500       27966 :         hashoperators = lappend_oid(hashoperators, hclause->opno);
    4501       27966 :         hashcollations = lappend_oid(hashcollations, hclause->inputcollid);
    4502       27966 :         outer_hashkeys = lappend(outer_hashkeys, linitial(hclause->args));
    4503       27966 :         inner_hashkeys = lappend(inner_hashkeys, lsecond(hclause->args));
    4504             :     }
    4505             : 
    4506             :     /*
    4507             :      * Build the hash node and hash join node.
    4508             :      */
    4509       26632 :     hash_plan = make_hash(inner_plan,
    4510             :                           inner_hashkeys,
    4511             :                           skewTable,
    4512             :                           skewColumn,
    4513             :                           skewInherit);
    4514             : 
    4515             :     /*
    4516             :      * Set Hash node's startup & total costs equal to total cost of input
    4517             :      * plan; this only affects EXPLAIN display not decisions.
    4518             :      */
    4519       26632 :     copy_plan_costsize(&hash_plan->plan, inner_plan);
    4520       26632 :     hash_plan->plan.startup_cost = hash_plan->plan.total_cost;
    4521             : 
    4522             :     /*
    4523             :      * If parallel-aware, the executor will also need an estimate of the total
    4524             :      * number of rows expected from all participants so that it can size the
    4525             :      * shared hash table.
    4526             :      */
    4527       26632 :     if (best_path->jpath.path.parallel_aware)
    4528             :     {
    4529          92 :         hash_plan->plan.parallel_aware = true;
    4530          92 :         hash_plan->rows_total = best_path->inner_rows_total;
    4531             :     }
    4532             : 
    4533       26632 :     join_plan = make_hashjoin(tlist,
    4534             :                               joinclauses,
    4535             :                               otherclauses,
    4536             :                               hashclauses,
    4537             :                               hashoperators,
    4538             :                               hashcollations,
    4539             :                               outer_hashkeys,
    4540             :                               outer_plan,
    4541             :                               (Plan *) hash_plan,
    4542             :                               best_path->jpath.jointype,
    4543       26632 :                               best_path->jpath.inner_unique);
    4544             : 
    4545       26632 :     copy_generic_path_info(&join_plan->join.plan, &best_path->jpath.path);
    4546             : 
    4547       26632 :     return join_plan;
    4548             : }
    4549             : 
    4550             : 
    4551             : /*****************************************************************************
    4552             :  *
    4553             :  *  SUPPORTING ROUTINES
    4554             :  *
    4555             :  *****************************************************************************/
    4556             : 
    4557             : /*
    4558             :  * replace_nestloop_params
    4559             :  *    Replace outer-relation Vars and PlaceHolderVars in the given expression
    4560             :  *    with nestloop Params
    4561             :  *
    4562             :  * All Vars and PlaceHolderVars belonging to the relation(s) identified by
    4563             :  * root->curOuterRels are replaced by Params, and entries are added to
    4564             :  * root->curOuterParams if not already present.
    4565             :  */
    4566             : static Node *
    4567      177956 : replace_nestloop_params(PlannerInfo *root, Node *expr)
    4568             : {
    4569             :     /* No setup needed for tree walk, so away we go */
    4570      177956 :     return replace_nestloop_params_mutator(expr, root);
    4571             : }
    4572             : 
    4573             : static Node *
    4574      615698 : replace_nestloop_params_mutator(Node *node, PlannerInfo *root)
    4575             : {
    4576      615698 :     if (node == NULL)
    4577       33340 :         return NULL;
    4578      582358 :     if (IsA(node, Var))
    4579             :     {
    4580      184270 :         Var        *var = (Var *) node;
    4581             : 
    4582             :         /* Upper-level Vars should be long gone at this point */
    4583             :         Assert(var->varlevelsup == 0);
    4584             :         /* If not to be replaced, we can just return the Var unmodified */
    4585      184270 :         if (!bms_is_member(var->varno, root->curOuterRels))
    4586      147126 :             return node;
    4587             :         /* Replace the Var with a nestloop Param */
    4588       37144 :         return (Node *) replace_nestloop_param_var(root, var);
    4589             :     }
    4590      398088 :     if (IsA(node, PlaceHolderVar))
    4591             :     {
    4592         280 :         PlaceHolderVar *phv = (PlaceHolderVar *) node;
    4593             : 
    4594             :         /* Upper-level PlaceHolderVars should be long gone at this point */
    4595             :         Assert(phv->phlevelsup == 0);
    4596             : 
    4597             :         /*
    4598             :          * Check whether we need to replace the PHV.  We use bms_overlap as a
    4599             :          * cheap/quick test to see if the PHV might be evaluated in the outer
    4600             :          * rels, and then grab its PlaceHolderInfo to tell for sure.
    4601             :          */
    4602         420 :         if (!bms_overlap(phv->phrels, root->curOuterRels) ||
    4603         140 :             !bms_is_subset(find_placeholder_info(root, phv, false)->ph_eval_at,
    4604         140 :                            root->curOuterRels))
    4605             :         {
    4606             :             /*
    4607             :              * We can't replace the whole PHV, but we might still need to
    4608             :              * replace Vars or PHVs within its expression, in case it ends up
    4609             :              * actually getting evaluated here.  (It might get evaluated in
    4610             :              * this plan node, or some child node; in the latter case we don't
    4611             :              * really need to process the expression here, but we haven't got
    4612             :              * enough info to tell if that's the case.)  Flat-copy the PHV
    4613             :              * node and then recurse on its expression.
    4614             :              *
    4615             :              * Note that after doing this, we might have different
    4616             :              * representations of the contents of the same PHV in different
    4617             :              * parts of the plan tree.  This is OK because equal() will just
    4618             :              * match on phid/phlevelsup, so setrefs.c will still recognize an
    4619             :              * upper-level reference to a lower-level copy of the same PHV.
    4620             :              */
    4621         156 :             PlaceHolderVar *newphv = makeNode(PlaceHolderVar);
    4622             : 
    4623         156 :             memcpy(newphv, phv, sizeof(PlaceHolderVar));
    4624         156 :             newphv->phexpr = (Expr *)
    4625         156 :                 replace_nestloop_params_mutator((Node *) phv->phexpr,
    4626             :                                                 root);
    4627         156 :             return (Node *) newphv;
    4628             :         }
    4629             :         /* Replace the PlaceHolderVar with a nestloop Param */
    4630         124 :         return (Node *) replace_nestloop_param_placeholdervar(root, phv);
    4631             :     }
    4632      397808 :     return expression_tree_mutator(node,
    4633             :                                    replace_nestloop_params_mutator,
    4634             :                                    (void *) root);
    4635             : }
    4636             : 
    4637             : /*
    4638             :  * fix_indexqual_references
    4639             :  *    Adjust indexqual clauses to the form the executor's indexqual
    4640             :  *    machinery needs.
    4641             :  *
    4642             :  * We have three tasks here:
    4643             :  *  * Select the actual qual clauses out of the input IndexClause list,
    4644             :  *    and remove RestrictInfo nodes from the qual clauses.
    4645             :  *  * Replace any outer-relation Var or PHV nodes with nestloop Params.
    4646             :  *    (XXX eventually, that responsibility should go elsewhere?)
    4647             :  *  * Index keys must be represented by Var nodes with varattno set to the
    4648             :  *    index's attribute number, not the attribute number in the original rel.
    4649             :  *
    4650             :  * *stripped_indexquals_p receives a list of the actual qual clauses.
    4651             :  *
    4652             :  * *fixed_indexquals_p receives a list of the adjusted quals.  This is a copy
    4653             :  * that shares no substructure with the original; this is needed in case there
    4654             :  * are subplans in it (we need two separate copies of the subplan tree, or
    4655             :  * things will go awry).
    4656             :  */
    4657             : static void
    4658      100300 : fix_indexqual_references(PlannerInfo *root, IndexPath *index_path,
    4659             :                          List **stripped_indexquals_p, List **fixed_indexquals_p)
    4660             : {
    4661      100300 :     IndexOptInfo *index = index_path->indexinfo;
    4662             :     List       *stripped_indexquals;
    4663             :     List       *fixed_indexquals;
    4664             :     ListCell   *lc;
    4665             : 
    4666      100300 :     stripped_indexquals = fixed_indexquals = NIL;
    4667             : 
    4668      211732 :     foreach(lc, index_path->indexclauses)
    4669             :     {
    4670      111432 :         IndexClause *iclause = lfirst_node(IndexClause, lc);
    4671      111432 :         int         indexcol = iclause->indexcol;
    4672             :         ListCell   *lc2;
    4673             : 
    4674      223394 :         foreach(lc2, iclause->indexquals)
    4675             :         {
    4676      111962 :             RestrictInfo *rinfo = lfirst_node(RestrictInfo, lc2);
    4677      111962 :             Node       *clause = (Node *) rinfo->clause;
    4678             : 
    4679      111962 :             stripped_indexquals = lappend(stripped_indexquals, clause);
    4680      111962 :             clause = fix_indexqual_clause(root, index, indexcol,
    4681             :                                           clause, iclause->indexcols);
    4682      111962 :             fixed_indexquals = lappend(fixed_indexquals, clause);
    4683             :         }
    4684             :     }
    4685             : 
    4686      100300 :     *stripped_indexquals_p = stripped_indexquals;
    4687      100300 :     *fixed_indexquals_p = fixed_indexquals;
    4688      100300 : }
    4689             : 
    4690             : /*
    4691             :  * fix_indexorderby_references
    4692             :  *    Adjust indexorderby clauses to the form the executor's index
    4693             :  *    machinery needs.
    4694             :  *
    4695             :  * This is a simplified version of fix_indexqual_references.  The input is
    4696             :  * bare clauses and a separate indexcol list, instead of IndexClauses.
    4697             :  */
    4698             : static List *
    4699      100300 : fix_indexorderby_references(PlannerInfo *root, IndexPath *index_path)
    4700             : {
    4701      100300 :     IndexOptInfo *index = index_path->indexinfo;
    4702             :     List       *fixed_indexorderbys;
    4703             :     ListCell   *lcc,
    4704             :                *lci;
    4705             : 
    4706      100300 :     fixed_indexorderbys = NIL;
    4707             : 
    4708      100550 :     forboth(lcc, index_path->indexorderbys, lci, index_path->indexorderbycols)
    4709             :     {
    4710         250 :         Node       *clause = (Node *) lfirst(lcc);
    4711         250 :         int         indexcol = lfirst_int(lci);
    4712             : 
    4713         250 :         clause = fix_indexqual_clause(root, index, indexcol, clause, NIL);
    4714         250 :         fixed_indexorderbys = lappend(fixed_indexorderbys, clause);
    4715             :     }
    4716             : 
    4717      100300 :     return fixed_indexorderbys;
    4718             : }
    4719             : 
    4720             : /*
    4721             :  * fix_indexqual_clause
    4722             :  *    Convert a single indexqual clause to the form needed by the executor.
    4723             :  *
    4724             :  * We replace nestloop params here, and replace the index key variables
    4725             :  * or expressions by index Var nodes.
    4726             :  */
    4727             : static Node *
    4728      112212 : fix_indexqual_clause(PlannerInfo *root, IndexOptInfo *index, int indexcol,
    4729             :                      Node *clause, List *indexcolnos)
    4730             : {
    4731             :     /*
    4732             :      * Replace any outer-relation variables with nestloop params.
    4733             :      *
    4734             :      * This also makes a copy of the clause, so it's safe to modify it
    4735             :      * in-place below.
    4736             :      */
    4737      112212 :     clause = replace_nestloop_params(root, clause);
    4738             : 
    4739      112212 :     if (IsA(clause, OpExpr))
    4740             :     {
    4741      111188 :         OpExpr     *op = (OpExpr *) clause;
    4742             : 
    4743             :         /* Replace the indexkey expression with an index Var. */
    4744      111188 :         linitial(op->args) = fix_indexqual_operand(linitial(op->args),
    4745             :                                                    index,
    4746             :                                                    indexcol);
    4747             :     }
    4748        1024 :     else if (IsA(clause, RowCompareExpr))
    4749             :     {
    4750          48 :         RowCompareExpr *rc = (RowCompareExpr *) clause;
    4751             :         ListCell   *lca,
    4752             :                    *lcai;
    4753             : 
    4754             :         /* Replace the indexkey expressions with index Vars. */
    4755             :         Assert(list_length(rc->largs) == list_length(indexcolnos));
    4756         144 :         forboth(lca, rc->largs, lcai, indexcolnos)
    4757             :         {
    4758          96 :             lfirst(lca) = fix_indexqual_operand(lfirst(lca),
    4759             :                                                 index,
    4760             :                                                 lfirst_int(lcai));
    4761             :         }
    4762             :     }
    4763         976 :     else if (IsA(clause, ScalarArrayOpExpr))
    4764             :     {
    4765         254 :         ScalarArrayOpExpr *saop = (ScalarArrayOpExpr *) clause;
    4766             : 
    4767             :         /* Replace the indexkey expression with an index Var. */
    4768         254 :         linitial(saop->args) = fix_indexqual_operand(linitial(saop->args),
    4769             :                                                      index,
    4770             :                                                      indexcol);
    4771             :     }
    4772         722 :     else if (IsA(clause, NullTest))
    4773             :     {
    4774         722 :         NullTest   *nt = (NullTest *) clause;
    4775             : 
    4776             :         /* Replace the indexkey expression with an index Var. */
    4777         722 :         nt->arg = (Expr *) fix_indexqual_operand((Node *) nt->arg,
    4778             :                                                  index,
    4779             :                                                  indexcol);
    4780             :     }
    4781             :     else
    4782           0 :         elog(ERROR, "unsupported indexqual type: %d",
    4783             :              (int) nodeTag(clause));
    4784             : 
    4785      112212 :     return clause;
    4786             : }
    4787             : 
    4788             : /*
    4789             :  * fix_indexqual_operand
    4790             :  *    Convert an indexqual expression to a Var referencing the index column.
    4791             :  *
    4792             :  * We represent index keys by Var nodes having varno == INDEX_VAR and varattno
    4793             :  * equal to the index's attribute number (index column position).
    4794             :  *
    4795             :  * Most of the code here is just for sanity cross-checking that the given
    4796             :  * expression actually matches the index column it's claimed to.
    4797             :  */
    4798             : static Node *
    4799      112260 : fix_indexqual_operand(Node *node, IndexOptInfo *index, int indexcol)
    4800             : {
    4801             :     Var        *result;
    4802             :     int         pos;
    4803             :     ListCell   *indexpr_item;
    4804             : 
    4805             :     /*
    4806             :      * Remove any binary-compatible relabeling of the indexkey
    4807             :      */
    4808      112260 :     if (IsA(node, RelabelType))
    4809         736 :         node = (Node *) ((RelabelType *) node)->arg;
    4810             : 
    4811             :     Assert(indexcol >= 0 && indexcol < index->ncolumns);
    4812             : 
    4813      112260 :     if (index->indexkeys[indexcol] != 0)
    4814             :     {
    4815             :         /* It's a simple index column */
    4816      224092 :         if (IsA(node, Var) &&
    4817      224092 :             ((Var *) node)->varno == index->rel->relid &&
    4818      112046 :             ((Var *) node)->varattno == index->indexkeys[indexcol])
    4819             :         {
    4820      112046 :             result = (Var *) copyObject(node);
    4821      112046 :             result->varno = INDEX_VAR;
    4822      112046 :             result->varattno = indexcol + 1;
    4823      112046 :             return (Node *) result;
    4824             :         }
    4825             :         else
    4826           0 :             elog(ERROR, "index key does not match expected index column");
    4827             :     }
    4828             : 
    4829             :     /* It's an index expression, so find and cross-check the expression */
    4830         214 :     indexpr_item = list_head(index->indexprs);
    4831         214 :     for (pos = 0; pos < index->ncolumns; pos++)
    4832             :     {
    4833         214 :         if (index->indexkeys[pos] == 0)
    4834             :         {
    4835         214 :             if (indexpr_item == NULL)
    4836           0 :                 elog(ERROR, "too few entries in indexprs list");
    4837         214 :             if (pos == indexcol)
    4838             :             {
    4839             :                 Node       *indexkey;
    4840             : 
    4841         214 :                 indexkey = (Node *) lfirst(indexpr_item);
    4842         214 :                 if (indexkey && IsA(indexkey, RelabelType))
    4843          10 :                     indexkey = (Node *) ((RelabelType *) indexkey)->arg;
    4844         214 :                 if (equal(node, indexkey))
    4845             :                 {
    4846         428 :                     result = makeVar(INDEX_VAR, indexcol + 1,
    4847         214 :                                      exprType(lfirst(indexpr_item)), -1,
    4848         214 :                                      exprCollation(lfirst(indexpr_item)),
    4849             :                                      0);
    4850         214 :                     return (Node *) result;
    4851             :                 }
    4852             :                 else
    4853           0 :                     elog(ERROR, "index key does not match expected index column");
    4854             :             }
    4855           0 :             indexpr_item = lnext(index->indexprs, indexpr_item);
    4856             :         }
    4857             :     }
    4858             : 
    4859             :     /* Oops... */
    4860           0 :     elog(ERROR, "index key does not match expected index column");
    4861             :     return NULL;                /* keep compiler quiet */
    4862             : }
    4863             : 
    4864             : /*
    4865             :  * get_switched_clauses
    4866             :  *    Given a list of merge or hash joinclauses (as RestrictInfo nodes),
    4867             :  *    extract the bare clauses, and rearrange the elements within the
    4868             :  *    clauses, if needed, so the outer join variable is on the left and
    4869             :  *    the inner is on the right.  The original clause data structure is not
    4870             :  *    touched; a modified list is returned.  We do, however, set the transient
    4871             :  *    outer_is_left field in each RestrictInfo to show which side was which.
    4872             :  */
    4873             : static List *
    4874       28738 : get_switched_clauses(List *clauses, Relids outerrelids)
    4875             : {
    4876       28738 :     List       *t_list = NIL;
    4877             :     ListCell   *l;
    4878             : 
    4879       58976 :     foreach(l, clauses)
    4880             :     {
    4881       30238 :         RestrictInfo *restrictinfo = (RestrictInfo *) lfirst(l);
    4882       30238 :         OpExpr     *clause = (OpExpr *) restrictinfo->clause;
    4883             : 
    4884             :         Assert(is_opclause(clause));
    4885       30238 :         if (bms_is_subset(restrictinfo->right_relids, outerrelids))
    4886             :         {
    4887             :             /*
    4888             :              * Duplicate just enough of the structure to allow commuting the
    4889             :              * clause without changing the original list.  Could use
    4890             :              * copyObject, but a complete deep copy is overkill.
    4891             :              */
    4892       11868 :             OpExpr     *temp = makeNode(OpExpr);
    4893             : 
    4894       11868 :             temp->opno = clause->opno;
    4895       11868 :             temp->opfuncid = InvalidOid;
    4896       11868 :             temp->opresulttype = clause->opresulttype;
    4897       11868 :             temp->opretset = clause->opretset;
    4898       11868 :             temp->opcollid = clause->opcollid;
    4899       11868 :             temp->inputcollid = clause->inputcollid;
    4900       11868 :             temp->args = list_copy(clause->args);
    4901       11868 :             temp->location = clause->location;
    4902             :             /* Commute it --- note this modifies the temp node in-place. */
    4903       11868 :             CommuteOpExpr(temp);
    4904       11868 :             t_list = lappend(t_list, temp);
    4905       11868 :             restrictinfo->outer_is_left = false;
    4906             :         }
    4907             :         else
    4908             :         {
    4909             :             Assert(bms_is_subset(restrictinfo->left_relids, outerrelids));
    4910       18370 :             t_list = lappend(t_list, clause);
    4911       18370 :             restrictinfo->outer_is_left = true;
    4912             :         }
    4913             :     }
    4914       28738 :     return t_list;
    4915             : }
    4916             : 
    4917             : /*
    4918             :  * order_qual_clauses
    4919             :  *      Given a list of qual clauses that will all be evaluated at the same
    4920             :  *      plan node, sort the list into the order we want to check the quals
    4921             :  *      in at runtime.
    4922             :  *
    4923             :  * When security barrier quals are used in the query, we may have quals with
    4924             :  * different security levels in the list.  Quals of lower security_level
    4925             :  * must go before quals of higher security_level, except that we can grant
    4926             :  * exceptions to move up quals that are leakproof.  When security level
    4927             :  * doesn't force the decision, we prefer to order clauses by estimated
    4928             :  * execution cost, cheapest first.
    4929             :  *
    4930             :  * Ideally the order should be driven by a combination of execution cost and
    4931             :  * selectivity, but it's not immediately clear how to account for both,
    4932             :  * and given the uncertainty of the estimates the reliability of the decisions
    4933             :  * would be doubtful anyway.  So we just order by security level then
    4934             :  * estimated per-tuple cost, being careful not to change the order when
    4935             :  * (as is often the case) the estimates are identical.
    4936             :  *
    4937             :  * Although this will work on either bare clauses or RestrictInfos, it's
    4938             :  * much faster to apply it to RestrictInfos, since it can re-use cost
    4939             :  * information that is cached in RestrictInfos.  XXX in the bare-clause
    4940             :  * case, we are also not able to apply security considerations.  That is
    4941             :  * all right for the moment, because the bare-clause case doesn't occur
    4942             :  * anywhere that barrier quals could be present, but it would be better to
    4943             :  * get rid of it.
    4944             :  *
    4945             :  * Note: some callers pass lists that contain entries that will later be
    4946             :  * removed; this is the easiest way to let this routine see RestrictInfos
    4947             :  * instead of bare clauses.  This is another reason why trying to consider
    4948             :  * selectivity in the ordering would likely do the wrong thing.
    4949             :  */
    4950             : static List *
    4951      479408 : order_qual_clauses(PlannerInfo *root, List *clauses)
    4952             : {
    4953             :     typedef struct
    4954             :     {
    4955             :         Node       *clause;
    4956             :         Cost        cost;
    4957             :         Index       security_level;
    4958             :     } QualItem;
    4959      479408 :     int         nitems = list_length(clauses);
    4960             :     QualItem   *items;
    4961             :     ListCell   *lc;
    4962             :     int         i;
    4963             :     List       *result;
    4964             : 
    4965             :     /* No need to work hard for 0 or 1 clause */
    4966      479408 :     if (nitems <= 1)
    4967      453534 :         return clauses;
    4968             : 
    4969             :     /*
    4970             :      * Collect the items and costs into an array.  This is to avoid repeated
    4971             :      * cost_qual_eval work if the inputs aren't RestrictInfos.
    4972             :      */
    4973       25874 :     items = (QualItem *) palloc(nitems * sizeof(QualItem));
    4974       25874 :     i = 0;
    4975       83824 :     foreach(lc, clauses)
    4976             :     {
    4977       57950 :         Node       *clause = (Node *) lfirst(lc);
    4978             :         QualCost    qcost;
    4979             : 
    4980       57950 :         cost_qual_eval_node(&qcost, clause, root);
    4981       57950 :         items[i].clause = clause;
    4982       57950 :         items[i].cost = qcost.per_tuple;
    4983       57950 :         if (IsA(clause, RestrictInfo))
    4984             :         {
    4985       57882 :             RestrictInfo *rinfo = (RestrictInfo *) clause;
    4986             : 
    4987             :             /*
    4988             :              * If a clause is leakproof, it doesn't have to be constrained by
    4989             :              * its nominal security level.  If it's also reasonably cheap
    4990             :              * (here defined as 10X cpu_operator_cost), pretend it has
    4991             :              * security_level 0, which will allow it to go in front of
    4992             :              * more-expensive quals of lower security levels.  Of course, that
    4993             :              * will also force it to go in front of cheaper quals of its own
    4994             :              * security level, which is not so great, but we can alleviate
    4995             :              * that risk by applying the cost limit cutoff.
    4996             :              */
    4997       57882 :             if (rinfo->leakproof && items[i].cost < 10 * cpu_operator_cost)
    4998         620 :                 items[i].security_level = 0;
    4999             :             else
    5000       57262 :                 items[i].security_level = rinfo->security_level;
    5001             :         }
    5002             :         else
    5003          68 :             items[i].security_level = 0;
    5004       57950 :         i++;
    5005             :     }
    5006             : 
    5007             :     /*
    5008             :      * Sort.  We don't use qsort() because it's not guaranteed stable for
    5009             :      * equal keys.  The expected number of entries is small enough that a
    5010             :      * simple insertion sort should be good enough.
    5011             :      */
    5012       57950 :     for (i = 1; i < nitems; i++)
    5013             :     {
    5014       32076 :         QualItem    newitem = items[i];
    5015             :         int         j;
    5016             : 
    5017             :         /* insert newitem into the already-sorted subarray */
    5018       38912 :         for (j = i; j > 0; j--)
    5019             :         {
    5020       34050 :             QualItem   *olditem = &items[j - 1];
    5021             : 
    5022       67744 :             if (newitem.security_level > olditem->security_level ||
    5023       66356 :                 (newitem.security_level == olditem->security_level &&
    5024       32662 :                  newitem.cost >= olditem->cost))
    5025             :                 break;
    5026        6836 :             items[j] = *olditem;
    5027             :         }
    5028       32076 :         items[j] = newitem;
    5029             :     }
    5030             : 
    5031             :     /* Convert back to a list */
    5032       25874 :     result = NIL;
    5033       83824 :     for (i = 0; i < nitems; i++)
    5034       57950 :         result = lappend(result, items[i].clause);
    5035             : 
    5036       25874 :     return result;
    5037             : }
    5038             : 
    5039             : /*
    5040             :  * Copy cost and size info from a Path node to the Plan node created from it.
    5041             :  * The executor usually won't use this info, but it's needed by EXPLAIN.
    5042             :  * Also copy the parallel-related flags, which the executor *will* use.
    5043             :  */
    5044             : static void
    5045      602846 : copy_generic_path_info(Plan *dest, Path *src)
    5046             : {
    5047      602846 :     dest->startup_cost = src->startup_cost;
    5048      602846 :     dest->total_cost = src->total_cost;
    5049      602846 :     dest->plan_rows = src->rows;
    5050      602846 :     dest->plan_width = src->pathtarget->width;
    5051      602846 :     dest->parallel_aware = src->parallel_aware;
    5052      602846 :     dest->parallel_safe = src->parallel_safe;
    5053      602846 : }
    5054             : 
    5055             : /*
    5056             :  * Copy cost and size info from a lower plan node to an inserted node.
    5057             :  * (Most callers alter the info after copying it.)
    5058             :  */
    5059             : static void
    5060       29262 : copy_plan_costsize(Plan *dest, Plan *src)
    5061             : {
    5062       29262 :     dest->startup_cost = src->startup_cost;
    5063       29262 :     dest->total_cost = src->total_cost;
    5064       29262 :     dest->plan_rows = src->plan_rows;
    5065       29262 :     dest->plan_width = src->plan_width;
    5066             :     /* Assume the inserted node is not parallel-aware. */
    5067       29262 :     dest->parallel_aware = false;
    5068             :     /* Assume the inserted node is parallel-safe, if child plan is. */
    5069       29262 :     dest->parallel_safe = src->parallel_safe;
    5070       29262 : }
    5071             : 
    5072             : /*
    5073             :  * Some places in this file build Sort nodes that don't have a directly
    5074             :  * corresponding Path node.  The cost of the sort is, or should have been,
    5075             :  * included in the cost of the Path node we're working from, but since it's
    5076             :  * not split out, we have to re-figure it using cost_sort().  This is just
    5077             :  * to label the Sort node nicely for EXPLAIN.
    5078             :  *
    5079             :  * limit_tuples is as for cost_sort (in particular, pass -1 if no limit)
    5080             :  */
    5081             : static void
    5082        3032 : label_sort_with_costsize(PlannerInfo *root, Sort *plan, double limit_tuples)
    5083             : {
    5084        3032 :     Plan       *lefttree = plan->plan.lefttree;
    5085             :     Path        sort_path;      /* dummy for result of cost_sort */
    5086             : 
    5087        3032 :     cost_sort(&sort_path, root, NIL,
    5088             :               lefttree->total_cost,
    5089             :               lefttree->plan_rows,
    5090             :               lefttree->plan_width,
    5091             :               0.0,
    5092             :               work_mem,
    5093             :               limit_tuples);
    5094        3032 :     plan->plan.startup_cost = sort_path.startup_cost;
    5095        3032 :     plan->plan.total_cost = sort_path.total_cost;
    5096        3032 :     plan->plan.plan_rows = lefttree->plan_rows;
    5097        3032 :     plan->plan.plan_width = lefttree->plan_width;
    5098        3032 :     plan->plan.parallel_aware = false;
    5099        3032 :     plan->plan.parallel_safe = lefttree->parallel_safe;
    5100        3032 : }
    5101             : 
    5102             : /*
    5103             :  * bitmap_subplan_mark_shared
    5104             :  *   Set isshared flag in bitmap subplan so that it will be created in
    5105             :  *   shared memory.
    5106             :  */
    5107             : static void
    5108          12 : bitmap_subplan_mark_shared(Plan *plan)
    5109             : {
    5110          12 :     if (IsA(plan, BitmapAnd))
    5111           0 :         bitmap_subplan_mark_shared(
    5112           0 :                                    linitial(((BitmapAnd *) plan)->bitmapplans));
    5113          12 :     else if (IsA(plan, BitmapOr))
    5114             :     {
    5115           0 :         ((BitmapOr *) plan)->isshared = true;
    5116           0 :         bitmap_subplan_mark_shared(
    5117           0 :                                    linitial(((BitmapOr *) plan)->bitmapplans));
    5118             :     }
    5119          12 :     else if (IsA(plan, BitmapIndexScan))
    5120          12 :         ((BitmapIndexScan *) plan)->isshared = true;
    5121             :     else
    5122           0 :         elog(ERROR, "unrecognized node type: %d", nodeTag(plan));
    5123          12 : }
    5124             : 
    5125             : /*****************************************************************************
    5126             :  *
    5127             :  *  PLAN NODE BUILDING ROUTINES
    5128             :  *
    5129             :  * In general, these functions are not passed the original Path and therefore
    5130             :  * leave it to the caller to fill in the cost/width fields from the Path,
    5131             :  * typically by calling copy_generic_path_info().  This convention is
    5132             :  * somewhat historical, but it does support a few places above where we build
    5133             :  * a plan node without having an exactly corresponding Path node.  Under no
    5134             :  * circumstances should one of these functions do its own cost calculations,
    5135             :  * as that would be redundant with calculations done while building Paths.
    5136             :  *
    5137             :  *****************************************************************************/
    5138             : 
    5139             : static SeqScan *
    5140      114992 : make_seqscan(List *qptlist,
    5141             :              List *qpqual,
    5142             :              Index scanrelid)
    5143             : {
    5144      114992 :     SeqScan    *node = makeNode(SeqScan);
    5145      114992 :     Plan       *plan = &node->plan;
    5146             : 
    5147      114992 :     plan->targetlist = qptlist;
    5148      114992 :     plan->qual = qpqual;
    5149      114992 :     plan->lefttree = NULL;
    5150      114992 :     plan->righttree = NULL;
    5151      114992 :     node->scanrelid = scanrelid;
    5152             : 
    5153      114992 :     return node;
    5154             : }
    5155             : 
    5156             : static SampleScan *
    5157         180 : make_samplescan(List *qptlist,
    5158             :                 List *qpqual,
    5159             :                 Index scanrelid,
    5160             :                 TableSampleClause *tsc)
    5161             : {
    5162         180 :     SampleScan *node = makeNode(SampleScan);
    5163         180 :     Plan       *plan = &node->scan.plan;
    5164             : 
    5165         180 :     plan->targetlist = qptlist;
    5166         180 :     plan->qual = qpqual;
    5167         180 :     plan->lefttree = NULL;
    5168         180 :     plan->righttree = NULL;
    5169         180 :     node->scan.scanrelid = scanrelid;
    5170         180 :     node->tablesample = tsc;
    5171             : 
    5172         180 :     return node;
    5173             : }
    5174             : 
    5175             : static IndexScan *
    5176       92254 : make_indexscan(List *qptlist,
    5177             :                List *qpqual,
    5178             :                Index scanrelid,
    5179             :                Oid indexid,
    5180             :                List *indexqual,
    5181             :                List *indexqualorig,
    5182             :                List *indexorderby,
    5183             :                List *indexorderbyorig,
    5184             :                List *indexorderbyops,
    5185             :                ScanDirection indexscandir)
    5186             : {
    5187       92254 :     IndexScan  *node = makeNode(IndexScan);
    5188       92254 :     Plan       *plan = &node->scan.plan;
    5189             : 
    5190       92254 :     plan->targetlist = qptlist;
    5191       92254 :     plan->qual = qpqual;
    5192       92254 :     plan->lefttree = NULL;
    5193       92254 :     plan->righttree = NULL;
    5194       92254 :     node->scan.scanrelid = scanrelid;
    5195       92254 :     node->indexid = indexid;
    5196       92254 :     node->indexqual = indexqual;
    5197       92254 :     node->indexqualorig = indexqualorig;
    5198       92254 :     node->indexorderby = indexorderby;
    5199       92254 :     node->indexorderbyorig = indexorderbyorig;
    5200       92254 :     node->indexorderbyops = indexorderbyops;
    5201       92254 :     node->indexorderdir = indexscandir;
    5202             : 
    5203       92254 :     return node;
    5204             : }
    5205             : 
    5206             : static IndexOnlyScan *
    5207        8046 : make_indexonlyscan(List *qptlist,
    5208             :                    List *qpqual,
    5209             :                    Index scanrelid,
    5210             :                    Oid indexid,
    5211             :                    List *indexqual,
    5212             :                    List *indexorderby,
    5213             :                    List *indextlist,
    5214             :                    ScanDirection indexscandir)
    5215             : {
    5216        8046 :     IndexOnlyScan *node = makeNode(IndexOnlyScan);
    5217        8046 :     Plan       *plan = &node->scan.plan;
    5218             : 
    5219        8046 :     plan->targetlist = qptlist;
    5220        8046 :     plan->qual = qpqual;
    5221        8046 :     plan->lefttree = NULL;
    5222        8046 :     plan->righttree = NULL;
    5223        8046 :     node->scan.scanrelid = scanrelid;
    5224        8046 :     node->indexid = indexid;
    5225        8046 :     node->indexqual = indexqual;
    5226        8046 :     node->indexorderby = indexorderby;
    5227        8046 :     node->indextlist = indextlist;
    5228        8046 :     node->indexorderdir = indexscandir;
    5229             : 
    5230        8046 :     return node;
    5231             : }
    5232             : 
    5233             : static BitmapIndexScan *
    5234       19482 : make_bitmap_indexscan(Index scanrelid,
    5235             :                       Oid indexid,
    5236             :                       List *indexqual,
    5237             :                       List *indexqualorig)
    5238             : {
    5239       19482 :     BitmapIndexScan *node = makeNode(BitmapIndexScan);
    5240       19482 :     Plan       *plan = &node->scan.plan;
    5241             : 
    5242       19482 :     plan->targetlist = NIL;      /* not used */
    5243       19482 :     plan->qual = NIL;            /* not used */
    5244       19482 :     plan->lefttree = NULL;
    5245       19482 :     plan->righttree = NULL;
    5246       19482 :     node->scan.scanrelid = scanrelid;
    5247       19482 :     node->indexid = indexid;
    5248       19482 :     node->indexqual = indexqual;
    5249       19482 :     node->indexqualorig = indexqualorig;
    5250             : 
    5251       19482 :     return node;
    5252             : }
    5253             : 
    5254             : static BitmapHeapScan *
    5255       19314 : make_bitmap_heapscan(List *qptlist,
    5256             :                      List *qpqual,
    5257             :                      Plan *lefttree,
    5258             :                      List *bitmapqualorig,
    5259             :                      Index scanrelid)
    5260             : {
    5261       19314 :     BitmapHeapScan *node = makeNode(BitmapHeapScan);
    5262       19314 :     Plan       *plan = &node->scan.plan;
    5263             : 
    5264       19314 :     plan->targetlist = qptlist;
    5265       19314 :     plan->qual = qpqual;
    5266       19314 :     plan->lefttree = lefttree;
    5267       19314 :     plan->righttree = NULL;
    5268       19314 :     node->scan.scanrelid = scanrelid;
    5269       19314 :     node->bitmapqualorig = bitmapqualorig;
    5270             : 
    5271       19314 :     return node;
    5272             : }
    5273             : 
    5274             : static TidScan *
    5275         410 : make_tidscan(List *qptlist,
    5276             :              List *qpqual,
    5277             :              Index scanrelid,
    5278             :              List *tidquals)
    5279             : {
    5280         410 :     TidScan    *node = makeNode(TidScan);
    5281         410 :     Plan       *plan = &node->scan.plan;
    5282             : 
    5283         410 :     plan->targetlist = qptlist;
    5284         410 :     plan->qual = qpqual;
    5285         410 :     plan->lefttree = NULL;
    5286         410 :     plan->righttree = NULL;
    5287         410 :     node->scan.scanrelid = scanrelid;
    5288         410 :     node->tidquals = tidquals;
    5289             : 
    5290         410 :     return node;
    5291             : }
    5292             : 
    5293             : static SubqueryScan *
    5294        8278 : make_subqueryscan(List *qptlist,
    5295             :                   List *qpqual,
    5296             :                   Index scanrelid,
    5297             :                   Plan *subplan)
    5298             : {
    5299        8278 :     SubqueryScan *node = makeNode(SubqueryScan);
    5300        8278 :     Plan       *plan = &node->scan.plan;
    5301             : 
    5302        8278 :     plan->targetlist = qptlist;
    5303        8278 :     plan->qual = qpqual;
    5304        8278 :     plan->lefttree = NULL;
    5305        8278 :     plan->righttree = NULL;
    5306        8278 :     node->scan.scanrelid = scanrelid;
    5307        8278 :     node->subplan = subplan;
    5308             : 
    5309        8278 :     return node;
    5310             : }
    5311             : 
    5312             : static FunctionScan *
    5313       28676 : make_functionscan(List *qptlist,
    5314             :                   List *qpqual,
    5315             :                   Index scanrelid,
    5316             :                   List *functions,
    5317             :                   bool funcordinality)
    5318             : {
    5319       28676 :     FunctionScan *node = makeNode(FunctionScan);
    5320       28676 :     Plan       *plan = &node->scan.plan;
    5321             : 
    5322       28676 :     plan->targetlist = qptlist;
    5323       28676 :     plan->qual = qpqual;
    5324       28676 :     plan->lefttree = NULL;
    5325       28676 :     plan->righttree = NULL;
    5326       28676 :     node->scan.scanrelid = scanrelid;
    5327       28676 :     node->functions = functions;
    5328       28676 :     node->funcordinality = funcordinality;
    5329             : 
    5330       28676 :     return node;
    5331             : }
    5332             : 
    5333             : static TableFuncScan *
    5334         144 : make_tablefuncscan(List *qptlist,
    5335             :                    List *qpqual,
    5336             :                    Index scanrelid,
    5337             :                    TableFunc *tablefunc)
    5338             : {
    5339         144 :     TableFuncScan *node = makeNode(TableFuncScan);
    5340         144 :     Plan       *plan = &node->scan.plan;
    5341             : 
    5342         144 :     plan->targetlist = qptlist;
    5343         144 :     plan->qual = qpqual;
    5344         144 :     plan->lefttree = NULL;
    5345         144 :     plan->righttree = NULL;
    5346         144 :     node->scan.scanrelid = scanrelid;
    5347         144 :     node->tablefunc = tablefunc;
    5348             : 
    5349         144 :     return node;
    5350             : }
    5351             : 
    5352             : static ValuesScan *
    5353        3792 : make_valuesscan(List *qptlist,
    5354             :                 List *qpqual,
    5355             :                 Index scanrelid,
    5356             :                 List *values_lists)
    5357             : {
    5358        3792 :     ValuesScan *node = makeNode(ValuesScan);
    5359        3792 :     Plan       *plan = &node->scan.plan;
    5360             : 
    5361        3792 :     plan->targetlist = qptlist;
    5362        3792 :     plan->qual = qpqual;
    5363        3792 :     plan->lefttree = NULL;
    5364        3792 :     plan->righttree = NULL;
    5365        3792 :     node->scan.scanrelid = scanrelid;
    5366        3792 :     node->values_lists = values_lists;
    5367             : 
    5368        3792 :     return node;
    5369             : }
    5370             : 
    5371             : static CteScan *
    5372         876 : make_ctescan(List *qptlist,
    5373             :              List *qpqual,
    5374             :              Index scanrelid,
    5375             :              int ctePlanId,
    5376             :              int cteParam)
    5377             : {
    5378         876 :     CteScan    *node = makeNode(CteScan);
    5379         876 :     Plan       *plan = &node->scan.plan;
    5380             : 
    5381         876 :     plan->targetlist = qptlist;
    5382         876 :     plan->qual = qpqual;
    5383         876 :     plan->lefttree = NULL;
    5384         876 :     plan->righttree = NULL;
    5385         876 :     node->scan.scanrelid = scanrelid;
    5386         876 :     node->ctePlanId = ctePlanId;
    5387         876 :     node->cteParam = cteParam;
    5388             : 
    5389         876 :     return node;
    5390             : }
    5391             : 
    5392             : static NamedTuplestoreScan *
    5393         256 : make_namedtuplestorescan(List *qptlist,
    5394             :                          List *qpqual,
    5395             :                          Index scanrelid,
    5396             :                          char *enrname)
    5397             : {
    5398         256 :     NamedTuplestoreScan *node = makeNode(NamedTuplestoreScan);
    5399         256 :     Plan       *plan = &node->scan.plan;
    5400             : 
    5401             :     /* cost should be inserted by caller */
    5402         256 :     plan->targetlist = qptlist;
    5403         256 :     plan->qual = qpqual;
    5404         256 :     plan->lefttree = NULL;
    5405         256 :     plan->righttree = NULL;
    5406         256 :     node->scan.scanrelid = scanrelid;
    5407         256 :     node->enrname = enrname;
    5408             : 
    5409         256 :     return node;
    5410             : }
    5411             : 
    5412             : static WorkTableScan *
    5413         320 : make_worktablescan(List *qptlist,
    5414             :                    List *qpqual,
    5415             :                    Index scanrelid,
    5416             :                    int wtParam)
    5417             : {
    5418         320 :     WorkTableScan *node = makeNode(WorkTableScan);
    5419         320 :     Plan       *plan = &node->scan.plan;
    5420             : 
    5421         320 :     plan->targetlist = qptlist;
    5422         320 :     plan->qual = qpqual;
    5423         320 :     plan->lefttree = NULL;
    5424         320 :     plan->righttree = NULL;
    5425         320 :     node->scan.scanrelid = scanrelid;
    5426         320 :     node->wtParam = wtParam;
    5427             : 
    5428         320 :     return node;
    5429             : }
    5430             : 
    5431             : ForeignScan *
    5432        1420 : make_foreignscan(List *qptlist,
    5433             :                  List *qpqual,
    5434             :                  Index scanrelid,
    5435             :                  List *fdw_exprs,
    5436             :                  List *fdw_private,
    5437             :                  List *fdw_scan_tlist,
    5438             :                  List *fdw_recheck_quals,
    5439             :                  Plan *outer_plan)
    5440             : {
    5441        1420 :     ForeignScan *node = makeNode(ForeignScan);
    5442        1420 :     Plan       *plan = &node->scan.plan;
    5443             : 
    5444             :     /* cost will be filled in by create_foreignscan_plan */
    5445        1420 :     plan->targetlist = qptlist;
    5446        1420 :     plan->qual = qpqual;
    5447        1420 :     plan->lefttree = outer_plan;
    5448        1420 :     plan->righttree = NULL;
    5449        1420 :     node->scan.scanrelid = scanrelid;
    5450        1420 :     node->operation = CMD_SELECT;
    5451             :     /* fs_server will be filled in by create_foreignscan_plan */
    5452        1420 :     node->fs_server = InvalidOid;
    5453        1420 :     node->fdw_exprs = fdw_exprs;
    5454        1420 :     node->fdw_private = fdw_private;
    5455        1420 :     node->fdw_scan_tlist = fdw_scan_tlist;
    5456        1420 :     node->fdw_recheck_quals = fdw_recheck_quals;
    5457             :     /* fs_relids will be filled in by create_foreignscan_plan */
    5458        1420 :     node->fs_relids = NULL;
    5459             :     /* fsSystemCol will be filled in by create_foreignscan_plan */
    5460        1420 :     node->fsSystemCol = false;
    5461             : 
    5462        1420 :     return node;
    5463             : }
    5464             : 
    5465             : static RecursiveUnion *
    5466         320 : make_recursive_union(List *tlist,
    5467             :                      Plan *lefttree,
    5468             :                      Plan *righttree,
    5469             :                      int wtParam,
    5470             :                      List *distinctList,
    5471             :                      long numGroups)
    5472             : {
    5473         320 :     RecursiveUnion *node = makeNode(RecursiveUnion);
    5474         320 :     Plan       *plan = &node->plan;
    5475         320 :     int         numCols = list_length(distinctList);
    5476             : 
    5477         320 :     plan->targetlist = tlist;
    5478         320 :     plan->qual = NIL;
    5479         320 :     plan->lefttree = lefttree;
    5480         320 :     plan->righttree = righttree;
    5481         320 :     node->wtParam = wtParam;
    5482             : 
    5483             :     /*
    5484             :      * convert SortGroupClause list into arrays of attr indexes and equality
    5485             :      * operators, as wanted by executor
    5486             :      */
    5487         320 :     node->numCols = numCols;
    5488         320 :     if (numCols > 0)
    5489             :     {
    5490         152 :         int         keyno = 0;
    5491             :         AttrNumber *dupColIdx;
    5492             :         Oid        *dupOperators;
    5493             :         Oid        *dupCollations;
    5494             :         ListCell   *slitem;
    5495             : 
    5496         152 :         dupColIdx = (AttrNumber *) palloc(sizeof(AttrNumber) * numCols);
    5497         152 :         dupOperators = (Oid *) palloc(sizeof(Oid) * numCols);
    5498         152 :         dupCollations = (Oid *) palloc(sizeof(Oid) * numCols);
    5499             : 
    5500         584 :         foreach(slitem, distinctList)
    5501             :         {
    5502         432 :             SortGroupClause *sortcl = (SortGroupClause *) lfirst(slitem);
    5503         432 :             TargetEntry *tle = get_sortgroupclause_tle(sortcl,
    5504             :                                                        plan->targetlist);
    5505             : 
    5506         432 :             dupColIdx[keyno] = tle->resno;
    5507         432 :             dupOperators[keyno] = sortcl->eqop;
    5508         432 :             dupCollations[keyno] = exprCollation((Node *) tle->expr);
    5509             :             Assert(OidIsValid(dupOperators[keyno]));
    5510         432 :             keyno++;
    5511             :         }
    5512         152 :         node->dupColIdx = dupColIdx;
    5513         152 :         node->dupOperators = dupOperators;
    5514         152 :         node->dupCollations = dupCollations;
    5515             :     }
    5516         320 :     node->numGroups = numGroups;
    5517             : 
    5518         320 :     return node;
    5519             : }
    5520             : 
    5521             : static BitmapAnd *
    5522          44 : make_bitmap_and(List *bitmapplans)
    5523             : {
    5524          44 :     BitmapAnd  *node = makeNode(BitmapAnd);
    5525          44 :     Plan       *plan = &node->plan;
    5526             : 
    5527          44 :     plan->targetlist = NIL;
    5528          44 :     plan->qual = NIL;
    5529          44 :     plan->lefttree = NULL;
    5530          44 :     plan->righttree = NULL;
    5531          44 :     node->bitmapplans = bitmapplans;
    5532             : 
    5533          44 :     return node;
    5534             : }
    5535             : 
    5536             : static BitmapOr *
    5537         104 : make_bitmap_or(List *bitmapplans)
    5538             : {
    5539         104 :     BitmapOr   *node = makeNode(BitmapOr);
    5540         104 :     Plan       *plan = &node->plan;
    5541             : 
    5542         104 :     plan->targetlist = NIL;
    5543         104 :     plan->qual = NIL;
    5544         104 :     plan->lefttree = NULL;
    5545         104 :     plan->righttree = NULL;
    5546         104 :     node->bitmapplans = bitmapplans;
    5547             : 
    5548         104 :     return node;
    5549             : }
    5550             : 
    5551             : static NestLoop *
    5552       31470 : make_nestloop(List *tlist,
    5553             :               List *joinclauses,
    5554             :               List *otherclauses,
    5555             :               List *nestParams,
    5556             :               Plan *lefttree,
    5557             :               Plan *righttree,
    5558             :               JoinType jointype,
    5559             :               bool inner_unique)
    5560             : {
    5561       31470 :     NestLoop   *node = makeNode(NestLoop);
    5562       31470 :     Plan       *plan = &node->join.plan;
    5563             : 
    5564       31470 :     plan->targetlist = tlist;
    5565       31470 :     plan->qual = otherclauses;
    5566       31470 :     plan->lefttree = lefttree;
    5567       31470 :     plan->righttree = righttree;
    5568       31470 :     node->join.jointype = jointype;
    5569       31470 :     node->join.inner_unique = inner_unique;
    5570       31470 :     node->join.joinqual = joinclauses;
    5571       31470 :     node->nestParams = nestParams;
    5572             : 
    5573       31470 :     return node;
    5574             : }
    5575             : 
    5576             : static HashJoin *
    5577       26632 : make_hashjoin(List *tlist,
    5578             :               List *joinclauses,
    5579             :               List *otherclauses,
    5580             :               List *hashclauses,
    5581             :               List *hashoperators,
    5582             :               List *hashcollations,
    5583             :               List *hashkeys,
    5584             :               Plan *lefttree,
    5585             :               Plan *righttree,
    5586             :               JoinType jointype,
    5587             :               bool inner_unique)
    5588             : {
    5589       26632 :     HashJoin   *node = makeNode(HashJoin);
    5590       26632 :     Plan       *plan = &node->join.plan;
    5591             : 
    5592       26632 :     plan->targetlist = tlist;
    5593       26632 :     plan->qual = otherclauses;
    5594       26632 :     plan->lefttree = lefttree;
    5595       26632 :     plan->righttree = righttree;
    5596       26632 :     node->hashclauses = hashclauses;
    5597       26632 :     node->hashoperators = hashoperators;
    5598       26632 :     node->hashcollations = hashcollations;
    5599       26632 :     node->hashkeys = hashkeys;
    5600       26632 :     node->join.jointype = jointype;
    5601       26632 :     node->join.inner_unique = inner_unique;
    5602       26632 :     node->join.joinqual = joinclauses;
    5603             : 
    5604       26632 :     return node;
    5605             : }
    5606             : 
    5607             : static Hash *
    5608       26632 : make_hash(Plan *lefttree,
    5609             :           List *hashkeys,
    5610             :           Oid skewTable,
    5611             :           AttrNumber skewColumn,
    5612             :           bool skewInherit)
    5613             : {
    5614       26632 :     Hash       *node = makeNode(Hash);
    5615       26632 :     Plan       *plan = &node->plan;
    5616             : 
    5617       26632 :     plan->targetlist = lefttree->targetlist;
    5618       26632 :     plan->qual = NIL;
    5619       26632 :     plan->lefttree = lefttree;
    5620       26632 :     plan->righttree = NULL;
    5621             : 
    5622       26632 :     node->hashkeys = hashkeys;
    5623       26632 :     node->skewTable = skewTable;
    5624       26632 :     node->skewColumn = skewColumn;
    5625       26632 :     node->skewInherit = skewInherit;
    5626             : 
    5627       26632 :     return node;
    5628             : }
    5629             : 
    5630             : static MergeJoin *
    5631        2106 : make_mergejoin(List *tlist,
    5632             :                List *joinclauses,
    5633             :                List *otherclauses,
    5634             :                List *mergeclauses,
    5635             :                Oid *mergefamilies,
    5636             :                Oid *mergecollations,
    5637             :                int *mergestrategies,
    5638             :                bool *mergenullsfirst,
    5639             :                Plan *lefttree,
    5640             :                Plan *righttree,
    5641             :                JoinType jointype,
    5642             :                bool inner_unique,
    5643             :                bool skip_mark_restore)
    5644             : {
    5645        2106 :     MergeJoin  *node = makeNode(MergeJoin);
    5646        2106 :     Plan       *plan = &node->join.plan;
    5647             : 
    5648        2106 :     plan->targetlist = tlist;
    5649        2106 :     plan->qual = otherclauses;
    5650        2106 :     plan->lefttree = lefttree;
    5651        2106 :     plan->righttree = righttree;
    5652        2106 :     node->skip_mark_restore = skip_mark_restore;
    5653        2106 :     node->mergeclauses = mergeclauses;
    5654        2106 :     node->mergeFamilies = mergefamilies;
    5655        2106 :     node->mergeCollations = mergecollations;
    5656        2106 :     node->mergeStrategies = mergestrategies;
    5657        2106 :     node->mergeNullsFirst = mergenullsfirst;
    5658        2106 :     node->join.jointype = jointype;
    5659        2106 :     node->join.inner_unique = inner_unique;
    5660        2106 :     node->join.joinqual = joinclauses;
    5661             : 
    5662        2106 :     return node;
    5663             : }
    5664             : 
    5665             : /*
    5666             :  * make_sort --- basic routine to build a Sort plan node
    5667             :  *
    5668             :  * Caller must have built the sortColIdx, sortOperators, collations, and
    5669             :  * nullsFirst arrays already.
    5670             :  */
    5671             : static Sort *
    5672       32218 : make_sort(Plan *lefttree, int numCols,
    5673             :           AttrNumber *sortColIdx, Oid *sortOperators,
    5674             :           Oid *collations, bool *nullsFirst)
    5675             : {
    5676       32218 :     Sort       *node = makeNode(Sort);
    5677       32218 :     Plan       *plan = &node->plan;
    5678             : 
    5679       32218 :     plan->targetlist = lefttree->targetlist;
    5680       32218 :     plan->qual = NIL;
    5681       32218 :     plan->lefttree = lefttree;
    5682       32218 :     plan->righttree = NULL;
    5683       32218 :     node->numCols = numCols;
    5684       32218 :     node->sortColIdx = sortColIdx;
    5685       32218 :     node->sortOperators = sortOperators;
    5686       32218 :     node->collations = collations;
    5687       32218 :     node->nullsFirst = nullsFirst;
    5688             : 
    5689       32218 :     return node;
    5690             : }
    5691             : 
    5692             : /*
    5693             :  * prepare_sort_from_pathkeys
    5694             :  *    Prepare to sort according to given pathkeys
    5695             :  *
    5696             :  * This is used to set up for Sort, MergeAppend, and Gather Merge nodes.  It
    5697             :  * calculates the executor's representation of the sort key information, and
    5698             :  * adjusts the plan targetlist if needed to add resjunk sort columns.
    5699             :  *
    5700             :  * Input parameters:
    5701             :  *    'lefttree' is the plan node which yields input tuples
    5702             :  *    'pathkeys' is the list of pathkeys by which the result is to be sorted
    5703             :  *    'relids' identifies the child relation being sorted, if any
    5704             :  *    'reqColIdx' is NULL or an array of required sort key column numbers
    5705             :  *    'adjust_tlist_in_place' is true if lefttree must be modified in-place
    5706             :  *
    5707             :  * We must convert the pathkey information into arrays of sort key column
    5708             :  * numbers, sort operator OIDs, collation OIDs, and nulls-first flags,
    5709             :  * which is the representation the executor wants.  These are returned into
    5710             :  * the output parameters *p_numsortkeys etc.
    5711             :  *
    5712             :  * When looking for matches to an EquivalenceClass's members, we will only
    5713             :  * consider child EC members if they belong to given 'relids'.  This protects
    5714             :  * against possible incorrect matches to child expressions that contain no
    5715             :  * Vars.
    5716             :  *
    5717             :  * If reqColIdx isn't NULL then it contains sort key column numbers that
    5718             :  * we should match.  This is used when making child plans for a MergeAppend;
    5719             :  * it's an error if we can't match the columns.
    5720             :  *
    5721             :  * If the pathkeys include expressions that aren't simple Vars, we will
    5722             :  * usually need to add resjunk items to the input plan's targetlist to
    5723             :  * compute these expressions, since a Sort or MergeAppend node itself won't
    5724             :  * do any such calculations.  If the input plan type isn't one that can do
    5725             :  * projections, this means adding a Result node just to do the projection.
    5726             :  * However, the caller can pass adjust_tlist_in_place = true to force the
    5727             :  * lefttree tlist to be modified in-place regardless of whether the node type
    5728             :  * can project --- we use this for fixing the tlist of MergeAppend itself.
    5729             :  *
    5730             :  * Returns the node which is to be the input to the Sort (either lefttree,
    5731             :  * or a Result stacked atop lefttree).
    5732             :  */
    5733             : static Plan *
    5734       33500 : prepare_sort_from_pathkeys(Plan *lefttree, List *pathkeys,
    5735             :                            Relids relids,
    5736             :                            const AttrNumber *reqColIdx,
    5737             :                            bool adjust_tlist_in_place,
    5738             :                            int *p_numsortkeys,
    5739             :                            AttrNumber **p_sortColIdx,
    5740             :                            Oid **p_sortOperators,
    5741             :                            Oid **p_collations,
    5742             :                            bool **p_nullsFirst)
    5743             : {
    5744       33500 :     List       *tlist = lefttree->targetlist;
    5745             :     ListCell   *i;
    5746             :     int         numsortkeys;
    5747             :     AttrNumber *sortColIdx;
    5748             :     Oid        *sortOperators;
    5749             :     Oid        *collations;
    5750             :     bool       *nullsFirst;
    5751             : 
    5752             :     /*
    5753             :      * We will need at most list_length(pathkeys) sort columns; possibly less
    5754             :      */
    5755       33500 :     numsortkeys = list_length(pathkeys);
    5756       33500 :     sortColIdx = (AttrNumber *) palloc(numsortkeys * sizeof(AttrNumber));
    5757       33500 :     sortOperators = (Oid *) palloc(numsortkeys * sizeof(Oid));
    5758       33500 :     collations = (Oid *) palloc(numsortkeys * sizeof(Oid));
    5759       33500 :     nullsFirst = (bool *) palloc(numsortkeys * sizeof(bool));
    5760             : 
    5761       33500 :     numsortkeys = 0;
    5762             : 
    5763       76540 :     foreach(i, pathkeys)
    5764             :     {
    5765       43040 :         PathKey    *pathkey = (PathKey *) lfirst(i);
    5766       43040 :         EquivalenceClass *ec = pathkey->pk_eclass;
    5767             :         EquivalenceMember *em;
    5768       43040 :         TargetEntry *tle = NULL;
    5769       43040 :         Oid         pk_datatype = InvalidOid;
    5770             :         Oid         sortop;
    5771             :         ListCell   *j;
    5772             : 
    5773       43040 :         if (ec->ec_has_volatile)
    5774             :         {
    5775             :             /*
    5776             :              * If the pathkey's EquivalenceClass is volatile, then it must
    5777             :              * have come from an ORDER BY clause, and we have to match it to
    5778             :              * that same targetlist entry.
    5779             :              */
    5780          48 :             if (ec->ec_sortref == 0) /* can't happen */
    5781           0 :                 elog(ERROR, "volatile EquivalenceClass has no sortref");
    5782          48 :             tle = get_sortgroupref_tle(ec->ec_sortref, tlist);
    5783             :             Assert(tle);
    5784             :             Assert(list_length(ec->ec_members) == 1);
    5785          48 :             pk_datatype = ((EquivalenceMember *) linitial(ec->ec_members))->em_datatype;
    5786             :         }
    5787       42992 :         else if (reqColIdx != NULL)
    5788             :         {
    5789             :             /*
    5790             :              * If we are given a sort column number to match, only consider
    5791             :              * the single TLE at that position.  It's possible that there is
    5792             :              * no such TLE, in which case fall through and generate a resjunk
    5793             :              * targetentry (we assume this must have happened in the parent
    5794             :              * plan as well).  If there is a TLE but it doesn't match the
    5795             :              * pathkey's EC, we do the same, which is probably the wrong thing
    5796             :              * but we'll leave it to caller to complain about the mismatch.
    5797             :              */
    5798        1428 :             tle = get_tle_by_resno(tlist, reqColIdx[numsortkeys]);
    5799        1428 :             if (tle)
    5800             :             {
    5801        1364 :                 em = find_ec_member_for_tle(ec, tle, relids);
    5802        1364 :                 if (em)
    5803             :                 {
    5804             :                     /* found expr at right place in tlist */
    5805        1364 :                     pk_datatype = em->em_datatype;
    5806             :                 }
    5807             :                 else
    5808           0 :                     tle = NULL;
    5809             :             }
    5810             :         }
    5811             :         else
    5812             :         {
    5813             :             /*
    5814             :              * Otherwise, we can sort by any non-constant expression listed in
    5815             :              * the pathkey's EquivalenceClass.  For now, we take the first
    5816             :              * tlist item found in the EC. If there's no match, we'll generate
    5817             :              * a resjunk entry using the first EC member that is an expression
    5818             :              * in the input's vars.  (The non-const restriction only matters
    5819             :              * if the EC is below_outer_join; but if it isn't, it won't
    5820             :              * contain consts anyway, else we'd have discarded the pathkey as
    5821             :              * redundant.)
    5822             :              *
    5823             :              * XXX if we have a choice, is there any way of figuring out which
    5824             :              * might be cheapest to execute?  (For example, int4lt is likely
    5825             :              * much cheaper to execute than numericlt, but both might appear
    5826             :              * in the same equivalence class...)  Not clear that we ever will
    5827             :              * have an interesting choice in practice, so it may not matter.
    5828             :              */
    5829       91590 :             foreach(j, tlist)
    5830             :             {
    5831       91482 :                 tle = (TargetEntry *) lfirst(j);
    5832       91482 :                 em = find_ec_member_for_tle(ec, tle, relids);
    5833       91482 :                 if (em)
    5834             :                 {
    5835             :                     /* found expr already in tlist */
    5836       41456 :                     pk_datatype = em->em_datatype;
    5837       41456 :                     break;
    5838             :                 }
    5839       50026 :                 tle = NULL;
    5840             :             }
    5841             :         }
    5842             : 
    5843       43040 :         if (!tle)
    5844             :         {
    5845             :             /*
    5846             :              * No matching tlist item; look for a computable expression. Note
    5847             :              * that we treat Aggrefs as if they were variables; this is
    5848             :              * necessary when attempting to sort the output from an Agg node
    5849             :              * for use in a WindowFunc (since grouping_planner will have
    5850             :              * treated the Aggrefs as variables, too).  Likewise, if we find a
    5851             :              * WindowFunc in a sort expression, treat it as a variable.
    5852             :              */
    5853         172 :             Expr       *sortexpr = NULL;
    5854             : 
    5855         632 :             foreach(j, ec->ec_members)
    5856             :             {
    5857         632 :                 EquivalenceMember *em = (EquivalenceMember *) lfirst(j);
    5858             :                 List       *exprvars;
    5859             :                 ListCell   *k;
    5860             : 
    5861             :                 /*
    5862             :                  * We shouldn't be trying to sort by an equivalence class that
    5863             :                  * contains a constant, so no need to consider such cases any
    5864             :                  * further.
    5865             :                  */
    5866         632 :                 if (em->em_is_const)
    5867           0 :                     continue;
    5868             : 
    5869             :                 /*
    5870             :                  * Ignore child members unless they belong to the rel being
    5871             :                  * sorted.
    5872             :                  */
    5873        1032 :                 if (em->em_is_child &&
    5874         400 :                     !bms_is_subset(em->em_relids, relids))
    5875         288 :                     continue;
    5876             : 
    5877         344 :                 sortexpr = em->em_expr;
    5878         344 :                 exprvars = pull_var_clause((Node *) sortexpr,
    5879             :                                            PVC_INCLUDE_AGGREGATES |
    5880             :                                            PVC_INCLUDE_WINDOWFUNCS |
    5881             :                                            PVC_INCLUDE_PLACEHOLDERS);
    5882         572 :                 foreach(k, exprvars)
    5883             :                 {
    5884         400 :                     if (!tlist_member_ignore_relabel(lfirst(k), tlist))
    5885         172 :                         break;
    5886             :                 }
    5887         344 :                 list_free(exprvars);
    5888         344 :                 if (!k)
    5889             :                 {
    5890         172 :                     pk_datatype = em->em_datatype;
    5891         172 :                     break;      /* found usable expression */
    5892             :                 }
    5893             :             }
    5894         172 :             if (!j)
    5895           0 :                 elog(ERROR, "could not find pathkey item to sort");
    5896             : 
    5897             :             /*
    5898             :              * Do we need to insert a Result node?
    5899             :              */
    5900         328 :             if (!adjust_tlist_in_place &&
    5901         156 :                 !is_projection_capable_plan(lefttree))
    5902             :             {
    5903             :                 /* copy needed so we don't modify input's tlist below */
    5904          16 :                 tlist = copyObject(tlist);
    5905          16 :                 lefttree = inject_projection_plan(lefttree, tlist,
    5906          16 :                                                   lefttree->parallel_safe);
    5907             :             }
    5908             : 
    5909             :             /* Don't bother testing is_projection_capable_plan again */
    5910         172 :             adjust_tlist_in_place = true;
    5911             : 
    5912             :             /*
    5913             :              * Add resjunk entry to input's tlist
    5914             :              */
    5915         172 :             tle = makeTargetEntry(sortexpr,
    5916         172 :                                   list_length(tlist) + 1,
    5917             :                                   NULL,
    5918             :                                   true);
    5919         172 :             tlist = lappend(tlist, tle);
    5920         172 :             lefttree->targetlist = tlist;    /* just in case NIL before */
    5921             :         }
    5922             : 
    5923             :         /*
    5924             :          * Look up the correct sort operator from the PathKey's slightly
    5925             :          * abstracted representation.
    5926             :          */
    5927       43040 :         sortop = get_opfamily_member(pathkey->pk_opfamily,
    5928             :                                      pk_datatype,
    5929             :                                      pk_datatype,
    5930       43040 :                                      pathkey->pk_strategy);
    5931       43040 :         if (!OidIsValid(sortop))    /* should not happen */
    5932           0 :             elog(ERROR, "missing operator %d(%u,%u) in opfamily %u",
    5933             :                  pathkey->pk_strategy, pk_datatype, pk_datatype,
    5934             :                  pathkey->pk_opfamily);
    5935             : 
    5936             :         /* Add the column to the sort arrays */
    5937       43040 :         sortColIdx[numsortkeys] = tle->resno;
    5938       43040 :         sortOperators[numsortkeys] = sortop;
    5939       43040 :         collations[numsortkeys] = ec->ec_collation;
    5940       43040 :         nullsFirst[numsortkeys] = pathkey->pk_nulls_first;
    5941       43040 :         numsortkeys++;
    5942             :     }
    5943             : 
    5944             :     /* Return results */
    5945       33500 :     *p_numsortkeys = numsortkeys;
    5946       33500 :     *p_sortColIdx = sortColIdx;
    5947       33500 :     *p_sortOperators = sortOperators;
    5948       33500 :     *p_collations = collations;
    5949       33500 :     *p_nullsFirst = nullsFirst;
    5950             : 
    5951       33500 :     return lefttree;
    5952             : }
    5953             : 
    5954             : /*
    5955             :  * find_ec_member_for_tle
    5956             :  *      Locate an EquivalenceClass member matching the given TLE, if any
    5957             :  *
    5958             :  * Child EC members are ignored unless they belong to given 'relids'.
    5959             :  */
    5960             : static EquivalenceMember *
    5961       93564 : find_ec_member_for_tle(EquivalenceClass *ec,
    5962             :                        TargetEntry *tle,
    5963             :                        Relids relids)
    5964             : {
    5965             :     Expr       *tlexpr;
    5966             :     ListCell   *lc;
    5967             : 
    5968             :     /* We ignore binary-compatible relabeling on both ends */
    5969       93564 :     tlexpr = tle->expr;
    5970      192588 :     while (tlexpr && IsA(tlexpr, RelabelType))
    5971        5460 :         tlexpr = ((RelabelType *) tlexpr)->arg;
    5972             : 
    5973      168952 :     foreach(lc, ec->ec_members)
    5974             :     {
    5975      118698 :         EquivalenceMember *em = (EquivalenceMember *) lfirst(lc);
    5976             :         Expr       *emexpr;
    5977             : 
    5978             :         /*
    5979             :          * We shouldn't be trying to sort by an equivalence class that
    5980             :          * contains a constant, so no need to consider such cases any further.
    5981             :          */
    5982      118698 :         if (em->em_is_const)
    5983           0 :             continue;
    5984             : 
    5985             :         /*
    5986             :          * Ignore child members unless they belong to the rel being sorted.
    5987             :          */
    5988      141252 :         if (em->em_is_child &&
    5989       22554 :             !bms_is_subset(em->em_relids, relids))
    5990       20398 :             continue;
    5991             : 
    5992             :         /* Match if same expression (after stripping relabel) */
    5993       98300 :         emexpr = em->em_expr;
    5994      198556 :         while (emexpr && IsA(emexpr, RelabelType))
    5995        1956 :             emexpr = ((RelabelType *) emexpr)->arg;
    5996             : 
    5997       98300 :         if (equal(emexpr, tlexpr))
    5998       43310 :             return em;
    5999             :     }
    6000             : 
    6001       50254 :     return NULL;
    6002             : }
    6003             : 
    6004             : /*
    6005             :  * make_sort_from_pathkeys
    6006             :  *    Create sort plan to sort according to given pathkeys
    6007             :  *
    6008             :  *    'lefttree' is the node which yields input tuples
    6009             :  *    'pathkeys' is the list of pathkeys by which the result is to be sorted
    6010             :  *    'relids' is the set of relations required by prepare_sort_from_pathkeys()
    6011             :  */
    6012             : static Sort *
    6013       32044 : make_sort_from_pathkeys(Plan *lefttree, List *pathkeys, Relids relids)
    6014             : {
    6015             :     int         numsortkeys;
    6016             :     AttrNumber *sortColIdx;
    6017             :     Oid        *sortOperators;
    6018             :     Oid        *collations;
    6019             :     bool       *nullsFirst;
    6020             : 
    6021             :     /* Compute sort column info, and adjust lefttree as needed */
    6022       32044 :     lefttree = prepare_sort_from_pathkeys(lefttree, pathkeys,
    6023             :                                           relids,
    6024             :                                           NULL,
    6025             :                                           false,
    6026             :                                           &numsortkeys,
    6027             :                                           &sortColIdx,
    6028             :                                           &sortOperators,
    6029             :                                           &collations,
    6030             :                                           &nullsFirst);
    6031             : 
    6032             :     /* Now build the Sort node */
    6033       32044 :     return make_sort(lefttree, numsortkeys,
    6034             :                      sortColIdx, sortOperators,
    6035             :                      collations, nullsFirst);
    6036             : }
    6037             : 
    6038             : /*
    6039             :  * make_sort_from_sortclauses
    6040             :  *    Create sort plan to sort according to given sortclauses
    6041             :  *
    6042             :  *    'sortcls' is a list of SortGroupClauses
    6043             :  *    'lefttree' is the node which yields input tuples
    6044             :  */
    6045             : Sort *
    6046           2 : make_sort_from_sortclauses(List *sortcls, Plan *lefttree)
    6047             : {
    6048           2 :     List       *sub_tlist = lefttree->targetlist;
    6049             :     ListCell   *l;
    6050             :     int         numsortkeys;
    6051             :     AttrNumber *sortColIdx;
    6052             :     Oid        *sortOperators;
    6053             :     Oid        *collations;
    6054             :     bool       *nullsFirst;
    6055             : 
    6056             :     /* Convert list-ish representation to arrays wanted by executor */
    6057           2 :     numsortkeys = list_length(sortcls);
    6058           2 :     sortColIdx = (AttrNumber *) palloc(numsortkeys * sizeof(AttrNumber));
    6059           2 :     sortOperators = (Oid *) palloc(numsortkeys * sizeof(Oid));
    6060           2 :     collations = (Oid *) palloc(numsortkeys * sizeof(Oid));
    6061           2 :     nullsFirst = (bool *) palloc(numsortkeys * sizeof(bool));
    6062             : 
    6063           2 :     numsortkeys = 0;
    6064           4 :     foreach(l, sortcls)
    6065             :     {
    6066           2 :         SortGroupClause *sortcl = (SortGroupClause *) lfirst(l);
    6067           2 :         TargetEntry *tle = get_sortgroupclause_tle(sortcl, sub_tlist);
    6068             : 
    6069           2 :         sortColIdx[numsortkeys] = tle->resno;
    6070           2 :         sortOperators[numsortkeys] = sortcl->sortop;
    6071           2 :         collations[numsortkeys] = exprCollation((Node *) tle->expr);
    6072           2 :         nullsFirst[numsortkeys] = sortcl->nulls_first;
    6073           2 :         numsortkeys++;
    6074             :     }
    6075             : 
    6076           2 :     return make_sort(lefttree, numsortkeys,
    6077             :                      sortColIdx, sortOperators,
    6078             :                      collations, nullsFirst);
    6079             : }
    6080             : 
    6081             : /*
    6082             :  * make_sort_from_groupcols
    6083             :  *    Create sort plan to sort based on grouping columns
    6084             :  *
    6085             :  * 'groupcls' is the list of SortGroupClauses
    6086             :  * 'grpColIdx' gives the column numbers to use
    6087             :  *
    6088             :  * This might look like it could be merged with make_sort_from_sortclauses,
    6089             :  * but presently we *must* use the grpColIdx[] array to locate sort columns,
    6090             :  * because the child plan's tlist is not marked with ressortgroupref info
    6091             :  * appropriate to the grouping node.  So, only the sort ordering info
    6092             :  * is used from the SortGroupClause entries.
    6093             :  */
    6094             : static Sort *
    6095         128 : make_sort_from_groupcols(List *groupcls,
    6096             :                          AttrNumber *grpColIdx,
    6097             :                          Plan *lefttree)
    6098             : {
    6099         128 :     List       *sub_tlist = lefttree->targetlist;
    6100             :     ListCell   *l;
    6101             :     int         numsortkeys;
    6102             :     AttrNumber *sortColIdx;
    6103             :     Oid        *sortOperators;
    6104             :     Oid        *collations;
    6105             :     bool       *nullsFirst;
    6106             : 
    6107             :     /* Convert list-ish representation to arrays wanted by executor */
    6108         128 :     numsortkeys = list_length(groupcls);
    6109         128 :     sortColIdx = (AttrNumber *) palloc(numsortkeys * sizeof(AttrNumber));
    6110         128 :     sortOperators = (Oid *) palloc(numsortkeys * sizeof(Oid));
    6111         128 :     collations = (Oid *) palloc(numsortkeys * sizeof(Oid));
    6112         128 :     nullsFirst = (bool *) palloc(numsortkeys * sizeof(bool));
    6113             : 
    6114         128 :     numsortkeys = 0;
    6115         300 :     foreach(l, groupcls)
    6116             :     {
    6117         172 :         SortGroupClause *grpcl = (SortGroupClause *) lfirst(l);
    6118         172 :         TargetEntry *tle = get_tle_by_resno(sub_tlist, grpColIdx[numsortkeys]);
    6119             : 
    6120         172 :         if (!tle)
    6121           0 :             elog(ERROR, "could not retrieve tle for sort-from-groupcols");
    6122             : 
    6123         172 :         sortColIdx[numsortkeys] = tle->resno;
    6124         172 :         sortOperators[numsortkeys] = grpcl->sortop;
    6125         172 :         collations[numsortkeys] = exprCollation((Node *) tle->expr);
    6126         172 :         nullsFirst[numsortkeys] = grpcl->nulls_first;
    6127         172 :         numsortkeys++;
    6128             :     }
    6129             : 
    6130         128 :     return make_sort(lefttree, numsortkeys,
    6131             :                      sortColIdx, sortOperators,
    6132             :                      collations, nullsFirst);
    6133             : }
    6134             : 
    6135             : static Material *
    6136        2762 : make_material(Plan *lefttree)
    6137             : {
    6138        2762 :     Material   *node = makeNode(Material);
    6139        2762 :     Plan       *plan = &node->plan;
    6140             : 
    6141        2762 :     plan->targetlist = lefttree->targetlist;
    6142        2762 :     plan->qual = NIL;
    6143        2762 :     plan->lefttree = lefttree;
    6144        2762 :     plan->righttree = NULL;
    6145             : 
    6146        2762 :     return node;
    6147             : }
    6148             : 
    6149             : /*
    6150             :  * materialize_finished_plan: stick a Material node atop a completed plan
    6151             :  *
    6152             :  * There are a couple of places where we want to attach a Material node
    6153             :  * after completion of create_plan(), without any MaterialPath path.
    6154             :  * Those places should probably be refactored someday to do this on the
    6155             :  * Path representation, but it's not worth the trouble yet.
    6156             :  */
    6157             : Plan *
    6158          28 : materialize_finished_plan(Plan *subplan)
    6159             : {
    6160             :     Plan       *matplan;
    6161             :     Path        matpath;        /* dummy for result of cost_material */
    6162             : 
    6163          28 :     matplan = (Plan *) make_material(subplan);
    6164             : 
    6165             :     /*
    6166             :      * XXX horrid kluge: if there are any initPlans attached to the subplan,
    6167             :      * move them up to the Material node, which is now effectively the top
    6168             :      * plan node in its query level.  This prevents failure in
    6169             :      * SS_finalize_plan(), which see for comments.  We don't bother adjusting
    6170             :      * the subplan's cost estimate for this.
    6171             :      */
    6172          28 :     matplan->initPlan = subplan->initPlan;
    6173          28 :     subplan->initPlan = NIL;
    6174             : 
    6175             :     /* Set cost data */
    6176          28 :     cost_material(&matpath,
    6177             :                   subplan->startup_cost,
    6178             :                   subplan->total_cost,
    6179             :                   subplan->plan_rows,
    6180             :                   subplan->plan_width);
    6181          28 :     matplan->startup_cost = matpath.startup_cost;
    6182          28 :     matplan->total_cost = matpath.total_cost;
    6183          28 :     matplan->plan_rows = subplan->plan_rows;
    6184          28 :     matplan->plan_width = subplan->plan_width;
    6185          28 :     matplan->parallel_aware = false;
    6186          28 :     matplan->parallel_safe = subplan->parallel_safe;
    6187             : 
    6188          28 :     return matplan;
    6189             : }
    6190             : 
    6191             : Agg *
    6192       25406 : make_agg(List *tlist, List *qual,
    6193             :          AggStrategy aggstrategy, AggSplit aggsplit,
    6194             :          int numGroupCols, AttrNumber *grpColIdx, Oid *grpOperators, Oid *grpCollations,
    6195             :          List *groupingSets, List *chain,
    6196             :          double dNumGroups, Plan *lefttree)
    6197             : {
    6198       25406 :     Agg        *node = makeNode(Agg);
    6199       25406 :     Plan       *plan = &node->plan;
    6200             :     long        numGroups;
    6201             : 
    6202             :     /* Reduce to long, but 'ware overflow! */
    6203       25406 :     numGroups = (long) Min(dNumGroups, (double) LONG_MAX);
    6204             : 
    6205       25406 :     node->aggstrategy = aggstrategy;
    6206       25406 :     node->aggsplit = aggsplit;
    6207       25406 :     node->numCols = numGroupCols;
    6208       25406 :     node->grpColIdx = grpColIdx;
    6209       25406 :     node->grpOperators = grpOperators;
    6210       25406 :     node->grpCollations = grpCollations;
    6211       25406 :     node->numGroups = numGroups;
    6212       25406 :     node->aggParams = NULL;      /* SS_finalize_plan() will fill this */
    6213       25406 :     node->groupingSets = groupingSets;
    6214       25406 :     node->chain = chain;
    6215             : 
    6216       25406 :     plan->qual = qual;
    6217       25406 :     plan->targetlist = tlist;
    6218       25406 :     plan->lefttree = lefttree;
    6219       25406 :     plan->righttree = NULL;
    6220             : 
    6221       25406 :     return node;
    6222             : }
    6223             : 
    6224             : static WindowAgg *
    6225        1160 : make_windowagg(List *tlist, Index winref,
    6226             :                int partNumCols, AttrNumber *partColIdx, Oid *partOperators, Oid *partCollations,
    6227             :                int ordNumCols, AttrNumber *ordColIdx, Oid *ordOperators, Oid *ordCollations,
    6228             :                int frameOptions, Node *startOffset, Node *endOffset,
    6229             :                Oid startInRangeFunc, Oid endInRangeFunc,
    6230             :                Oid inRangeColl, bool inRangeAsc, bool inRangeNullsFirst,
    6231             :                Plan *lefttree)
    6232             : {
    6233        1160 :     WindowAgg  *node = makeNode(WindowAgg);
    6234        1160 :     Plan       *plan = &node->plan;
    6235             : 
    6236        1160 :     node->winref = winref;
    6237        1160 :     node->partNumCols = partNumCols;
    6238        1160 :     node->partColIdx = partColIdx;
    6239        1160 :     node->partOperators = partOperators;
    6240        1160 :     node->partCollations = partCollations;
    6241        1160 :     node->ordNumCols = ordNumCols;
    6242        1160 :     node->ordColIdx = ordColIdx;
    6243        1160 :     node->ordOperators = ordOperators;
    6244        1160 :     node->ordCollations = ordCollations;
    6245        1160 :     node->frameOptions = frameOptions;
    6246        1160 :     node->startOffset = startOffset;
    6247        1160 :     node->endOffset = endOffset;
    6248        1160 :     node->startInRangeFunc = startInRangeFunc;
    6249        1160 :     node->endInRangeFunc = endInRangeFunc;
    6250        1160 :     node->inRangeColl = inRangeColl;
    6251        1160 :     node->inRangeAsc = inRangeAsc;
    6252        1160 :     node->inRangeNullsFirst = inRangeNullsFirst;
    6253             : 
    6254        1160 :     plan->targetlist = tlist;
    6255        1160 :     plan->lefttree = lefttree;
    6256        1160 :     plan->righttree = NULL;
    6257             :     /* WindowAgg nodes never have a qual clause */
    6258        1160 :     plan->qual = NIL;
    6259             : 
    6260        1160 :     return node;
    6261             : }
    6262             : 
    6263             : static Group *
    6264         138 : make_group(List *tlist,
    6265             :            List *qual,
    6266             :            int numGroupCols,
    6267             :            AttrNumber *grpColIdx,
    6268             :            Oid *grpOperators,
    6269             :            Oid *grpCollations,
    6270             :            Plan *lefttree)
    6271             : {
    6272         138 :     Group      *node = makeNode(Group);
    6273         138 :     Plan       *plan = &node->plan;
    6274             : 
    6275         138 :     node->numCols = numGroupCols;
    6276         138 :     node->grpColIdx = grpColIdx;
    6277         138 :     node->grpOperators = grpOperators;
    6278         138 :     node->grpCollations = grpCollations;
    6279             : 
    6280         138 :     plan->qual = qual;
    6281         138 :     plan->targetlist = tlist;
    6282         138 :     plan->lefttree = lefttree;
    6283         138 :     plan->righttree = NULL;
    6284             : 
    6285         138 :     return node;
    6286             : }
    6287             : 
    6288             : /*
    6289             :  * distinctList is a list of SortGroupClauses, identifying the targetlist items
    6290             :  * that should be considered by the Unique filter.  The input path must
    6291             :  * already be sorted accordingly.
    6292             :  */
    6293             : static Unique *
    6294           2 : make_unique_from_sortclauses(Plan *lefttree, List *distinctList)
    6295             : {
    6296           2 :     Unique     *node = makeNode(Unique);
    6297           2 :     Plan       *plan = &node->plan;
    6298           2 :     int         numCols = list_length(distinctList);
    6299           2 :     int         keyno = 0;
    6300             :     AttrNumber *uniqColIdx;
    6301             :     Oid        *uniqOperators;
    6302             :     Oid        *uniqCollations;
    6303             :     ListCell   *slitem;
    6304             : 
    6305           2 :     plan->targetlist = lefttree->targetlist;
    6306           2 :     plan->qual = NIL;
    6307           2 :     plan->lefttree = lefttree;
    6308           2 :     plan->righttree = NULL;
    6309             : 
    6310             :     /*
    6311             :      * convert SortGroupClause list into arrays of attr indexes and equality
    6312             :      * operators, as wanted by executor
    6313             :      */
    6314             :     Assert(numCols > 0);
    6315           2 :     uniqColIdx = (AttrNumber *) palloc(sizeof(AttrNumber) * numCols);
    6316           2 :     uniqOperators = (Oid *) palloc(sizeof(Oid) * numCols);
    6317           2 :     uniqCollations = (Oid *) palloc(sizeof(Oid) * numCols);
    6318             : 
    6319           4 :     foreach(slitem, distinctList)
    6320             :     {
    6321           2 :         SortGroupClause *sortcl = (SortGroupClause *) lfirst(slitem);
    6322           2 :         TargetEntry *tle = get_sortgroupclause_tle(sortcl, plan->targetlist);
    6323             : 
    6324           2 :         uniqColIdx[keyno] = tle->resno;
    6325           2 :         uniqOperators[keyno] = sortcl->eqop;
    6326           2 :         uniqCollations[keyno] = exprCollation((Node *) tle->expr);
    6327             :         Assert(OidIsValid(uniqOperators[keyno]));
    6328           2 :         keyno++;
    6329             :     }
    6330             : 
    6331           2 :     node->numCols = numCols;
    6332           2 :     node->uniqColIdx = uniqColIdx;
    6333           2 :     node->uniqOperators = uniqOperators;
    6334           2 :     node->uniqCollations = uniqCollations;
    6335             : 
    6336           2 :     return node;
    6337             : }
    6338             : 
    6339             : /*
    6340             :  * as above, but use pathkeys to identify the sort columns and semantics
    6341             :  */
    6342             : static Unique *
    6343         324 : make_unique_from_pathkeys(Plan *lefttree, List *pathkeys, int numCols)
    6344             : {
    6345         324 :     Unique     *node = makeNode(Unique);
    6346         324 :     Plan       *plan = &node->plan;
    6347         324 :     int         keyno = 0;
    6348             :     AttrNumber *uniqColIdx;
    6349             :     Oid        *uniqOperators;
    6350             :     Oid        *uniqCollations;
    6351             :     ListCell   *lc;
    6352             : 
    6353         324 :     plan->targetlist = lefttree->targetlist;
    6354         324 :     plan->qual = NIL;
    6355         324 :     plan->lefttree = lefttree;
    6356         324 :     plan->righttree = NULL;
    6357             : 
    6358             :     /*
    6359             :      * Convert pathkeys list into arrays of attr indexes and equality
    6360             :      * operators, as wanted by executor.  This has a lot in common with
    6361             :      * prepare_sort_from_pathkeys ... maybe unify sometime?
    6362             :      */
    6363             :     Assert(numCols >= 0 && numCols <= list_length(pathkeys));
    6364         324 :     uniqColIdx = (AttrNumber *) palloc(sizeof(AttrNumber) * numCols);
    6365         324 :     uniqOperators = (Oid *) palloc(sizeof(Oid) * numCols);
    6366         324 :     uniqCollations = (Oid *) palloc(sizeof(Oid) * numCols);
    6367             : 
    6368         818 :     foreach(lc, pathkeys)
    6369             :     {
    6370         514 :         PathKey    *pathkey = (PathKey *) lfirst(lc);
    6371         514 :         EquivalenceClass *ec = pathkey->pk_eclass;
    6372             :         EquivalenceMember *em;
    6373         514 :         TargetEntry *tle = NULL;
    6374         514 :         Oid         pk_datatype = InvalidOid;
    6375             :         Oid         eqop;
    6376             :         ListCell   *j;
    6377             : 
    6378             :         /* Ignore pathkeys beyond the specified number of columns */
    6379         514 :         if (keyno >= numCols)
    6380          20 :             break;
    6381             : 
    6382         494 :         if (ec->ec_has_volatile)
    6383             :         {
    6384             :             /*
    6385             :              * If the pathkey's EquivalenceClass is volatile, then it must
    6386             :              * have come from an ORDER BY clause, and we have to match it to
    6387             :              * that same targetlist entry.
    6388             :              */
    6389           4 :             if (ec->ec_sortref == 0) /* can't happen */
    6390           0 :                 elog(ERROR, "volatile EquivalenceClass has no sortref");
    6391           4 :             tle = get_sortgroupref_tle(ec->ec_sortref, plan->targetlist);
    6392             :             Assert(tle);
    6393             :             Assert(list_length(ec->ec_members) == 1);
    6394           4 :             pk_datatype = ((EquivalenceMember *) linitial(ec->ec_members))->em_datatype;
    6395             :         }
    6396             :         else
    6397             :         {
    6398             :             /*
    6399             :              * Otherwise, we can use any non-constant expression listed in the
    6400             :              * pathkey's EquivalenceClass.  For now, we take the first tlist
    6401             :              * item found in the EC.
    6402             :              */
    6403         718 :             foreach(j, plan->targetlist)
    6404             :             {
    6405         718 :                 tle = (TargetEntry *) lfirst(j);
    6406         718 :                 em = find_ec_member_for_tle(ec, tle, NULL);
    6407         718 :                 if (em)
    6408             :                 {
    6409             :                     /* found expr already in tlist */
    6410         490 :                     pk_datatype = em->em_datatype;
    6411         490 :                     break;
    6412             :                 }
    6413         228 :                 tle = NULL;
    6414             :             }
    6415             :         }
    6416             : 
    6417         494 :         if (!tle)
    6418           0 :             elog(ERROR, "could not find pathkey item to sort");
    6419             : 
    6420             :         /*
    6421             :          * Look up the correct equality operator from the PathKey's slightly
    6422             :          * abstracted representation.
    6423             :          */
    6424         494 :         eqop = get_opfamily_member(pathkey->pk_opfamily,
    6425             :                                    pk_datatype,
    6426             :                                    pk_datatype,
    6427             :                                    BTEqualStrategyNumber);
    6428         494 :         if (!OidIsValid(eqop))  /* should not happen */
    6429           0 :             elog(ERROR, "missing operator %d(%u,%u) in opfamily %u",
    6430             :                  BTEqualStrategyNumber, pk_datatype, pk_datatype,
    6431             :                  pathkey->pk_opfamily);
    6432             : 
    6433         494 :         uniqColIdx[keyno] = tle->resno;
    6434         494 :         uniqOperators[keyno] = eqop;
    6435         494 :         uniqCollations[keyno] = ec->ec_collation;
    6436             : 
    6437         494 :         keyno++;
    6438             :     }
    6439             : 
    6440         324 :     node->numCols = numCols;
    6441         324 :     node->uniqColIdx = uniqColIdx;
    6442         324 :     node->uniqOperators = uniqOperators;
    6443         324 :     node->uniqCollations = uniqCollations;
    6444             : 
    6445         324 :     return node;
    6446             : }
    6447             : 
    6448             : static Gather *
    6449         488 : make_gather(List *qptlist,
    6450             :             List *qpqual,
    6451             :             int nworkers,
    6452             :             int rescan_param,
    6453             :             bool single_copy,
    6454             :             Plan *subplan)
    6455             : {
    6456         488 :     Gather     *node = makeNode(Gather);
    6457         488 :     Plan       *plan = &node->plan;
    6458             : 
    6459         488 :     plan->targetlist = qptlist;
    6460         488 :     plan->qual = qpqual;
    6461         488 :     plan->lefttree = subplan;
    6462         488 :     plan->righttree = NULL;
    6463         488 :     node->num_workers = nworkers;
    6464         488 :     node->rescan_param = rescan_param;
    6465         488 :     node->single_copy = single_copy;
    6466         488 :     node->invisible = false;
    6467         488 :     node->initParam = NULL;
    6468             : 
    6469         488 :     return node;
    6470             : }
    6471             : 
    6472             : /*
    6473             :  * distinctList is a list of SortGroupClauses, identifying the targetlist
    6474             :  * items that should be considered by the SetOp filter.  The input path must
    6475             :  * already be sorted accordingly.
    6476             :  */
    6477             : static SetOp *
    6478         208 : make_setop(SetOpCmd cmd, SetOpStrategy strategy, Plan *lefttree,
    6479             :            List *distinctList, AttrNumber flagColIdx, int firstFlag,
    6480             :            long numGroups)
    6481             : {
    6482         208 :     SetOp      *node = makeNode(SetOp);
    6483         208 :     Plan       *plan = &node->plan;
    6484         208 :     int         numCols = list_length(distinctList);
    6485         208 :     int         keyno = 0;
    6486             :     AttrNumber *dupColIdx;
    6487             :     Oid        *dupOperators;
    6488             :     Oid        *dupCollations;
    6489             :     ListCell   *slitem;
    6490             : 
    6491         208 :     plan->targetlist = lefttree->targetlist;
    6492         208 :     plan->qual = NIL;
    6493         208 :     plan->lefttree = lefttree;
    6494         208 :     plan->righttree = NULL;
    6495             : 
    6496             :     /*
    6497             :      * convert SortGroupClause list into arrays of attr indexes and equality
    6498             :      * operators, as wanted by executor
    6499             :      */
    6500         208 :     dupColIdx = (AttrNumber *) palloc(sizeof(AttrNumber) * numCols);
    6501         208 :     dupOperators = (Oid *) palloc(sizeof(Oid) * numCols);
    6502         208 :     dupCollations = (Oid *) palloc(sizeof(Oid) * numCols);
    6503             : 
    6504         472 :     foreach(slitem, distinctList)
    6505             :     {
    6506         264 :         SortGroupClause *sortcl = (SortGroupClause *) lfirst(slitem);
    6507         264 :         TargetEntry *tle = get_sortgroupclause_tle(sortcl, plan->targetlist);
    6508             : 
    6509         264 :         dupColIdx[keyno] = tle->resno;
    6510         264 :         dupOperators[keyno] = sortcl->eqop;
    6511         264 :         dupCollations[keyno] = exprCollation((Node *) tle->expr);
    6512             :         Assert(OidIsValid(dupOperators[keyno]));
    6513         264 :         keyno++;
    6514             :     }
    6515             : 
    6516         208 :     node->cmd = cmd;
    6517         208 :     node->strategy = strategy;
    6518         208 :     node->numCols = numCols;
    6519         208 :     node->dupColIdx = dupColIdx;
    6520         208 :     node->dupOperators = dupOperators;
    6521         208 :     node->dupCollations = dupCollations;
    6522         208 :     node->flagColIdx = flagColIdx;
    6523         208 :     node->firstFlag = firstFlag;
    6524         208 :     node->numGroups = numGroups;
    6525             : 
    6526         208 :     return node;
    6527             : }
    6528             : 
    6529             : /*
    6530             :  * make_lockrows
    6531             :  *    Build a LockRows plan node
    6532             :  */
    6533             : static LockRows *
    6534        4840 : make_lockrows(Plan *lefttree, List *rowMarks, int epqParam)
    6535             : {
    6536        4840 :     LockRows   *node = makeNode(LockRows);
    6537        4840 :     Plan       *plan = &node->plan;
    6538             : 
    6539        4840 :     plan->targetlist = lefttree->targetlist;
    6540        4840 :     plan->qual = NIL;
    6541        4840 :     plan->lefttree = lefttree;
    6542        4840 :     plan->righttree = NULL;
    6543             : 
    6544        4840 :     node->rowMarks = rowMarks;
    6545        4840 :     node->epqParam = epqParam;
    6546             : 
    6547        4840 :     return node;
    6548             : }
    6549             : 
    6550             : /*
    6551             :  * make_limit
    6552             :  *    Build a Limit plan node
    6553             :  */
    6554             : Limit *
    6555        3076 : make_limit(Plan *lefttree, Node *limitOffset, Node *limitCount)
    6556             : {
    6557        3076 :     Limit      *node = makeNode(Limit);
    6558        3076 :     Plan       *plan = &node->plan;
    6559             : 
    6560        3076 :     plan->targetlist = lefttree->targetlist;
    6561        3076 :     plan->qual = NIL;
    6562        3076 :     plan->lefttree = lefttree;
    6563        3076 :     plan->righttree = NULL;
    6564             : 
    6565        3076 :     node->limitOffset = limitOffset;
    6566        3076 :     node->limitCount = limitCount;
    6567             : 
    6568        3076 :     return node;
    6569             : }
    6570             : 
    6571             : /*
    6572             :  * make_result
    6573             :  *    Build a Result plan node
    6574             :  */
    6575             : static Result *
    6576      116976 : make_result(List *tlist,
    6577             :             Node *resconstantqual,
    6578             :             Plan *subplan)
    6579             : {
    6580      116976 :     Result     *node = makeNode(Result);
    6581      116976 :     Plan       *plan = &node->plan;
    6582             : 
    6583      116976 :     plan->targetlist = tlist;
    6584      116976 :     plan->qual = NIL;
    6585      116976 :     plan->lefttree = subplan;
    6586      116976 :     plan->righttree = NULL;
    6587      116976 :     node->resconstantqual = resconstantqual;
    6588             : 
    6589      116976 :     return node;
    6590             : }
    6591             : 
    6592             : /*
    6593             :  * make_project_set
    6594             :  *    Build a ProjectSet plan node
    6595             :  */
    6596             : static ProjectSet *
    6597        3686 : make_project_set(List *tlist,
    6598             :                  Plan *subplan)
    6599             : {
    6600        3686 :     ProjectSet *node = makeNode(ProjectSet);
    6601        3686 :     Plan       *plan = &node->plan;
    6602             : 
    6603        3686 :     plan->targetlist = tlist;
    6604        3686 :     plan->qual = NIL;
    6605        3686 :     plan->lefttree = subplan;
    6606        3686 :     plan->righttree = NULL;
    6607             : 
    6608        3686 :     return node;
    6609             : }
    6610             : 
    6611             : /*
    6612             :  * make_modifytable
    6613             :  *    Build a ModifyTable plan node
    6614             :  */
    6615             : static ModifyTable *
    6616       69372 : make_modifytable(PlannerInfo *root,
    6617             :                  CmdType operation, bool canSetTag,
    6618             :                  Index nominalRelation, Index rootRelation,
    6619             :                  bool partColsUpdated,
    6620             :                  List *resultRelations, List *subplans, List *subroots,
    6621             :                  List *withCheckOptionLists, List *returningLists,
    6622             :                  List *rowMarks, OnConflictExpr *onconflict, int epqParam)
    6623             : {
    6624       69372 :     ModifyTable *node = makeNode(ModifyTable);
    6625             :     List       *fdw_private_list;
    6626             :     Bitmapset  *direct_modify_plans;
    6627             :     ListCell   *lc;
    6628             :     ListCell   *lc2;
    6629             :     int         i;
    6630             : 
    6631             :     Assert(list_length(resultRelations) == list_length(subplans));
    6632             :     Assert(list_length(resultRelations) == list_length(subroots));
    6633             :     Assert(withCheckOptionLists == NIL ||
    6634             :            list_length(resultRelations) == list_length(withCheckOptionLists));
    6635             :     Assert(returningLists == NIL ||
    6636             :            list_length(resultRelations) == list_length(returningLists));
    6637             : 
    6638       69372 :     node->plan.lefttree = NULL;
    6639       69372 :     node->plan.righttree = NULL;
    6640       69372 :     node->plan.qual = NIL;
    6641             :     /* setrefs.c will fill in the targetlist, if needed */
    6642       69372 :     node->plan.targetlist = NIL;
    6643             : 
    6644       69372 :     node->operation = operation;
    6645       69372 :     node->canSetTag = canSetTag;
    6646       69372 :     node->nominalRelation = nominalRelation;
    6647       69372 :     node->rootRelation = rootRelation;
    6648       69372 :     node->partColsUpdated = partColsUpdated;
    6649       69372 :     node->resultRelations = resultRelations;
    6650       69372 :     node->resultRelIndex = -1;   /* will be set correctly in setrefs.c */
    6651       69372 :     node->rootResultRelIndex = -1;   /* will be set correctly in setrefs.c */
    6652       69372 :     node->plans = subplans;
    6653       69372 :     if (!onconflict)
    6654             :     {
    6655       68392 :         node->onConflictAction = ONCONFLICT_NONE;
    6656       68392 :         node->onConflictSet = NIL;
    6657       68392 :         node->onConflictWhere = NULL;
    6658       68392 :         node->arbiterIndexes = NIL;
    6659       68392 :         node->exclRelRTI = 0;
    6660       68392 :         node->exclRelTlist = NIL;
    6661             :     }
    6662             :     else
    6663             :     {
    6664         980 :         node->onConflictAction = onconflict->action;
    6665         980 :         node->onConflictSet = onconflict->onConflictSet;
    6666         980 :         node->onConflictWhere = onconflict->onConflictWhere;
    6667             : 
    6668             :         /*
    6669             :          * If a set of unique index inference elements was provided (an
    6670             :          * INSERT...ON CONFLICT "inference specification"), then infer
    6671             :          * appropriate unique indexes (or throw an error if none are
    6672             :          * available).
    6673             :          */
    6674         980 :         node->arbiterIndexes = infer_arbiter_indexes(root);
    6675             : 
    6676         860 :         node->exclRelRTI = onconflict->exclRelIndex;
    6677         860 :         node->exclRelTlist = onconflict->exclRelTlist;
    6678             :     }
    6679       69252 :     node->withCheckOptionLists = withCheckOptionLists;
    6680       69252 :     node->returningLists = returningLists;
    6681       69252 :     node->rowMarks = rowMarks;
    6682       69252 :     node->epqParam = epqParam;
    6683             : 
    6684             :     /*
    6685             :      * For each result relation that is a foreign table, allow the FDW to
    6686             :      * construct private plan data, and accumulate it all into a list.
    6687             :      */
    6688       69252 :     fdw_private_list = NIL;
    6689       69252 :     direct_modify_plans = NULL;
    6690       69252 :     i = 0;
    6691      139674 :     forboth(lc, resultRelations, lc2, subroots)
    6692             :     {
    6693       70422 :         Index       rti = lfirst_int(lc);
    6694       70422 :         PlannerInfo *subroot = lfirst_node(PlannerInfo, lc2);
    6695             :         FdwRoutine *fdwroutine;
    6696             :         List       *fdw_private;
    6697             :         bool        direct_modify;
    6698             : 
    6699             :         /*
    6700             :          * If possible, we want to get the FdwRoutine from our RelOptInfo for
    6701             :          * the table.  But sometimes we don't have a RelOptInfo and must get
    6702             :          * it the hard way.  (In INSERT, the target relation is not scanned,
    6703             :          * so it's not a baserel; and there are also corner cases for
    6704             :          * updatable views where the target rel isn't a baserel.)
    6705             :          */
    6706      140812 :         if (rti < subroot->simple_rel_array_size &&
    6707       70390 :             subroot->simple_rel_array[rti] != NULL)
    6708       13368 :         {
    6709       13368 :             RelOptInfo *resultRel = subroot->simple_rel_array[rti];
    6710             : 
    6711       13368 :             fdwroutine = resultRel->fdwroutine;
    6712             :         }
    6713             :         else
    6714             :         {
    6715       57054 :             RangeTblEntry *rte = planner_rt_fetch(rti, subroot);
    6716             : 
    6717             :             Assert(rte->rtekind == RTE_RELATION);
    6718       57054 :             if (rte->relkind == RELKIND_FOREIGN_TABLE)
    6719          96 :                 fdwroutine = GetFdwRoutineByRelId(rte->relid);
    6720             :             else
    6721       56958 :                 fdwroutine = NULL;
    6722             :         }
    6723             : 
    6724             :         /*
    6725             :          * Try to modify the foreign table directly if (1) the FDW provides
    6726             :          * callback functions needed for that and (2) there are no local
    6727             :          * structures that need to be run for each modified row: row-level
    6728             :          * triggers on the foreign table, stored generated columns, WITH CHECK
    6729             :          * OPTIONs from parent views.
    6730             :          */
    6731       70422 :         direct_modify = false;
    6732       70786 :         if (fdwroutine != NULL &&
    6733         718 :             fdwroutine->PlanDirectModify != NULL &&
    6734         708 :             fdwroutine->BeginDirectModify != NULL &&
    6735         708 :             fdwroutine->IterateDirectModify != NULL &&
    6736         708 :             fdwroutine->EndDirectModify != NULL &&
    6737         330 :             withCheckOptionLists == NIL &&
    6738         594 :             !has_row_triggers(subroot, rti, operation) &&
    6739         264 :             !has_stored_generated_columns(subroot, rti))
    6740         260 :             direct_modify = fdwroutine->PlanDirectModify(subroot, node, rti, i);
    6741       70422 :         if (direct_modify)
    6742         166 :             direct_modify_plans = bms_add_member(direct_modify_plans, i);
    6743             : 
    6744       70422 :         if (!direct_modify &&
    6745         198 :             fdwroutine != NULL &&
    6746         198 :             fdwroutine->PlanForeignModify != NULL)
    6747         188 :             fdw_private = fdwroutine->PlanForeignModify(subroot, node, rti, i);
    6748             :         else
    6749       70234 :             fdw_private = NIL;
    6750       70422 :         fdw_private_list = lappend(fdw_private_list, fdw_private);
    6751       70422 :         i++;
    6752             :     }
    6753       69252 :     node->fdwPrivLists = fdw_private_list;
    6754       69252 :     node->fdwDirectModifyPlans = direct_modify_plans;
    6755             : 
    6756       69252 :     return node;
    6757             : }
    6758             : 
    6759             : /*
    6760             :  * is_projection_capable_path
    6761             :  *      Check whether a given Path node is able to do projection.
    6762             :  */
    6763             : bool
    6764      457230 : is_projection_capable_path(Path *path)
    6765             : {
    6766             :     /* Most plan types can project, so just list the ones that can't */
    6767      457230 :     switch (path->pathtype)
    6768             :     {
    6769             :         case T_Hash:
    6770             :         case T_Material:
    6771             :         case T_Sort:
    6772             :         case T_Unique:
    6773             :         case T_SetOp:
    6774             :         case T_LockRows:
    6775             :         case T_Limit:
    6776             :         case T_ModifyTable:
    6777             :         case T_MergeAppend:
    6778             :         case T_RecursiveUnion:
    6779       18754 :             return false;
    6780             :         case T_Append:
    6781             : 
    6782             :             /*
    6783             :              * Append can't project, but if an AppendPath is being used to
    6784             :              * represent a dummy path, what will actually be generated is a
    6785             :              * Result which can project.
    6786             :              */
    6787        1024 :             return IS_DUMMY_APPEND(path);
    6788             :         case T_ProjectSet:
    6789             : 
    6790             :             /*
    6791             :              * Although ProjectSet certainly projects, say "no" because we
    6792             :              * don't want the planner to randomly replace its tlist with
    6793             :              * something else; the SRFs have to stay at top level.  This might
    6794             :              * get relaxed later.
    6795             :              */
    6796        1860 :             return false;
    6797             :         default:
    6798      435592 :             break;
    6799             :     }
    6800      435592 :     return true;
    6801             : }
    6802             : 
    6803             : /*
    6804             :  * is_projection_capable_plan
    6805             :  *      Check whether a given Plan node is able to do projection.
    6806             :  */
    6807             : bool
    6808         222 : is_projection_capable_plan(Plan *plan)
    6809             : {
    6810             :     /* Most plan types can project, so just list the ones that can't */
    6811         222 :     switch (nodeTag(plan))
    6812             :     {
    6813             :         case T_Hash:
    6814             :         case T_Material:
    6815             :         case T_Sort:
    6816             :         case T_Unique:
    6817             :         case T_SetOp:
    6818             :         case T_LockRows:
    6819             :         case T_Limit:
    6820             :         case T_ModifyTable:
    6821             :         case T_Append:
    6822             :         case T_MergeAppend:
    6823             :         case T_RecursiveUnion:
    6824          22 :             return false;
    6825             :         case T_ProjectSet:
    6826             : 
    6827             :             /*
    6828             :              * Although ProjectSet certainly projects, say "no" because we
    6829             :              * don't want the planner to randomly replace its tlist with
    6830             :              * something else; the SRFs have to stay at top level.  This might
    6831             :              * get relaxed later.
    6832             :              */
    6833           0 :             return false;
    6834             :         default:
    6835         200 :             break;
    6836             :     }
    6837         200 :     return true;
    6838             : }

Generated by: LCOV version 1.13