LCOV - code coverage report
Current view: top level - src/backend/optimizer/path - allpaths.c (source / functions) Coverage Total Hit
Test: PostgreSQL 19devel Lines: 93.9 % 1261 1184
Test Date: 2026-03-14 12:15:02 Functions: 100.0 % 52 52
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /*-------------------------------------------------------------------------
       2              :  *
       3              :  * allpaths.c
       4              :  *    Routines to find possible search paths for processing a query
       5              :  *
       6              :  * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
       7              :  * Portions Copyright (c) 1994, Regents of the University of California
       8              :  *
       9              :  *
      10              :  * IDENTIFICATION
      11              :  *    src/backend/optimizer/path/allpaths.c
      12              :  *
      13              :  *-------------------------------------------------------------------------
      14              :  */
      15              : 
      16              : #include "postgres.h"
      17              : 
      18              : #include <limits.h>
      19              : #include <math.h>
      20              : 
      21              : #include "access/sysattr.h"
      22              : #include "access/tsmapi.h"
      23              : #include "catalog/pg_class.h"
      24              : #include "catalog/pg_operator.h"
      25              : #include "catalog/pg_proc.h"
      26              : #include "foreign/fdwapi.h"
      27              : #include "miscadmin.h"
      28              : #include "nodes/makefuncs.h"
      29              : #include "nodes/nodeFuncs.h"
      30              : #include "nodes/supportnodes.h"
      31              : #ifdef OPTIMIZER_DEBUG
      32              : #include "nodes/print.h"
      33              : #endif
      34              : #include "optimizer/appendinfo.h"
      35              : #include "optimizer/clauses.h"
      36              : #include "optimizer/cost.h"
      37              : #include "optimizer/geqo.h"
      38              : #include "optimizer/optimizer.h"
      39              : #include "optimizer/pathnode.h"
      40              : #include "optimizer/paths.h"
      41              : #include "optimizer/plancat.h"
      42              : #include "optimizer/planner.h"
      43              : #include "optimizer/prep.h"
      44              : #include "optimizer/tlist.h"
      45              : #include "parser/parse_clause.h"
      46              : #include "parser/parsetree.h"
      47              : #include "partitioning/partbounds.h"
      48              : #include "port/pg_bitutils.h"
      49              : #include "rewrite/rewriteManip.h"
      50              : #include "utils/lsyscache.h"
      51              : #include "utils/selfuncs.h"
      52              : 
      53              : 
      54              : /* Bitmask flags for pushdown_safety_info.unsafeFlags */
      55              : #define UNSAFE_HAS_VOLATILE_FUNC        (1 << 0)
      56              : #define UNSAFE_HAS_SET_FUNC             (1 << 1)
      57              : #define UNSAFE_NOTIN_DISTINCTON_CLAUSE  (1 << 2)
      58              : #define UNSAFE_NOTIN_PARTITIONBY_CLAUSE (1 << 3)
      59              : #define UNSAFE_TYPE_MISMATCH            (1 << 4)
      60              : 
      61              : /* results of subquery_is_pushdown_safe */
      62              : typedef struct pushdown_safety_info
      63              : {
      64              :     unsigned char *unsafeFlags; /* bitmask of reasons why this target list
      65              :                                  * column is unsafe for qual pushdown, or 0 if
      66              :                                  * no reason. */
      67              :     bool        unsafeVolatile; /* don't push down volatile quals */
      68              :     bool        unsafeLeaky;    /* don't push down leaky quals */
      69              : } pushdown_safety_info;
      70              : 
      71              : /* Return type for qual_is_pushdown_safe */
      72              : typedef enum pushdown_safe_type
      73              : {
      74              :     PUSHDOWN_UNSAFE,            /* unsafe to push qual into subquery */
      75              :     PUSHDOWN_SAFE,              /* safe to push qual into subquery */
      76              :     PUSHDOWN_WINDOWCLAUSE_RUNCOND,  /* unsafe, but may work as WindowClause
      77              :                                      * run condition */
      78              : } pushdown_safe_type;
      79              : 
      80              : /* These parameters are set by GUC */
      81              : bool        enable_geqo = false;    /* just in case GUC doesn't set it */
      82              : bool        enable_eager_aggregate = true;
      83              : int         geqo_threshold;
      84              : double      min_eager_agg_group_size;
      85              : int         min_parallel_table_scan_size;
      86              : int         min_parallel_index_scan_size;
      87              : 
      88              : /* Hook for plugins to get control in set_rel_pathlist() */
      89              : set_rel_pathlist_hook_type set_rel_pathlist_hook = NULL;
      90              : 
      91              : /* Hook for plugins to replace standard_join_search() */
      92              : join_search_hook_type join_search_hook = NULL;
      93              : 
      94              : 
      95              : static void set_base_rel_consider_startup(PlannerInfo *root);
      96              : static void set_base_rel_sizes(PlannerInfo *root);
      97              : static void setup_simple_grouped_rels(PlannerInfo *root);
      98              : static void set_base_rel_pathlists(PlannerInfo *root);
      99              : static void set_rel_size(PlannerInfo *root, RelOptInfo *rel,
     100              :                          Index rti, RangeTblEntry *rte);
     101              : static void set_rel_pathlist(PlannerInfo *root, RelOptInfo *rel,
     102              :                              Index rti, RangeTblEntry *rte);
     103              : static void set_plain_rel_size(PlannerInfo *root, RelOptInfo *rel,
     104              :                                RangeTblEntry *rte);
     105              : static void create_plain_partial_paths(PlannerInfo *root, RelOptInfo *rel);
     106              : static void set_rel_consider_parallel(PlannerInfo *root, RelOptInfo *rel,
     107              :                                       RangeTblEntry *rte);
     108              : static void set_plain_rel_pathlist(PlannerInfo *root, RelOptInfo *rel,
     109              :                                    RangeTblEntry *rte);
     110              : static void set_tablesample_rel_size(PlannerInfo *root, RelOptInfo *rel,
     111              :                                      RangeTblEntry *rte);
     112              : static void set_tablesample_rel_pathlist(PlannerInfo *root, RelOptInfo *rel,
     113              :                                          RangeTblEntry *rte);
     114              : static void set_foreign_size(PlannerInfo *root, RelOptInfo *rel,
     115              :                              RangeTblEntry *rte);
     116              : static void set_foreign_pathlist(PlannerInfo *root, RelOptInfo *rel,
     117              :                                  RangeTblEntry *rte);
     118              : static void set_append_rel_size(PlannerInfo *root, RelOptInfo *rel,
     119              :                                 Index rti, RangeTblEntry *rte);
     120              : static void set_append_rel_pathlist(PlannerInfo *root, RelOptInfo *rel,
     121              :                                     Index rti, RangeTblEntry *rte);
     122              : static void set_grouped_rel_pathlist(PlannerInfo *root, RelOptInfo *rel);
     123              : static void generate_orderedappend_paths(PlannerInfo *root, RelOptInfo *rel,
     124              :                                          List *live_childrels,
     125              :                                          List *all_child_pathkeys);
     126              : static Path *get_cheapest_parameterized_child_path(PlannerInfo *root,
     127              :                                                    RelOptInfo *rel,
     128              :                                                    Relids required_outer);
     129              : static void accumulate_append_subpath(Path *path,
     130              :                                       List **subpaths,
     131              :                                       List **special_subpaths,
     132              :                                       List **child_append_relid_sets);
     133              : static Path *get_singleton_append_subpath(Path *path,
     134              :                                           List **child_append_relid_sets);
     135              : static void set_dummy_rel_pathlist(RelOptInfo *rel);
     136              : static void set_subquery_pathlist(PlannerInfo *root, RelOptInfo *rel,
     137              :                                   Index rti, RangeTblEntry *rte);
     138              : static void set_function_pathlist(PlannerInfo *root, RelOptInfo *rel,
     139              :                                   RangeTblEntry *rte);
     140              : static void set_values_pathlist(PlannerInfo *root, RelOptInfo *rel,
     141              :                                 RangeTblEntry *rte);
     142              : static void set_tablefunc_pathlist(PlannerInfo *root, RelOptInfo *rel,
     143              :                                    RangeTblEntry *rte);
     144              : static void set_cte_pathlist(PlannerInfo *root, RelOptInfo *rel,
     145              :                              RangeTblEntry *rte);
     146              : static void set_namedtuplestore_pathlist(PlannerInfo *root, RelOptInfo *rel,
     147              :                                          RangeTblEntry *rte);
     148              : static void set_result_pathlist(PlannerInfo *root, RelOptInfo *rel,
     149              :                                 RangeTblEntry *rte);
     150              : static void set_worktable_pathlist(PlannerInfo *root, RelOptInfo *rel,
     151              :                                    RangeTblEntry *rte);
     152              : static RelOptInfo *make_rel_from_joinlist(PlannerInfo *root, List *joinlist);
     153              : static bool subquery_is_pushdown_safe(Query *subquery, Query *topquery,
     154              :                                       pushdown_safety_info *safetyInfo);
     155              : static bool recurse_pushdown_safe(Node *setOp, Query *topquery,
     156              :                                   pushdown_safety_info *safetyInfo);
     157              : static void check_output_expressions(Query *subquery,
     158              :                                      pushdown_safety_info *safetyInfo);
     159              : static void compare_tlist_datatypes(List *tlist, List *colTypes,
     160              :                                     pushdown_safety_info *safetyInfo);
     161              : static bool targetIsInAllPartitionLists(TargetEntry *tle, Query *query);
     162              : static pushdown_safe_type qual_is_pushdown_safe(Query *subquery, Index rti,
     163              :                                                 RestrictInfo *rinfo,
     164              :                                                 pushdown_safety_info *safetyInfo);
     165              : static void subquery_push_qual(Query *subquery,
     166              :                                RangeTblEntry *rte, Index rti, Node *qual);
     167              : static void recurse_push_qual(Node *setOp, Query *topquery,
     168              :                               RangeTblEntry *rte, Index rti, Node *qual);
     169              : static void remove_unused_subquery_outputs(Query *subquery, RelOptInfo *rel,
     170              :                                            Bitmapset *extra_used_attrs);
     171              : 
     172              : 
     173              : /*
     174              :  * make_one_rel
     175              :  *    Finds all possible access paths for executing a query, returning a
     176              :  *    single rel that represents the join of all base rels in the query.
     177              :  */
     178              : RelOptInfo *
     179       182975 : make_one_rel(PlannerInfo *root, List *joinlist)
     180              : {
     181              :     RelOptInfo *rel;
     182              :     Index       rti;
     183              :     double      total_pages;
     184              : 
     185              :     /* Mark base rels as to whether we care about fast-start plans */
     186       182975 :     set_base_rel_consider_startup(root);
     187              : 
     188              :     /*
     189              :      * Compute size estimates and consider_parallel flags for each base rel.
     190              :      */
     191       182975 :     set_base_rel_sizes(root);
     192              : 
     193              :     /*
     194              :      * Build grouped relations for simple rels (i.e., base or "other" member
     195              :      * relations) where possible.
     196              :      */
     197       182958 :     setup_simple_grouped_rels(root);
     198              : 
     199              :     /*
     200              :      * We should now have size estimates for every actual table involved in
     201              :      * the query, and we also know which if any have been deleted from the
     202              :      * query by join removal, pruned by partition pruning, or eliminated by
     203              :      * constraint exclusion.  So we can now compute total_table_pages.
     204              :      *
     205              :      * Note that appendrels are not double-counted here, even though we don't
     206              :      * bother to distinguish RelOptInfos for appendrel parents, because the
     207              :      * parents will have pages = 0.
     208              :      *
     209              :      * XXX if a table is self-joined, we will count it once per appearance,
     210              :      * which perhaps is the wrong thing ... but that's not completely clear,
     211              :      * and detecting self-joins here is difficult, so ignore it for now.
     212              :      */
     213       182958 :     total_pages = 0;
     214       568100 :     for (rti = 1; rti < root->simple_rel_array_size; rti++)
     215              :     {
     216       385142 :         RelOptInfo *brel = root->simple_rel_array[rti];
     217              : 
     218              :         /* there may be empty slots corresponding to non-baserel RTEs */
     219       385142 :         if (brel == NULL)
     220        91496 :             continue;
     221              : 
     222              :         Assert(brel->relid == rti); /* sanity check on array */
     223              : 
     224       293646 :         if (IS_DUMMY_REL(brel))
     225          748 :             continue;
     226              : 
     227       292898 :         if (IS_SIMPLE_REL(brel))
     228       292898 :             total_pages += (double) brel->pages;
     229              :     }
     230       182958 :     root->total_table_pages = total_pages;
     231              : 
     232              :     /*
     233              :      * Generate access paths for each base rel.
     234              :      */
     235       182958 :     set_base_rel_pathlists(root);
     236              : 
     237              :     /*
     238              :      * Generate access paths for the entire join tree.
     239              :      */
     240       182958 :     rel = make_rel_from_joinlist(root, joinlist);
     241              : 
     242              :     /*
     243              :      * The result should join all and only the query's base + outer-join rels.
     244              :      */
     245              :     Assert(bms_equal(rel->relids, root->all_query_rels));
     246              : 
     247       182958 :     return rel;
     248              : }
     249              : 
     250              : /*
     251              :  * set_base_rel_consider_startup
     252              :  *    Set the consider_[param_]startup flags for each base-relation entry.
     253              :  *
     254              :  * For the moment, we only deal with consider_param_startup here; because the
     255              :  * logic for consider_startup is pretty trivial and is the same for every base
     256              :  * relation, we just let build_simple_rel() initialize that flag correctly to
     257              :  * start with.  If that logic ever gets more complicated it would probably
     258              :  * be better to move it here.
     259              :  */
     260              : static void
     261       182975 : set_base_rel_consider_startup(PlannerInfo *root)
     262              : {
     263              :     /*
     264              :      * Since parameterized paths can only be used on the inside of a nestloop
     265              :      * join plan, there is usually little value in considering fast-start
     266              :      * plans for them.  However, for relations that are on the RHS of a SEMI
     267              :      * or ANTI join, a fast-start plan can be useful because we're only going
     268              :      * to care about fetching one tuple anyway.
     269              :      *
     270              :      * To minimize growth of planning time, we currently restrict this to
     271              :      * cases where the RHS is a single base relation, not a join; there is no
     272              :      * provision for consider_param_startup to get set at all on joinrels.
     273              :      * Also we don't worry about appendrels.  costsize.c's costing rules for
     274              :      * nestloop semi/antijoins don't consider such cases either.
     275              :      */
     276              :     ListCell   *lc;
     277              : 
     278       207814 :     foreach(lc, root->join_info_list)
     279              :     {
     280        24839 :         SpecialJoinInfo *sjinfo = (SpecialJoinInfo *) lfirst(lc);
     281              :         int         varno;
     282              : 
     283        30984 :         if ((sjinfo->jointype == JOIN_SEMI || sjinfo->jointype == JOIN_ANTI) &&
     284         6145 :             bms_get_singleton_member(sjinfo->syn_righthand, &varno))
     285              :         {
     286         6030 :             RelOptInfo *rel = find_base_rel(root, varno);
     287              : 
     288         6030 :             rel->consider_param_startup = true;
     289              :         }
     290              :     }
     291       182975 : }
     292              : 
     293              : /*
     294              :  * set_base_rel_sizes
     295              :  *    Set the size estimates (rows and widths) for each base-relation entry.
     296              :  *    Also determine whether to consider parallel paths for base relations.
     297              :  *
     298              :  * We do this in a separate pass over the base rels so that rowcount
     299              :  * estimates are available for parameterized path generation, and also so
     300              :  * that each rel's consider_parallel flag is set correctly before we begin to
     301              :  * generate paths.
     302              :  */
     303              : static void
     304       182975 : set_base_rel_sizes(PlannerInfo *root)
     305              : {
     306              :     Index       rti;
     307              : 
     308       568118 :     for (rti = 1; rti < root->simple_rel_array_size; rti++)
     309              :     {
     310       385160 :         RelOptInfo *rel = root->simple_rel_array[rti];
     311              :         RangeTblEntry *rte;
     312              : 
     313              :         /* there may be empty slots corresponding to non-baserel RTEs */
     314       385160 :         if (rel == NULL)
     315        91497 :             continue;
     316              : 
     317              :         Assert(rel->relid == rti);   /* sanity check on array */
     318              : 
     319              :         /* ignore RTEs that are "other rels" */
     320       293663 :         if (rel->reloptkind != RELOPT_BASEREL)
     321        30862 :             continue;
     322              : 
     323       262801 :         rte = root->simple_rte_array[rti];
     324              : 
     325              :         /*
     326              :          * If parallelism is allowable for this query in general, see whether
     327              :          * it's allowable for this rel in particular.  We have to do this
     328              :          * before set_rel_size(), because (a) if this rel is an inheritance
     329              :          * parent, set_append_rel_size() will use and perhaps change the rel's
     330              :          * consider_parallel flag, and (b) for some RTE types, set_rel_size()
     331              :          * goes ahead and makes paths immediately.
     332              :          */
     333       262801 :         if (root->glob->parallelModeOK)
     334       208579 :             set_rel_consider_parallel(root, rel, rte);
     335              : 
     336       262801 :         set_rel_size(root, rel, rti, rte);
     337              :     }
     338       182958 : }
     339              : 
     340              : /*
     341              :  * setup_simple_grouped_rels
     342              :  *    For each simple relation, build a grouped simple relation if eager
     343              :  *    aggregation is possible and if this relation can produce grouped paths.
     344              :  */
     345              : static void
     346       182958 : setup_simple_grouped_rels(PlannerInfo *root)
     347              : {
     348              :     Index       rti;
     349              : 
     350              :     /*
     351              :      * If there are no aggregate expressions or grouping expressions, eager
     352              :      * aggregation is not possible.
     353              :      */
     354       182958 :     if (root->agg_clause_list == NIL ||
     355          329 :         root->group_expr_list == NIL)
     356       182662 :         return;
     357              : 
     358         2537 :     for (rti = 1; rti < root->simple_rel_array_size; rti++)
     359              :     {
     360         2241 :         RelOptInfo *rel = root->simple_rel_array[rti];
     361              : 
     362              :         /* there may be empty slots corresponding to non-baserel RTEs */
     363         2241 :         if (rel == NULL)
     364          707 :             continue;
     365              : 
     366              :         Assert(rel->relid == rti);   /* sanity check on array */
     367              :         Assert(IS_SIMPLE_REL(rel)); /* sanity check on rel */
     368              : 
     369         1534 :         (void) build_simple_grouped_rel(root, rel);
     370              :     }
     371              : }
     372              : 
     373              : /*
     374              :  * set_base_rel_pathlists
     375              :  *    Finds all paths available for scanning each base-relation entry.
     376              :  *    Sequential scan and any available indices are considered.
     377              :  *    Each useful path is attached to its relation's 'pathlist' field.
     378              :  */
     379              : static void
     380       182958 : set_base_rel_pathlists(PlannerInfo *root)
     381              : {
     382              :     Index       rti;
     383              : 
     384       568100 :     for (rti = 1; rti < root->simple_rel_array_size; rti++)
     385              :     {
     386       385142 :         RelOptInfo *rel = root->simple_rel_array[rti];
     387              : 
     388              :         /* there may be empty slots corresponding to non-baserel RTEs */
     389       385142 :         if (rel == NULL)
     390        91496 :             continue;
     391              : 
     392              :         Assert(rel->relid == rti);   /* sanity check on array */
     393              : 
     394              :         /* ignore RTEs that are "other rels" */
     395       293646 :         if (rel->reloptkind != RELOPT_BASEREL)
     396        30862 :             continue;
     397              : 
     398       262784 :         set_rel_pathlist(root, rel, rti, root->simple_rte_array[rti]);
     399              :     }
     400       182958 : }
     401              : 
     402              : /*
     403              :  * set_rel_size
     404              :  *    Set size estimates for a base relation
     405              :  */
     406              : static void
     407       293502 : set_rel_size(PlannerInfo *root, RelOptInfo *rel,
     408              :              Index rti, RangeTblEntry *rte)
     409              : {
     410       556303 :     if (rel->reloptkind == RELOPT_BASEREL &&
     411       262801 :         relation_excluded_by_constraints(root, rel, rte))
     412              :     {
     413              :         /*
     414              :          * We proved we don't need to scan the rel via constraint exclusion,
     415              :          * so set up a single dummy path for it.  Here we only check this for
     416              :          * regular baserels; if it's an otherrel, CE was already checked in
     417              :          * set_append_rel_size().
     418              :          *
     419              :          * In this case, we go ahead and set up the relation's path right away
     420              :          * instead of leaving it for set_rel_pathlist to do.  This is because
     421              :          * we don't have a convention for marking a rel as dummy except by
     422              :          * assigning a dummy path to it.
     423              :          */
     424          371 :         set_dummy_rel_pathlist(rel);
     425              :     }
     426       293131 :     else if (rte->inh)
     427              :     {
     428              :         /* It's an "append relation", process accordingly */
     429        13311 :         set_append_rel_size(root, rel, rti, rte);
     430              :     }
     431              :     else
     432              :     {
     433       279820 :         switch (rel->rtekind)
     434              :         {
     435       229039 :             case RTE_RELATION:
     436       229039 :                 if (rte->relkind == RELKIND_FOREIGN_TABLE)
     437              :                 {
     438              :                     /* Foreign table */
     439         1237 :                     set_foreign_size(root, rel, rte);
     440              :                 }
     441       227802 :                 else if (rte->relkind == RELKIND_PARTITIONED_TABLE)
     442              :                 {
     443              :                     /*
     444              :                      * We could get here if asked to scan a partitioned table
     445              :                      * with ONLY.  In that case we shouldn't scan any of the
     446              :                      * partitions, so mark it as a dummy rel.
     447              :                      */
     448           20 :                     set_dummy_rel_pathlist(rel);
     449              :                 }
     450       227782 :                 else if (rte->tablesample != NULL)
     451              :                 {
     452              :                     /* Sampled relation */
     453          153 :                     set_tablesample_rel_size(root, rel, rte);
     454              :                 }
     455              :                 else
     456              :                 {
     457              :                     /* Plain relation */
     458       227629 :                     set_plain_rel_size(root, rel, rte);
     459              :                 }
     460       229022 :                 break;
     461        13383 :             case RTE_SUBQUERY:
     462              : 
     463              :                 /*
     464              :                  * Subqueries don't support making a choice between
     465              :                  * parameterized and unparameterized paths, so just go ahead
     466              :                  * and build their paths immediately.
     467              :                  */
     468        13383 :                 set_subquery_pathlist(root, rel, rti, rte);
     469        13383 :                 break;
     470        27429 :             case RTE_FUNCTION:
     471        27429 :                 set_function_size_estimates(root, rel);
     472        27429 :                 break;
     473          313 :             case RTE_TABLEFUNC:
     474          313 :                 set_tablefunc_size_estimates(root, rel);
     475          313 :                 break;
     476         4329 :             case RTE_VALUES:
     477         4329 :                 set_values_size_estimates(root, rel);
     478         4329 :                 break;
     479         2918 :             case RTE_CTE:
     480              : 
     481              :                 /*
     482              :                  * CTEs don't support making a choice between parameterized
     483              :                  * and unparameterized paths, so just go ahead and build their
     484              :                  * paths immediately.
     485              :                  */
     486         2918 :                 if (rte->self_reference)
     487          540 :                     set_worktable_pathlist(root, rel, rte);
     488              :                 else
     489         2378 :                     set_cte_pathlist(root, rel, rte);
     490         2918 :                 break;
     491          237 :             case RTE_NAMEDTUPLESTORE:
     492              :                 /* Might as well just build the path immediately */
     493          237 :                 set_namedtuplestore_pathlist(root, rel, rte);
     494          237 :                 break;
     495         2172 :             case RTE_RESULT:
     496              :                 /* Might as well just build the path immediately */
     497         2172 :                 set_result_pathlist(root, rel, rte);
     498         2172 :                 break;
     499            0 :             default:
     500            0 :                 elog(ERROR, "unexpected rtekind: %d", (int) rel->rtekind);
     501              :                 break;
     502              :         }
     503              :     }
     504              : 
     505              :     /*
     506              :      * We insist that all non-dummy rels have a nonzero rowcount estimate.
     507              :      */
     508              :     Assert(rel->rows > 0 || IS_DUMMY_REL(rel));
     509       293484 : }
     510              : 
     511              : /*
     512              :  * set_rel_pathlist
     513              :  *    Build access paths for a base relation
     514              :  */
     515              : static void
     516       293556 : set_rel_pathlist(PlannerInfo *root, RelOptInfo *rel,
     517              :                  Index rti, RangeTblEntry *rte)
     518              : {
     519       293556 :     if (IS_DUMMY_REL(rel))
     520              :     {
     521              :         /* We already proved the relation empty, so nothing more to do */
     522              :     }
     523       292880 :     else if (rte->inh)
     524              :     {
     525              :         /* It's an "append relation", process accordingly */
     526        13160 :         set_append_rel_pathlist(root, rel, rti, rte);
     527              :     }
     528              :     else
     529              :     {
     530       279720 :         switch (rel->rtekind)
     531              :         {
     532       229002 :             case RTE_RELATION:
     533       229002 :                 if (rte->relkind == RELKIND_FOREIGN_TABLE)
     534              :                 {
     535              :                     /* Foreign table */
     536         1235 :                     set_foreign_pathlist(root, rel, rte);
     537              :                 }
     538       227767 :                 else if (rte->tablesample != NULL)
     539              :                 {
     540              :                     /* Sampled relation */
     541          153 :                     set_tablesample_rel_pathlist(root, rel, rte);
     542              :                 }
     543              :                 else
     544              :                 {
     545              :                     /* Plain relation */
     546       227614 :                     set_plain_rel_pathlist(root, rel, rte);
     547              :                 }
     548       229002 :                 break;
     549        13320 :             case RTE_SUBQUERY:
     550              :                 /* Subquery --- fully handled during set_rel_size */
     551        13320 :                 break;
     552        27429 :             case RTE_FUNCTION:
     553              :                 /* RangeFunction */
     554        27429 :                 set_function_pathlist(root, rel, rte);
     555        27429 :                 break;
     556          313 :             case RTE_TABLEFUNC:
     557              :                 /* Table Function */
     558          313 :                 set_tablefunc_pathlist(root, rel, rte);
     559          313 :                 break;
     560         4329 :             case RTE_VALUES:
     561              :                 /* Values list */
     562         4329 :                 set_values_pathlist(root, rel, rte);
     563         4329 :                 break;
     564         2918 :             case RTE_CTE:
     565              :                 /* CTE reference --- fully handled during set_rel_size */
     566         2918 :                 break;
     567          237 :             case RTE_NAMEDTUPLESTORE:
     568              :                 /* tuplestore reference --- fully handled during set_rel_size */
     569          237 :                 break;
     570         2172 :             case RTE_RESULT:
     571              :                 /* simple Result --- fully handled during set_rel_size */
     572         2172 :                 break;
     573            0 :             default:
     574            0 :                 elog(ERROR, "unexpected rtekind: %d", (int) rel->rtekind);
     575              :                 break;
     576              :         }
     577              :     }
     578              : 
     579              :     /*
     580              :      * Allow a plugin to editorialize on the set of Paths for this base
     581              :      * relation.  It could add new paths (such as CustomPaths) by calling
     582              :      * add_path(), or add_partial_path() if parallel aware.  It could also
     583              :      * delete or modify paths added by the core code.
     584              :      */
     585       293556 :     if (set_rel_pathlist_hook)
     586            0 :         (*set_rel_pathlist_hook) (root, rel, rti, rte);
     587              : 
     588              :     /*
     589              :      * If this is a baserel, we should normally consider gathering any partial
     590              :      * paths we may have created for it.  We have to do this after calling the
     591              :      * set_rel_pathlist_hook, else it cannot add partial paths to be included
     592              :      * here.
     593              :      *
     594              :      * However, if this is an inheritance child, skip it.  Otherwise, we could
     595              :      * end up with a very large number of gather nodes, each trying to grab
     596              :      * its own pool of workers.  Instead, we'll consider gathering partial
     597              :      * paths for the parent appendrel.
     598              :      *
     599              :      * Also, if this is the topmost scan/join rel, we postpone gathering until
     600              :      * the final scan/join targetlist is available (see grouping_planner).
     601              :      */
     602       293556 :     if (rel->reloptkind == RELOPT_BASEREL &&
     603       262784 :         !bms_equal(rel->relids, root->all_query_rels))
     604       137408 :         generate_useful_gather_paths(root, rel, false);
     605              : 
     606              :     /* Now find the cheapest of the paths for this rel */
     607       293556 :     set_cheapest(rel);
     608              : 
     609              :     /*
     610              :      * If a grouped relation for this rel exists, build partial aggregation
     611              :      * paths for it.
     612              :      *
     613              :      * Note that this can only happen after we've called set_cheapest() for
     614              :      * this base rel, because we need its cheapest paths.
     615              :      */
     616       293556 :     set_grouped_rel_pathlist(root, rel);
     617              : 
     618              : #ifdef OPTIMIZER_DEBUG
     619              :     pprint(rel);
     620              : #endif
     621       293556 : }
     622              : 
     623              : /*
     624              :  * set_plain_rel_size
     625              :  *    Set size estimates for a plain relation (no subquery, no inheritance)
     626              :  */
     627              : static void
     628       227629 : set_plain_rel_size(PlannerInfo *root, RelOptInfo *rel, RangeTblEntry *rte)
     629              : {
     630              :     /*
     631              :      * Test any partial indexes of rel for applicability.  We must do this
     632              :      * first since partial unique indexes can affect size estimates.
     633              :      */
     634       227629 :     check_index_predicates(root, rel);
     635              : 
     636              :     /* Mark rel with estimated output rows, width, etc */
     637       227629 :     set_baserel_size_estimates(root, rel);
     638       227614 : }
     639              : 
     640              : /*
     641              :  * If this relation could possibly be scanned from within a worker, then set
     642              :  * its consider_parallel flag.
     643              :  */
     644              : static void
     645       231777 : set_rel_consider_parallel(PlannerInfo *root, RelOptInfo *rel,
     646              :                           RangeTblEntry *rte)
     647              : {
     648              :     /*
     649              :      * The flag has previously been initialized to false, so we can just
     650              :      * return if it becomes clear that we can't safely set it.
     651              :      */
     652              :     Assert(!rel->consider_parallel);
     653              : 
     654              :     /* Don't call this if parallelism is disallowed for the entire query. */
     655              :     Assert(root->glob->parallelModeOK);
     656              : 
     657              :     /* This should only be called for baserels and appendrel children. */
     658              :     Assert(IS_SIMPLE_REL(rel));
     659              : 
     660              :     /* Assorted checks based on rtekind. */
     661       231777 :     switch (rte->rtekind)
     662              :     {
     663       198832 :         case RTE_RELATION:
     664              : 
     665              :             /*
     666              :              * Currently, parallel workers can't access the leader's temporary
     667              :              * tables.  We could possibly relax this if we wrote all of its
     668              :              * local buffers at the start of the query and made no changes
     669              :              * thereafter (maybe we could allow hint bit changes), and if we
     670              :              * taught the workers to read them.  Writing a large number of
     671              :              * temporary buffers could be expensive, though, and we don't have
     672              :              * the rest of the necessary infrastructure right now anyway.  So
     673              :              * for now, bail out if we see a temporary table.
     674              :              */
     675       198832 :             if (get_rel_persistence(rte->relid) == RELPERSISTENCE_TEMP)
     676         4540 :                 return;
     677              : 
     678              :             /*
     679              :              * Table sampling can be pushed down to workers if the sample
     680              :              * function and its arguments are safe.
     681              :              */
     682       194292 :             if (rte->tablesample != NULL)
     683              :             {
     684          165 :                 char        proparallel = func_parallel(rte->tablesample->tsmhandler);
     685              : 
     686          165 :                 if (proparallel != PROPARALLEL_SAFE)
     687           18 :                     return;
     688          147 :                 if (!is_parallel_safe(root, (Node *) rte->tablesample->args))
     689            6 :                     return;
     690              :             }
     691              : 
     692              :             /*
     693              :              * Ask FDWs whether they can support performing a ForeignScan
     694              :              * within a worker.  Most often, the answer will be no.  For
     695              :              * example, if the nature of the FDW is such that it opens a TCP
     696              :              * connection with a remote server, each parallel worker would end
     697              :              * up with a separate connection, and these connections might not
     698              :              * be appropriately coordinated between workers and the leader.
     699              :              */
     700       194268 :             if (rte->relkind == RELKIND_FOREIGN_TABLE)
     701              :             {
     702              :                 Assert(rel->fdwroutine);
     703          782 :                 if (!rel->fdwroutine->IsForeignScanParallelSafe)
     704          744 :                     return;
     705           38 :                 if (!rel->fdwroutine->IsForeignScanParallelSafe(root, rel, rte))
     706            0 :                     return;
     707              :             }
     708              : 
     709              :             /*
     710              :              * There are additional considerations for appendrels, which we'll
     711              :              * deal with in set_append_rel_size and set_append_rel_pathlist.
     712              :              * For now, just set consider_parallel based on the rel's own
     713              :              * quals and targetlist.
     714              :              */
     715       193524 :             break;
     716              : 
     717        11530 :         case RTE_SUBQUERY:
     718              : 
     719              :             /*
     720              :              * There's no intrinsic problem with scanning a subquery-in-FROM
     721              :              * (as distinct from a SubPlan or InitPlan) in a parallel worker.
     722              :              * If the subquery doesn't happen to have any parallel-safe paths,
     723              :              * then flagging it as consider_parallel won't change anything,
     724              :              * but that's true for plain tables, too.  We must set
     725              :              * consider_parallel based on the rel's own quals and targetlist,
     726              :              * so that if a subquery path is parallel-safe but the quals and
     727              :              * projection we're sticking onto it are not, we correctly mark
     728              :              * the SubqueryScanPath as not parallel-safe.  (Note that
     729              :              * set_subquery_pathlist() might push some of these quals down
     730              :              * into the subquery itself, but that doesn't change anything.)
     731              :              *
     732              :              * We can't push sub-select containing LIMIT/OFFSET to workers as
     733              :              * there is no guarantee that the row order will be fully
     734              :              * deterministic, and applying LIMIT/OFFSET will lead to
     735              :              * inconsistent results at the top-level.  (In some cases, where
     736              :              * the result is ordered, we could relax this restriction.  But it
     737              :              * doesn't currently seem worth expending extra effort to do so.)
     738              :              */
     739              :             {
     740        11530 :                 Query      *subquery = castNode(Query, rte->subquery);
     741              : 
     742        11530 :                 if (limit_needed(subquery))
     743          256 :                     return;
     744              :             }
     745        11274 :             break;
     746              : 
     747            0 :         case RTE_JOIN:
     748              :             /* Shouldn't happen; we're only considering baserels here. */
     749              :             Assert(false);
     750            0 :             return;
     751              : 
     752        15193 :         case RTE_FUNCTION:
     753              :             /* Check for parallel-restricted functions. */
     754        15193 :             if (!is_parallel_safe(root, (Node *) rte->functions))
     755         6849 :                 return;
     756         8344 :             break;
     757              : 
     758          313 :         case RTE_TABLEFUNC:
     759              :             /* not parallel safe */
     760          313 :             return;
     761              : 
     762         1444 :         case RTE_VALUES:
     763              :             /* Check for parallel-restricted functions. */
     764         1444 :             if (!is_parallel_safe(root, (Node *) rte->values_lists))
     765            6 :                 return;
     766         1438 :             break;
     767              : 
     768         2296 :         case RTE_CTE:
     769              : 
     770              :             /*
     771              :              * CTE tuplestores aren't shared among parallel workers, so we
     772              :              * force all CTE scans to happen in the leader.  Also, populating
     773              :              * the CTE would require executing a subplan that's not available
     774              :              * in the worker, might be parallel-restricted, and must get
     775              :              * executed only once.
     776              :              */
     777         2296 :             return;
     778              : 
     779          223 :         case RTE_NAMEDTUPLESTORE:
     780              : 
     781              :             /*
     782              :              * tuplestore cannot be shared, at least without more
     783              :              * infrastructure to support that.
     784              :              */
     785          223 :             return;
     786              : 
     787         1946 :         case RTE_RESULT:
     788              :             /* RESULT RTEs, in themselves, are no problem. */
     789         1946 :             break;
     790            0 :         case RTE_GROUP:
     791              :             /* Shouldn't happen; we're only considering baserels here. */
     792              :             Assert(false);
     793            0 :             return;
     794              :     }
     795              : 
     796              :     /*
     797              :      * If there's anything in baserestrictinfo that's parallel-restricted, we
     798              :      * give up on parallelizing access to this relation.  We could consider
     799              :      * instead postponing application of the restricted quals until we're
     800              :      * above all the parallelism in the plan tree, but it's not clear that
     801              :      * that would be a win in very many cases, and it might be tricky to make
     802              :      * outer join clauses work correctly.  It would likely break equivalence
     803              :      * classes, too.
     804              :      */
     805       216526 :     if (!is_parallel_safe(root, (Node *) rel->baserestrictinfo))
     806        15079 :         return;
     807              : 
     808              :     /*
     809              :      * Likewise, if the relation's outputs are not parallel-safe, give up.
     810              :      * (Usually, they're just Vars, but sometimes they're not.)
     811              :      */
     812       201447 :     if (!is_parallel_safe(root, (Node *) rel->reltarget->exprs))
     813            9 :         return;
     814              : 
     815              :     /* We have a winner. */
     816       201438 :     rel->consider_parallel = true;
     817              : }
     818              : 
     819              : /*
     820              :  * set_plain_rel_pathlist
     821              :  *    Build access paths for a plain relation (no subquery, no inheritance)
     822              :  */
     823              : static void
     824       227614 : set_plain_rel_pathlist(PlannerInfo *root, RelOptInfo *rel, RangeTblEntry *rte)
     825              : {
     826              :     Relids      required_outer;
     827              : 
     828              :     /*
     829              :      * We don't support pushing join clauses into the quals of a seqscan, but
     830              :      * it could still have required parameterization due to LATERAL refs in
     831              :      * its tlist.
     832              :      */
     833       227614 :     required_outer = rel->lateral_relids;
     834              : 
     835              :     /*
     836              :      * Consider TID scans.
     837              :      *
     838              :      * If create_tidscan_paths returns true, then a TID scan path is forced.
     839              :      * This happens when rel->baserestrictinfo contains CurrentOfExpr, because
     840              :      * the executor can't handle any other type of path for such queries.
     841              :      * Hence, we return without adding any other paths.
     842              :      */
     843       227614 :     if (create_tidscan_paths(root, rel))
     844          202 :         return;
     845              : 
     846              :     /* Consider sequential scan */
     847       227412 :     add_path(rel, create_seqscan_path(root, rel, required_outer, 0));
     848              : 
     849              :     /* If appropriate, consider parallel sequential scan */
     850       227412 :     if (rel->consider_parallel && required_outer == NULL)
     851       171513 :         create_plain_partial_paths(root, rel);
     852              : 
     853              :     /* Consider index scans */
     854       227412 :     create_index_paths(root, rel);
     855              : }
     856              : 
     857              : /*
     858              :  * create_plain_partial_paths
     859              :  *    Build partial access paths for parallel scan of a plain relation
     860              :  */
     861              : static void
     862       171513 : create_plain_partial_paths(PlannerInfo *root, RelOptInfo *rel)
     863              : {
     864              :     int         parallel_workers;
     865              : 
     866       171513 :     parallel_workers = compute_parallel_worker(rel, rel->pages, -1,
     867              :                                                max_parallel_workers_per_gather);
     868              : 
     869              :     /* If any limit was set to zero, the user doesn't want a parallel scan. */
     870       171513 :     if (parallel_workers <= 0)
     871       156897 :         return;
     872              : 
     873              :     /* Add an unordered partial path based on a parallel sequential scan. */
     874        14616 :     add_partial_path(rel, create_seqscan_path(root, rel, NULL, parallel_workers));
     875              : }
     876              : 
     877              : /*
     878              :  * set_tablesample_rel_size
     879              :  *    Set size estimates for a sampled relation
     880              :  */
     881              : static void
     882          153 : set_tablesample_rel_size(PlannerInfo *root, RelOptInfo *rel, RangeTblEntry *rte)
     883              : {
     884          153 :     TableSampleClause *tsc = rte->tablesample;
     885              :     TsmRoutine *tsm;
     886              :     BlockNumber pages;
     887              :     double      tuples;
     888              : 
     889              :     /*
     890              :      * Test any partial indexes of rel for applicability.  We must do this
     891              :      * first since partial unique indexes can affect size estimates.
     892              :      */
     893          153 :     check_index_predicates(root, rel);
     894              : 
     895              :     /*
     896              :      * Call the sampling method's estimation function to estimate the number
     897              :      * of pages it will read and the number of tuples it will return.  (Note:
     898              :      * we assume the function returns sane values.)
     899              :      */
     900          153 :     tsm = GetTsmRoutine(tsc->tsmhandler);
     901          153 :     tsm->SampleScanGetSampleSize(root, rel, tsc->args,
     902              :                                  &pages, &tuples);
     903              : 
     904              :     /*
     905              :      * For the moment, because we will only consider a SampleScan path for the
     906              :      * rel, it's okay to just overwrite the pages and tuples estimates for the
     907              :      * whole relation.  If we ever consider multiple path types for sampled
     908              :      * rels, we'll need more complication.
     909              :      */
     910          153 :     rel->pages = pages;
     911          153 :     rel->tuples = tuples;
     912              : 
     913              :     /* Mark rel with estimated output rows, width, etc */
     914          153 :     set_baserel_size_estimates(root, rel);
     915          153 : }
     916              : 
     917              : /*
     918              :  * set_tablesample_rel_pathlist
     919              :  *    Build access paths for a sampled relation
     920              :  */
     921              : static void
     922          153 : set_tablesample_rel_pathlist(PlannerInfo *root, RelOptInfo *rel, RangeTblEntry *rte)
     923              : {
     924              :     Relids      required_outer;
     925              :     Path       *path;
     926              : 
     927              :     /*
     928              :      * We don't support pushing join clauses into the quals of a samplescan,
     929              :      * but it could still have required parameterization due to LATERAL refs
     930              :      * in its tlist or TABLESAMPLE arguments.
     931              :      */
     932          153 :     required_outer = rel->lateral_relids;
     933              : 
     934              :     /* Consider sampled scan */
     935          153 :     path = create_samplescan_path(root, rel, required_outer);
     936              : 
     937              :     /*
     938              :      * If the sampling method does not support repeatable scans, we must avoid
     939              :      * plans that would scan the rel multiple times.  Ideally, we'd simply
     940              :      * avoid putting the rel on the inside of a nestloop join; but adding such
     941              :      * a consideration to the planner seems like a great deal of complication
     942              :      * to support an uncommon usage of second-rate sampling methods.  Instead,
     943              :      * if there is a risk that the query might perform an unsafe join, just
     944              :      * wrap the SampleScan in a Materialize node.  We can check for joins by
     945              :      * counting the membership of all_query_rels (note that this correctly
     946              :      * counts inheritance trees as single rels).  If we're inside a subquery,
     947              :      * we can't easily check whether a join might occur in the outer query, so
     948              :      * just assume one is possible.
     949              :      *
     950              :      * GetTsmRoutine is relatively expensive compared to the other tests here,
     951              :      * so check repeatable_across_scans last, even though that's a bit odd.
     952              :      */
     953          293 :     if ((root->query_level > 1 ||
     954          140 :          bms_membership(root->all_query_rels) != BMS_SINGLETON) &&
     955           49 :         !(GetTsmRoutine(rte->tablesample->tsmhandler)->repeatable_across_scans))
     956              :     {
     957            4 :         path = (Path *) create_material_path(rel, path, true);
     958              :     }
     959              : 
     960          153 :     add_path(rel, path);
     961              : 
     962              :     /* For the moment, at least, there are no other paths to consider */
     963          153 : }
     964              : 
     965              : /*
     966              :  * set_foreign_size
     967              :  *      Set size estimates for a foreign table RTE
     968              :  */
     969              : static void
     970         1237 : set_foreign_size(PlannerInfo *root, RelOptInfo *rel, RangeTblEntry *rte)
     971              : {
     972              :     /* Mark rel with estimated output rows, width, etc */
     973         1237 :     set_foreign_size_estimates(root, rel);
     974              : 
     975              :     /* Let FDW adjust the size estimates, if it can */
     976         1237 :     rel->fdwroutine->GetForeignRelSize(root, rel, rte->relid);
     977              : 
     978              :     /* ... but do not let it set the rows estimate to zero */
     979         1235 :     rel->rows = clamp_row_est(rel->rows);
     980              : 
     981              :     /*
     982              :      * Also, make sure rel->tuples is not insane relative to rel->rows.
     983              :      * Notably, this ensures sanity if pg_class.reltuples contains -1 and the
     984              :      * FDW doesn't do anything to replace that.
     985              :      */
     986         1235 :     rel->tuples = Max(rel->tuples, rel->rows);
     987         1235 : }
     988              : 
     989              : /*
     990              :  * set_foreign_pathlist
     991              :  *      Build access paths for a foreign table RTE
     992              :  */
     993              : static void
     994         1235 : set_foreign_pathlist(PlannerInfo *root, RelOptInfo *rel, RangeTblEntry *rte)
     995              : {
     996              :     /* Call the FDW's GetForeignPaths function to generate path(s) */
     997         1235 :     rel->fdwroutine->GetForeignPaths(root, rel, rte->relid);
     998         1235 : }
     999              : 
    1000              : /*
    1001              :  * set_append_rel_size
    1002              :  *    Set size estimates for a simple "append relation"
    1003              :  *
    1004              :  * The passed-in rel and RTE represent the entire append relation.  The
    1005              :  * relation's contents are computed by appending together the output of the
    1006              :  * individual member relations.  Note that in the non-partitioned inheritance
    1007              :  * case, the first member relation is actually the same table as is mentioned
    1008              :  * in the parent RTE ... but it has a different RTE and RelOptInfo.  This is
    1009              :  * a good thing because their outputs are not the same size.
    1010              :  */
    1011              : static void
    1012        13311 : set_append_rel_size(PlannerInfo *root, RelOptInfo *rel,
    1013              :                     Index rti, RangeTblEntry *rte)
    1014              : {
    1015        13311 :     int         parentRTindex = rti;
    1016              :     bool        has_live_children;
    1017              :     double      parent_tuples;
    1018              :     double      parent_rows;
    1019              :     double      parent_size;
    1020              :     double     *parent_attrsizes;
    1021              :     int         nattrs;
    1022              :     ListCell   *l;
    1023              : 
    1024              :     /* Guard against stack overflow due to overly deep inheritance tree. */
    1025        13311 :     check_stack_depth();
    1026              : 
    1027              :     Assert(IS_SIMPLE_REL(rel));
    1028              : 
    1029              :     /*
    1030              :      * If this is a partitioned baserel, set the consider_partitionwise_join
    1031              :      * flag; currently, we only consider partitionwise joins with the baserel
    1032              :      * if its targetlist doesn't contain a whole-row Var.
    1033              :      */
    1034        13311 :     if (enable_partitionwise_join &&
    1035         2517 :         rel->reloptkind == RELOPT_BASEREL &&
    1036         2007 :         rte->relkind == RELKIND_PARTITIONED_TABLE &&
    1037         2007 :         bms_is_empty(rel->attr_needed[InvalidAttrNumber - rel->min_attr]))
    1038         1969 :         rel->consider_partitionwise_join = true;
    1039              : 
    1040              :     /*
    1041              :      * Initialize to compute size estimates for whole append relation.
    1042              :      *
    1043              :      * We handle tuples estimates by setting "tuples" to the total number of
    1044              :      * tuples accumulated from each live child, rather than using "rows".
    1045              :      * Although an appendrel itself doesn't directly enforce any quals, its
    1046              :      * child relations may.  Therefore, setting "tuples" equal to "rows" for
    1047              :      * an appendrel isn't always appropriate, and can lead to inaccurate cost
    1048              :      * estimates.  For example, when estimating the number of distinct values
    1049              :      * from an appendrel, we would be unable to adjust the estimate based on
    1050              :      * the restriction selectivity (see estimate_num_groups).
    1051              :      *
    1052              :      * We handle width estimates by weighting the widths of different child
    1053              :      * rels proportionally to their number of rows.  This is sensible because
    1054              :      * the use of width estimates is mainly to compute the total relation
    1055              :      * "footprint" if we have to sort or hash it.  To do this, we sum the
    1056              :      * total equivalent size (in "double" arithmetic) and then divide by the
    1057              :      * total rowcount estimate.  This is done separately for the total rel
    1058              :      * width and each attribute.
    1059              :      *
    1060              :      * Note: if you consider changing this logic, beware that child rels could
    1061              :      * have zero rows and/or width, if they were excluded by constraints.
    1062              :      */
    1063        13311 :     has_live_children = false;
    1064        13311 :     parent_tuples = 0;
    1065        13311 :     parent_rows = 0;
    1066        13311 :     parent_size = 0;
    1067        13311 :     nattrs = rel->max_attr - rel->min_attr + 1;
    1068        13311 :     parent_attrsizes = (double *) palloc0(nattrs * sizeof(double));
    1069              : 
    1070        70206 :     foreach(l, root->append_rel_list)
    1071              :     {
    1072        56896 :         AppendRelInfo *appinfo = (AppendRelInfo *) lfirst(l);
    1073              :         int         childRTindex;
    1074              :         RangeTblEntry *childRTE;
    1075              :         RelOptInfo *childrel;
    1076              :         List       *childrinfos;
    1077              :         ListCell   *parentvars;
    1078              :         ListCell   *childvars;
    1079              :         ListCell   *lc;
    1080              : 
    1081              :         /* append_rel_list contains all append rels; ignore others */
    1082        56896 :         if (appinfo->parent_relid != parentRTindex)
    1083        26264 :             continue;
    1084              : 
    1085        30806 :         childRTindex = appinfo->child_relid;
    1086        30806 :         childRTE = root->simple_rte_array[childRTindex];
    1087              : 
    1088              :         /*
    1089              :          * The child rel's RelOptInfo was already created during
    1090              :          * add_other_rels_to_query.
    1091              :          */
    1092        30806 :         childrel = find_base_rel(root, childRTindex);
    1093              :         Assert(childrel->reloptkind == RELOPT_OTHER_MEMBER_REL);
    1094              : 
    1095              :         /* We may have already proven the child to be dummy. */
    1096        30806 :         if (IS_DUMMY_REL(childrel))
    1097            9 :             continue;
    1098              : 
    1099              :         /*
    1100              :          * We have to copy the parent's targetlist and quals to the child,
    1101              :          * with appropriate substitution of variables.  However, the
    1102              :          * baserestrictinfo quals were already copied/substituted when the
    1103              :          * child RelOptInfo was built.  So we don't need any additional setup
    1104              :          * before applying constraint exclusion.
    1105              :          */
    1106        30797 :         if (relation_excluded_by_constraints(root, childrel, childRTE))
    1107              :         {
    1108              :             /*
    1109              :              * This child need not be scanned, so we can omit it from the
    1110              :              * appendrel.
    1111              :              */
    1112           96 :             set_dummy_rel_pathlist(childrel);
    1113           96 :             continue;
    1114              :         }
    1115              : 
    1116              :         /*
    1117              :          * Constraint exclusion failed, so copy the parent's join quals and
    1118              :          * targetlist to the child, with appropriate variable substitutions.
    1119              :          *
    1120              :          * We skip join quals that came from above outer joins that can null
    1121              :          * this rel, since they would be of no value while generating paths
    1122              :          * for the child.  This saves some effort while processing the child
    1123              :          * rel, and it also avoids an implementation restriction in
    1124              :          * adjust_appendrel_attrs (it can't apply nullingrels to a non-Var).
    1125              :          */
    1126        30701 :         childrinfos = NIL;
    1127        37301 :         foreach(lc, rel->joininfo)
    1128              :         {
    1129         6600 :             RestrictInfo *rinfo = (RestrictInfo *) lfirst(lc);
    1130              : 
    1131         6600 :             if (!bms_overlap(rinfo->clause_relids, rel->nulling_relids))
    1132         5439 :                 childrinfos = lappend(childrinfos,
    1133         5439 :                                       adjust_appendrel_attrs(root,
    1134              :                                                              (Node *) rinfo,
    1135              :                                                              1, &appinfo));
    1136              :         }
    1137        30701 :         childrel->joininfo = childrinfos;
    1138              : 
    1139              :         /*
    1140              :          * Now for the child's targetlist.
    1141              :          *
    1142              :          * NB: the resulting childrel->reltarget->exprs may contain arbitrary
    1143              :          * expressions, which otherwise would not occur in a rel's targetlist.
    1144              :          * Code that might be looking at an appendrel child must cope with
    1145              :          * such.  (Normally, a rel's targetlist would only include Vars and
    1146              :          * PlaceHolderVars.)  XXX we do not bother to update the cost or width
    1147              :          * fields of childrel->reltarget; not clear if that would be useful.
    1148              :          */
    1149        61402 :         childrel->reltarget->exprs = (List *)
    1150        30701 :             adjust_appendrel_attrs(root,
    1151        30701 :                                    (Node *) rel->reltarget->exprs,
    1152              :                                    1, &appinfo);
    1153              : 
    1154              :         /*
    1155              :          * We have to make child entries in the EquivalenceClass data
    1156              :          * structures as well.  This is needed either if the parent
    1157              :          * participates in some eclass joins (because we will want to consider
    1158              :          * inner-indexscan joins on the individual children) or if the parent
    1159              :          * has useful pathkeys (because we should try to build MergeAppend
    1160              :          * paths that produce those sort orderings).
    1161              :          */
    1162        30701 :         if (rel->has_eclass_joins || has_useful_pathkeys(root, rel))
    1163        19190 :             add_child_rel_equivalences(root, appinfo, rel, childrel);
    1164        30701 :         childrel->has_eclass_joins = rel->has_eclass_joins;
    1165              : 
    1166              :         /*
    1167              :          * Note: we could compute appropriate attr_needed data for the child's
    1168              :          * variables, by transforming the parent's attr_needed through the
    1169              :          * translated_vars mapping.  However, currently there's no need
    1170              :          * because attr_needed is only examined for base relations not
    1171              :          * otherrels.  So we just leave the child's attr_needed empty.
    1172              :          */
    1173              : 
    1174              :         /*
    1175              :          * If we consider partitionwise joins with the parent rel, do the same
    1176              :          * for partitioned child rels.
    1177              :          *
    1178              :          * Note: here we abuse the consider_partitionwise_join flag by setting
    1179              :          * it for child rels that are not themselves partitioned.  We do so to
    1180              :          * tell try_partitionwise_join() that the child rel is sufficiently
    1181              :          * valid to be used as a per-partition input, even if it later gets
    1182              :          * proven to be dummy.  (It's not usable until we've set up the
    1183              :          * reltarget and EC entries, which we just did.)
    1184              :          */
    1185        30701 :         if (rel->consider_partitionwise_join)
    1186         6651 :             childrel->consider_partitionwise_join = true;
    1187              : 
    1188              :         /*
    1189              :          * If parallelism is allowable for this query in general, see whether
    1190              :          * it's allowable for this childrel in particular.  But if we've
    1191              :          * already decided the appendrel is not parallel-safe as a whole,
    1192              :          * there's no point in considering parallelism for this child.  For
    1193              :          * consistency, do this before calling set_rel_size() for the child.
    1194              :          */
    1195        30701 :         if (root->glob->parallelModeOK && rel->consider_parallel)
    1196        23198 :             set_rel_consider_parallel(root, childrel, childRTE);
    1197              : 
    1198              :         /*
    1199              :          * Compute the child's size.
    1200              :          */
    1201        30701 :         set_rel_size(root, childrel, childRTindex, childRTE);
    1202              : 
    1203              :         /*
    1204              :          * It is possible that constraint exclusion detected a contradiction
    1205              :          * within a child subquery, even though we didn't prove one above. If
    1206              :          * so, we can skip this child.
    1207              :          */
    1208        30700 :         if (IS_DUMMY_REL(childrel))
    1209           69 :             continue;
    1210              : 
    1211              :         /* We have at least one live child. */
    1212        30631 :         has_live_children = true;
    1213              : 
    1214              :         /*
    1215              :          * If any live child is not parallel-safe, treat the whole appendrel
    1216              :          * as not parallel-safe.  In future we might be able to generate plans
    1217              :          * in which some children are farmed out to workers while others are
    1218              :          * not; but we don't have that today, so it's a waste to consider
    1219              :          * partial paths anywhere in the appendrel unless it's all safe.
    1220              :          * (Child rels visited before this one will be unmarked in
    1221              :          * set_append_rel_pathlist().)
    1222              :          */
    1223        30631 :         if (!childrel->consider_parallel)
    1224         7861 :             rel->consider_parallel = false;
    1225              : 
    1226              :         /*
    1227              :          * Accumulate size information from each live child.
    1228              :          */
    1229              :         Assert(childrel->rows > 0);
    1230              : 
    1231        30631 :         parent_tuples += childrel->tuples;
    1232        30631 :         parent_rows += childrel->rows;
    1233        30631 :         parent_size += childrel->reltarget->width * childrel->rows;
    1234              : 
    1235              :         /*
    1236              :          * Accumulate per-column estimates too.  We need not do anything for
    1237              :          * PlaceHolderVars in the parent list.  If child expression isn't a
    1238              :          * Var, or we didn't record a width estimate for it, we have to fall
    1239              :          * back on a datatype-based estimate.
    1240              :          *
    1241              :          * By construction, child's targetlist is 1-to-1 with parent's.
    1242              :          */
    1243       103914 :         forboth(parentvars, rel->reltarget->exprs,
    1244              :                 childvars, childrel->reltarget->exprs)
    1245              :         {
    1246        73283 :             Var        *parentvar = (Var *) lfirst(parentvars);
    1247        73283 :             Node       *childvar = (Node *) lfirst(childvars);
    1248              : 
    1249        73283 :             if (IsA(parentvar, Var) && parentvar->varno == parentRTindex)
    1250              :             {
    1251        66733 :                 int         pndx = parentvar->varattno - rel->min_attr;
    1252        66733 :                 int32       child_width = 0;
    1253              : 
    1254        66733 :                 if (IsA(childvar, Var) &&
    1255        64220 :                     ((Var *) childvar)->varno == childrel->relid)
    1256              :                 {
    1257        64175 :                     int         cndx = ((Var *) childvar)->varattno - childrel->min_attr;
    1258              : 
    1259        64175 :                     child_width = childrel->attr_widths[cndx];
    1260              :                 }
    1261        66733 :                 if (child_width <= 0)
    1262         2558 :                     child_width = get_typavgwidth(exprType(childvar),
    1263              :                                                   exprTypmod(childvar));
    1264              :                 Assert(child_width > 0);
    1265        66733 :                 parent_attrsizes[pndx] += child_width * childrel->rows;
    1266              :             }
    1267              :         }
    1268              :     }
    1269              : 
    1270        13310 :     if (has_live_children)
    1271              :     {
    1272              :         /*
    1273              :          * Save the finished size estimates.
    1274              :          */
    1275              :         int         i;
    1276              : 
    1277              :         Assert(parent_rows > 0);
    1278        13160 :         rel->tuples = parent_tuples;
    1279        13160 :         rel->rows = parent_rows;
    1280        13160 :         rel->reltarget->width = rint(parent_size / parent_rows);
    1281       122474 :         for (i = 0; i < nattrs; i++)
    1282       109314 :             rel->attr_widths[i] = rint(parent_attrsizes[i] / parent_rows);
    1283              : 
    1284              :         /*
    1285              :          * Note that we leave rel->pages as zero; this is important to avoid
    1286              :          * double-counting the appendrel tree in total_table_pages.
    1287              :          */
    1288              :     }
    1289              :     else
    1290              :     {
    1291              :         /*
    1292              :          * All children were excluded by constraints, so mark the whole
    1293              :          * appendrel dummy.  We must do this in this phase so that the rel's
    1294              :          * dummy-ness is visible when we generate paths for other rels.
    1295              :          */
    1296          150 :         set_dummy_rel_pathlist(rel);
    1297              :     }
    1298              : 
    1299        13310 :     pfree(parent_attrsizes);
    1300        13310 : }
    1301              : 
    1302              : /*
    1303              :  * set_append_rel_pathlist
    1304              :  *    Build access paths for an "append relation"
    1305              :  */
    1306              : static void
    1307        13160 : set_append_rel_pathlist(PlannerInfo *root, RelOptInfo *rel,
    1308              :                         Index rti, RangeTblEntry *rte)
    1309              : {
    1310        13160 :     int         parentRTindex = rti;
    1311        13160 :     List       *live_childrels = NIL;
    1312              :     ListCell   *l;
    1313              : 
    1314              :     /*
    1315              :      * Generate access paths for each member relation, and remember the
    1316              :      * non-dummy children.
    1317              :      */
    1318        69848 :     foreach(l, root->append_rel_list)
    1319              :     {
    1320        56688 :         AppendRelInfo *appinfo = (AppendRelInfo *) lfirst(l);
    1321              :         int         childRTindex;
    1322              :         RangeTblEntry *childRTE;
    1323              :         RelOptInfo *childrel;
    1324              : 
    1325              :         /* append_rel_list contains all append rels; ignore others */
    1326        56688 :         if (appinfo->parent_relid != parentRTindex)
    1327        25916 :             continue;
    1328              : 
    1329              :         /* Re-locate the child RTE and RelOptInfo */
    1330        30772 :         childRTindex = appinfo->child_relid;
    1331        30772 :         childRTE = root->simple_rte_array[childRTindex];
    1332        30772 :         childrel = root->simple_rel_array[childRTindex];
    1333              : 
    1334              :         /*
    1335              :          * If set_append_rel_size() decided the parent appendrel was
    1336              :          * parallel-unsafe at some point after visiting this child rel, we
    1337              :          * need to propagate the unsafety marking down to the child, so that
    1338              :          * we don't generate useless partial paths for it.
    1339              :          */
    1340        30772 :         if (!rel->consider_parallel)
    1341         7962 :             childrel->consider_parallel = false;
    1342              : 
    1343              :         /*
    1344              :          * Compute the child's access paths.
    1345              :          */
    1346        30772 :         set_rel_pathlist(root, childrel, childRTindex, childRTE);
    1347              : 
    1348              :         /*
    1349              :          * If child is dummy, ignore it.
    1350              :          */
    1351        30772 :         if (IS_DUMMY_REL(childrel))
    1352          141 :             continue;
    1353              : 
    1354              :         /*
    1355              :          * Child is live, so add it to the live_childrels list for use below.
    1356              :          */
    1357        30631 :         live_childrels = lappend(live_childrels, childrel);
    1358              :     }
    1359              : 
    1360              :     /* Add paths to the append relation. */
    1361        13160 :     add_paths_to_append_rel(root, rel, live_childrels);
    1362        13160 : }
    1363              : 
    1364              : /*
    1365              :  * set_grouped_rel_pathlist
    1366              :  *    If a grouped relation for the given 'rel' exists, build partial
    1367              :  *    aggregation paths for it.
    1368              :  */
    1369              : static void
    1370       293556 : set_grouped_rel_pathlist(PlannerInfo *root, RelOptInfo *rel)
    1371              : {
    1372              :     RelOptInfo *grouped_rel;
    1373              : 
    1374              :     /*
    1375              :      * If there are no aggregate expressions or grouping expressions, eager
    1376              :      * aggregation is not possible.
    1377              :      */
    1378       293556 :     if (root->agg_clause_list == NIL ||
    1379         1666 :         root->group_expr_list == NIL)
    1380       292022 :         return;
    1381              : 
    1382              :     /* Add paths to the grouped base relation if one exists. */
    1383         1534 :     grouped_rel = rel->grouped_rel;
    1384         1534 :     if (grouped_rel)
    1385              :     {
    1386              :         Assert(IS_GROUPED_REL(grouped_rel));
    1387              : 
    1388          293 :         generate_grouped_paths(root, grouped_rel, rel);
    1389          293 :         set_cheapest(grouped_rel);
    1390              :     }
    1391              : }
    1392              : 
    1393              : 
    1394              : /*
    1395              :  * add_paths_to_append_rel
    1396              :  *      Generate paths for the given append relation given the set of non-dummy
    1397              :  *      child rels.
    1398              :  *
    1399              :  * The function collects all parameterizations and orderings supported by the
    1400              :  * non-dummy children. For every such parameterization or ordering, it creates
    1401              :  * an append path collecting one path from each non-dummy child with given
    1402              :  * parameterization or ordering. Similarly it collects partial paths from
    1403              :  * non-dummy children to create partial append paths.
    1404              :  */
    1405              : void
    1406        23985 : add_paths_to_append_rel(PlannerInfo *root, RelOptInfo *rel,
    1407              :                         List *live_childrels)
    1408              : {
    1409        23985 :     AppendPathInput unparameterized = {0};
    1410        23985 :     AppendPathInput startup = {0};
    1411        23985 :     AppendPathInput partial_only = {0};
    1412        23985 :     AppendPathInput parallel_append = {0};
    1413        23985 :     bool        unparameterized_valid = true;
    1414        23985 :     bool        startup_valid = true;
    1415        23985 :     bool        partial_only_valid = true;
    1416        23985 :     bool        parallel_append_valid = true;
    1417        23985 :     List       *all_child_pathkeys = NIL;
    1418        23985 :     List       *all_child_outers = NIL;
    1419              :     ListCell   *l;
    1420        23985 :     double      partial_rows = -1;
    1421              : 
    1422              :     /* If appropriate, consider parallel append */
    1423        23985 :     parallel_append_valid = enable_parallel_append && rel->consider_parallel;
    1424              : 
    1425              :     /*
    1426              :      * For every non-dummy child, remember the cheapest path.  Also, identify
    1427              :      * all pathkeys (orderings) and parameterizations (required_outer sets)
    1428              :      * available for the non-dummy member relations.
    1429              :      */
    1430        77650 :     foreach(l, live_childrels)
    1431              :     {
    1432        53665 :         RelOptInfo *childrel = lfirst(l);
    1433              :         ListCell   *lcp;
    1434        53665 :         Path       *cheapest_partial_path = NULL;
    1435              : 
    1436              :         /*
    1437              :          * If child has an unparameterized cheapest-total path, add that to
    1438              :          * the unparameterized Append path we are constructing for the parent.
    1439              :          * If not, there's no workable unparameterized path.
    1440              :          *
    1441              :          * With partitionwise aggregates, the child rel's pathlist may be
    1442              :          * empty, so don't assume that a path exists here.
    1443              :          */
    1444        53665 :         if (childrel->pathlist != NIL &&
    1445        53665 :             childrel->cheapest_total_path->param_info == NULL)
    1446        53287 :             accumulate_append_subpath(childrel->cheapest_total_path,
    1447              :                                       &unparameterized.subpaths, NULL, &unparameterized.child_append_relid_sets);
    1448              :         else
    1449          378 :             unparameterized_valid = false;
    1450              : 
    1451              :         /*
    1452              :          * When the planner is considering cheap startup plans, we'll also
    1453              :          * collect all the cheapest_startup_paths (if set) and build an
    1454              :          * AppendPath containing those as subpaths.
    1455              :          */
    1456        53665 :         if (rel->consider_startup && childrel->cheapest_startup_path != NULL)
    1457          865 :         {
    1458              :             Path       *cheapest_path;
    1459              : 
    1460              :             /*
    1461              :              * With an indication of how many tuples the query should provide,
    1462              :              * the optimizer tries to choose the path optimal for that
    1463              :              * specific number of tuples.
    1464              :              */
    1465          865 :             if (root->tuple_fraction > 0.0)
    1466              :                 cheapest_path =
    1467          865 :                     get_cheapest_fractional_path(childrel,
    1468              :                                                  root->tuple_fraction);
    1469              :             else
    1470            0 :                 cheapest_path = childrel->cheapest_startup_path;
    1471              : 
    1472              :             /* cheapest_startup_path must not be a parameterized path. */
    1473              :             Assert(cheapest_path->param_info == NULL);
    1474          865 :             accumulate_append_subpath(cheapest_path,
    1475              :                                       &startup.subpaths,
    1476              :                                       NULL,
    1477              :                                       &startup.child_append_relid_sets);
    1478              :         }
    1479              :         else
    1480        52800 :             startup_valid = false;
    1481              : 
    1482              : 
    1483              :         /* Same idea, but for a partial plan. */
    1484        53665 :         if (childrel->partial_pathlist != NIL)
    1485              :         {
    1486        32683 :             cheapest_partial_path = linitial(childrel->partial_pathlist);
    1487        32683 :             accumulate_append_subpath(cheapest_partial_path,
    1488              :                                       &partial_only.partial_subpaths, NULL,
    1489              :                                       &partial_only.child_append_relid_sets);
    1490              :         }
    1491              :         else
    1492        20982 :             partial_only_valid = false;
    1493              : 
    1494              :         /*
    1495              :          * Same idea, but for a parallel append mixing partial and non-partial
    1496              :          * paths.
    1497              :          */
    1498        53665 :         if (parallel_append_valid)
    1499              :         {
    1500        40644 :             Path       *nppath = NULL;
    1501              : 
    1502              :             nppath =
    1503        40644 :                 get_cheapest_parallel_safe_total_inner(childrel->pathlist);
    1504              : 
    1505        40644 :             if (cheapest_partial_path == NULL && nppath == NULL)
    1506              :             {
    1507              :                 /* Neither a partial nor a parallel-safe path?  Forget it. */
    1508          283 :                 parallel_append_valid = false;
    1509              :             }
    1510        40361 :             else if (nppath == NULL ||
    1511        32458 :                      (cheapest_partial_path != NULL &&
    1512        32458 :                       cheapest_partial_path->total_cost < nppath->total_cost))
    1513              :             {
    1514              :                 /* Partial path is cheaper or the only option. */
    1515              :                 Assert(cheapest_partial_path != NULL);
    1516        32388 :                 accumulate_append_subpath(cheapest_partial_path,
    1517              :                                           &parallel_append.partial_subpaths,
    1518              :                                           &parallel_append.subpaths,
    1519              :                                           &parallel_append.child_append_relid_sets);
    1520              :             }
    1521              :             else
    1522              :             {
    1523              :                 /*
    1524              :                  * Either we've got only a non-partial path, or we think that
    1525              :                  * a single backend can execute the best non-partial path
    1526              :                  * faster than all the parallel backends working together can
    1527              :                  * execute the best partial path.
    1528              :                  *
    1529              :                  * It might make sense to be more aggressive here.  Even if
    1530              :                  * the best non-partial path is more expensive than the best
    1531              :                  * partial path, it could still be better to choose the
    1532              :                  * non-partial path if there are several such paths that can
    1533              :                  * be given to different workers.  For now, we don't try to
    1534              :                  * figure that out.
    1535              :                  */
    1536         7973 :                 accumulate_append_subpath(nppath,
    1537              :                                           &parallel_append.subpaths,
    1538              :                                           NULL,
    1539              :                                           &parallel_append.child_append_relid_sets);
    1540              :             }
    1541              :         }
    1542              : 
    1543              :         /*
    1544              :          * Collect lists of all the available path orderings and
    1545              :          * parameterizations for all the children.  We use these as a
    1546              :          * heuristic to indicate which sort orderings and parameterizations we
    1547              :          * should build Append and MergeAppend paths for.
    1548              :          */
    1549       126210 :         foreach(lcp, childrel->pathlist)
    1550              :         {
    1551        72545 :             Path       *childpath = (Path *) lfirst(lcp);
    1552        72545 :             List       *childkeys = childpath->pathkeys;
    1553        72545 :             Relids      childouter = PATH_REQ_OUTER(childpath);
    1554              : 
    1555              :             /* Unsorted paths don't contribute to pathkey list */
    1556        72545 :             if (childkeys != NIL)
    1557              :             {
    1558              :                 ListCell   *lpk;
    1559        18707 :                 bool        found = false;
    1560              : 
    1561              :                 /* Have we already seen this ordering? */
    1562        18822 :                 foreach(lpk, all_child_pathkeys)
    1563              :                 {
    1564        12676 :                     List       *existing_pathkeys = (List *) lfirst(lpk);
    1565              : 
    1566        12676 :                     if (compare_pathkeys(existing_pathkeys,
    1567              :                                          childkeys) == PATHKEYS_EQUAL)
    1568              :                     {
    1569        12561 :                         found = true;
    1570        12561 :                         break;
    1571              :                     }
    1572              :                 }
    1573        18707 :                 if (!found)
    1574              :                 {
    1575              :                     /* No, so add it to all_child_pathkeys */
    1576         6146 :                     all_child_pathkeys = lappend(all_child_pathkeys,
    1577              :                                                  childkeys);
    1578              :                 }
    1579              :             }
    1580              : 
    1581              :             /* Unparameterized paths don't contribute to param-set list */
    1582        72545 :             if (childouter)
    1583              :             {
    1584              :                 ListCell   *lco;
    1585         3429 :                 bool        found = false;
    1586              : 
    1587              :                 /* Have we already seen this param set? */
    1588         3843 :                 foreach(lco, all_child_outers)
    1589              :                 {
    1590         2540 :                     Relids      existing_outers = (Relids) lfirst(lco);
    1591              : 
    1592         2540 :                     if (bms_equal(existing_outers, childouter))
    1593              :                     {
    1594         2126 :                         found = true;
    1595         2126 :                         break;
    1596              :                     }
    1597              :                 }
    1598         3429 :                 if (!found)
    1599              :                 {
    1600              :                     /* No, so add it to all_child_outers */
    1601         1303 :                     all_child_outers = lappend(all_child_outers,
    1602              :                                                childouter);
    1603              :                 }
    1604              :             }
    1605              :         }
    1606              :     }
    1607              : 
    1608              :     /*
    1609              :      * If we found unparameterized paths for all children, build an unordered,
    1610              :      * unparameterized Append path for the rel.  (Note: this is correct even
    1611              :      * if we have zero or one live subpath due to constraint exclusion.)
    1612              :      */
    1613        23985 :     if (unparameterized_valid)
    1614        23823 :         add_path(rel, (Path *) create_append_path(root, rel, unparameterized,
    1615              :                                                   NIL, NULL, 0, false,
    1616              :                                                   -1));
    1617              : 
    1618              :     /* build an AppendPath for the cheap startup paths, if valid */
    1619        23985 :     if (startup_valid)
    1620          350 :         add_path(rel, (Path *) create_append_path(root, rel, startup,
    1621              :                                                   NIL, NULL, 0, false, -1));
    1622              : 
    1623              :     /*
    1624              :      * Consider an append of unordered, unparameterized partial paths.  Make
    1625              :      * it parallel-aware if possible.
    1626              :      */
    1627        23985 :     if (partial_only_valid && partial_only.partial_subpaths != NIL)
    1628              :     {
    1629              :         AppendPath *appendpath;
    1630              :         ListCell   *lc;
    1631        14230 :         int         parallel_workers = 0;
    1632              : 
    1633              :         /* Find the highest number of workers requested for any subpath. */
    1634        49150 :         foreach(lc, partial_only.partial_subpaths)
    1635              :         {
    1636        34920 :             Path       *path = lfirst(lc);
    1637              : 
    1638        34920 :             parallel_workers = Max(parallel_workers, path->parallel_workers);
    1639              :         }
    1640              :         Assert(parallel_workers > 0);
    1641              : 
    1642              :         /*
    1643              :          * If the use of parallel append is permitted, always request at least
    1644              :          * log2(# of children) workers.  We assume it can be useful to have
    1645              :          * extra workers in this case because they will be spread out across
    1646              :          * the children.  The precise formula is just a guess, but we don't
    1647              :          * want to end up with a radically different answer for a table with N
    1648              :          * partitions vs. an unpartitioned table with the same data, so the
    1649              :          * use of some kind of log-scaling here seems to make some sense.
    1650              :          */
    1651        14230 :         if (enable_parallel_append)
    1652              :         {
    1653        14206 :             parallel_workers = Max(parallel_workers,
    1654              :                                    pg_leftmost_one_pos32(list_length(live_childrels)) + 1);
    1655        14206 :             parallel_workers = Min(parallel_workers,
    1656              :                                    max_parallel_workers_per_gather);
    1657              :         }
    1658              :         Assert(parallel_workers > 0);
    1659              : 
    1660              :         /* Generate a partial append path. */
    1661        14230 :         appendpath = create_append_path(root, rel, partial_only,
    1662              :                                         NIL, NULL, parallel_workers,
    1663              :                                         enable_parallel_append,
    1664              :                                         -1);
    1665              : 
    1666              :         /*
    1667              :          * Make sure any subsequent partial paths use the same row count
    1668              :          * estimate.
    1669              :          */
    1670        14230 :         partial_rows = appendpath->path.rows;
    1671              : 
    1672              :         /* Add the path. */
    1673        14230 :         add_partial_path(rel, (Path *) appendpath);
    1674              :     }
    1675              : 
    1676              :     /*
    1677              :      * Consider a parallel-aware append using a mix of partial and non-partial
    1678              :      * paths.  (This only makes sense if there's at least one child which has
    1679              :      * a non-partial path that is substantially cheaper than any partial path;
    1680              :      * otherwise, we should use the append path added in the previous step.)
    1681              :      */
    1682        23985 :     if (parallel_append_valid && parallel_append.subpaths != NIL)
    1683              :     {
    1684              :         AppendPath *appendpath;
    1685              :         ListCell   *lc;
    1686         2611 :         int         parallel_workers = 0;
    1687              : 
    1688              :         /*
    1689              :          * Find the highest number of workers requested for any partial
    1690              :          * subpath.
    1691              :          */
    1692         3062 :         foreach(lc, parallel_append.partial_subpaths)
    1693              :         {
    1694          451 :             Path       *path = lfirst(lc);
    1695              : 
    1696          451 :             parallel_workers = Max(parallel_workers, path->parallel_workers);
    1697              :         }
    1698              : 
    1699              :         /*
    1700              :          * Same formula here as above.  It's even more important in this
    1701              :          * instance because the non-partial paths won't contribute anything to
    1702              :          * the planned number of parallel workers.
    1703              :          */
    1704         2611 :         parallel_workers = Max(parallel_workers,
    1705              :                                pg_leftmost_one_pos32(list_length(live_childrels)) + 1);
    1706         2611 :         parallel_workers = Min(parallel_workers,
    1707              :                                max_parallel_workers_per_gather);
    1708              :         Assert(parallel_workers > 0);
    1709              : 
    1710         2611 :         appendpath = create_append_path(root, rel, parallel_append,
    1711              :                                         NIL, NULL, parallel_workers, true,
    1712              :                                         partial_rows);
    1713         2611 :         add_partial_path(rel, (Path *) appendpath);
    1714              :     }
    1715              : 
    1716              :     /*
    1717              :      * Also build unparameterized ordered append paths based on the collected
    1718              :      * list of child pathkeys.
    1719              :      */
    1720        23985 :     if (unparameterized_valid)
    1721        23823 :         generate_orderedappend_paths(root, rel, live_childrels,
    1722              :                                      all_child_pathkeys);
    1723              : 
    1724              :     /*
    1725              :      * Build Append paths for each parameterization seen among the child rels.
    1726              :      * (This may look pretty expensive, but in most cases of practical
    1727              :      * interest, the child rels will expose mostly the same parameterizations,
    1728              :      * so that not that many cases actually get considered here.)
    1729              :      *
    1730              :      * The Append node itself cannot enforce quals, so all qual checking must
    1731              :      * be done in the child paths.  This means that to have a parameterized
    1732              :      * Append path, we must have the exact same parameterization for each
    1733              :      * child path; otherwise some children might be failing to check the
    1734              :      * moved-down quals.  To make them match up, we can try to increase the
    1735              :      * parameterization of lesser-parameterized paths.
    1736              :      */
    1737        25288 :     foreach(l, all_child_outers)
    1738              :     {
    1739         1303 :         Relids      required_outer = (Relids) lfirst(l);
    1740              :         ListCell   *lcr;
    1741         1303 :         AppendPathInput parameterized = {0};
    1742         1303 :         bool        parameterized_valid = true;
    1743              : 
    1744              :         /* Select the child paths for an Append with this parameterization */
    1745         4780 :         foreach(lcr, live_childrels)
    1746              :         {
    1747         3483 :             RelOptInfo *childrel = (RelOptInfo *) lfirst(lcr);
    1748              :             Path       *subpath;
    1749              : 
    1750         3483 :             if (childrel->pathlist == NIL)
    1751              :             {
    1752              :                 /* failed to make a suitable path for this child */
    1753            0 :                 parameterized_valid = false;
    1754            0 :                 break;
    1755              :             }
    1756              : 
    1757         3483 :             subpath = get_cheapest_parameterized_child_path(root,
    1758              :                                                             childrel,
    1759              :                                                             required_outer);
    1760         3483 :             if (subpath == NULL)
    1761              :             {
    1762              :                 /* failed to make a suitable path for this child */
    1763            6 :                 parameterized_valid = false;
    1764            6 :                 break;
    1765              :             }
    1766         3477 :             accumulate_append_subpath(subpath, &parameterized.subpaths, NULL,
    1767              :                                       &parameterized.child_append_relid_sets);
    1768              :         }
    1769              : 
    1770         1303 :         if (parameterized_valid)
    1771         1297 :             add_path(rel, (Path *)
    1772         1297 :                      create_append_path(root, rel, parameterized,
    1773              :                                         NIL, required_outer, 0, false,
    1774              :                                         -1));
    1775              :     }
    1776              : 
    1777              :     /*
    1778              :      * When there is only a single child relation, the Append path can inherit
    1779              :      * any ordering available for the child rel's path, so that it's useful to
    1780              :      * consider ordered partial paths.  Above we only considered the cheapest
    1781              :      * partial path for each child, but let's also make paths using any
    1782              :      * partial paths that have pathkeys.
    1783              :      */
    1784        23985 :     if (list_length(live_childrels) == 1)
    1785              :     {
    1786         7424 :         RelOptInfo *childrel = (RelOptInfo *) linitial(live_childrels);
    1787              : 
    1788              :         /* skip the cheapest partial path, since we already used that above */
    1789         7532 :         for_each_from(l, childrel->partial_pathlist, 1)
    1790              :         {
    1791          108 :             Path       *path = (Path *) lfirst(l);
    1792              :             AppendPath *appendpath;
    1793          108 :             AppendPathInput append = {0};
    1794              : 
    1795              :             /* skip paths with no pathkeys. */
    1796          108 :             if (path->pathkeys == NIL)
    1797            0 :                 continue;
    1798              : 
    1799          108 :             append.partial_subpaths = list_make1(path);
    1800          108 :             appendpath = create_append_path(root, rel, append, NIL, NULL,
    1801              :                                             path->parallel_workers, true,
    1802              :                                             partial_rows);
    1803          108 :             add_partial_path(rel, (Path *) appendpath);
    1804              :         }
    1805              :     }
    1806        23985 : }
    1807              : 
    1808              : /*
    1809              :  * generate_orderedappend_paths
    1810              :  *      Generate ordered append paths for an append relation
    1811              :  *
    1812              :  * Usually we generate MergeAppend paths here, but there are some special
    1813              :  * cases where we can generate simple Append paths, because the subpaths
    1814              :  * can provide tuples in the required order already.
    1815              :  *
    1816              :  * We generate a path for each ordering (pathkey list) appearing in
    1817              :  * all_child_pathkeys.
    1818              :  *
    1819              :  * We consider the cheapest-startup and cheapest-total cases, and also the
    1820              :  * cheapest-fractional case when not all tuples need to be retrieved.  For each
    1821              :  * interesting ordering, we collect all the cheapest startup subpaths, all the
    1822              :  * cheapest total paths, and, if applicable, all the cheapest fractional paths,
    1823              :  * and build a suitable path for each case.
    1824              :  *
    1825              :  * We don't currently generate any parameterized ordered paths here.  While
    1826              :  * it would not take much more code here to do so, it's very unclear that it
    1827              :  * is worth the planning cycles to investigate such paths: there's little
    1828              :  * use for an ordered path on the inside of a nestloop.  In fact, it's likely
    1829              :  * that the current coding of add_path would reject such paths out of hand,
    1830              :  * because add_path gives no credit for sort ordering of parameterized paths,
    1831              :  * and a parameterized MergeAppend is going to be more expensive than the
    1832              :  * corresponding parameterized Append path.  If we ever try harder to support
    1833              :  * parameterized mergejoin plans, it might be worth adding support for
    1834              :  * parameterized paths here to feed such joins.  (See notes in
    1835              :  * optimizer/README for why that might not ever happen, though.)
    1836              :  */
    1837              : static void
    1838        23823 : generate_orderedappend_paths(PlannerInfo *root, RelOptInfo *rel,
    1839              :                              List *live_childrels,
    1840              :                              List *all_child_pathkeys)
    1841              : {
    1842              :     ListCell   *lcp;
    1843        23823 :     List       *partition_pathkeys = NIL;
    1844        23823 :     List       *partition_pathkeys_desc = NIL;
    1845        23823 :     bool        partition_pathkeys_partial = true;
    1846        23823 :     bool        partition_pathkeys_desc_partial = true;
    1847              : 
    1848              :     /*
    1849              :      * Some partitioned table setups may allow us to use an Append node
    1850              :      * instead of a MergeAppend.  This is possible in cases such as RANGE
    1851              :      * partitioned tables where it's guaranteed that an earlier partition must
    1852              :      * contain rows which come earlier in the sort order.  To detect whether
    1853              :      * this is relevant, build pathkey descriptions of the partition ordering,
    1854              :      * for both forward and reverse scans.
    1855              :      */
    1856        38540 :     if (rel->part_scheme != NULL && IS_SIMPLE_REL(rel) &&
    1857        14717 :         partitions_are_ordered(rel->boundinfo, rel->live_parts))
    1858              :     {
    1859        12261 :         partition_pathkeys = build_partition_pathkeys(root, rel,
    1860              :                                                       ForwardScanDirection,
    1861              :                                                       &partition_pathkeys_partial);
    1862              : 
    1863        12261 :         partition_pathkeys_desc = build_partition_pathkeys(root, rel,
    1864              :                                                            BackwardScanDirection,
    1865              :                                                            &partition_pathkeys_desc_partial);
    1866              : 
    1867              :         /*
    1868              :          * You might think we should truncate_useless_pathkeys here, but
    1869              :          * allowing partition keys which are a subset of the query's pathkeys
    1870              :          * can often be useful.  For example, consider a table partitioned by
    1871              :          * RANGE (a, b), and a query with ORDER BY a, b, c.  If we have child
    1872              :          * paths that can produce the a, b, c ordering (perhaps via indexes on
    1873              :          * (a, b, c)) then it works to consider the appendrel output as
    1874              :          * ordered by a, b, c.
    1875              :          */
    1876              :     }
    1877              : 
    1878              :     /* Now consider each interesting sort ordering */
    1879        29939 :     foreach(lcp, all_child_pathkeys)
    1880              :     {
    1881         6116 :         List       *pathkeys = (List *) lfirst(lcp);
    1882         6116 :         AppendPathInput startup = {0};
    1883         6116 :         AppendPathInput total = {0};
    1884         6116 :         AppendPathInput fractional = {0};
    1885         6116 :         bool        startup_neq_total = false;
    1886         6116 :         bool        fraction_neq_total = false;
    1887              :         bool        match_partition_order;
    1888              :         bool        match_partition_order_desc;
    1889              :         int         end_index;
    1890              :         int         first_index;
    1891              :         int         direction;
    1892              : 
    1893              :         /*
    1894              :          * Determine if this sort ordering matches any partition pathkeys we
    1895              :          * have, for both ascending and descending partition order.  If the
    1896              :          * partition pathkeys happen to be contained in pathkeys then it still
    1897              :          * works, as described above, providing that the partition pathkeys
    1898              :          * are complete and not just a prefix of the partition keys.  (In such
    1899              :          * cases we'll be relying on the child paths to have sorted the
    1900              :          * lower-order columns of the required pathkeys.)
    1901              :          */
    1902         6116 :         match_partition_order =
    1903        11054 :             pathkeys_contained_in(pathkeys, partition_pathkeys) ||
    1904         5042 :             (!partition_pathkeys_partial &&
    1905          104 :              pathkeys_contained_in(partition_pathkeys, pathkeys));
    1906              : 
    1907        15866 :         match_partition_order_desc = !match_partition_order &&
    1908         4884 :             (pathkeys_contained_in(pathkeys, partition_pathkeys_desc) ||
    1909         4898 :              (!partition_pathkeys_desc_partial &&
    1910           32 :               pathkeys_contained_in(partition_pathkeys_desc, pathkeys)));
    1911              : 
    1912              :         /*
    1913              :          * When the required pathkeys match the reverse of the partition
    1914              :          * order, we must build the list of paths in reverse starting with the
    1915              :          * last matching partition first.  We can get away without making any
    1916              :          * special cases for this in the loop below by just looping backward
    1917              :          * over the child relations in this case.
    1918              :          */
    1919         6116 :         if (match_partition_order_desc)
    1920              :         {
    1921              :             /* loop backward */
    1922           24 :             first_index = list_length(live_childrels) - 1;
    1923           24 :             end_index = -1;
    1924           24 :             direction = -1;
    1925              : 
    1926              :             /*
    1927              :              * Set this to true to save us having to check for
    1928              :              * match_partition_order_desc in the loop below.
    1929              :              */
    1930           24 :             match_partition_order = true;
    1931              :         }
    1932              :         else
    1933              :         {
    1934              :             /* for all other case, loop forward */
    1935         6092 :             first_index = 0;
    1936         6092 :             end_index = list_length(live_childrels);
    1937         6092 :             direction = 1;
    1938              :         }
    1939              : 
    1940              :         /* Select the child paths for this ordering... */
    1941        21964 :         for (int i = first_index; i != end_index; i += direction)
    1942              :         {
    1943        15848 :             RelOptInfo *childrel = list_nth_node(RelOptInfo, live_childrels, i);
    1944              :             Path       *cheapest_startup,
    1945              :                        *cheapest_total,
    1946        15848 :                        *cheapest_fractional = NULL;
    1947              : 
    1948              :             /* Locate the right paths, if they are available. */
    1949              :             cheapest_startup =
    1950        15848 :                 get_cheapest_path_for_pathkeys(childrel->pathlist,
    1951              :                                                pathkeys,
    1952              :                                                NULL,
    1953              :                                                STARTUP_COST,
    1954              :                                                false);
    1955              :             cheapest_total =
    1956        15848 :                 get_cheapest_path_for_pathkeys(childrel->pathlist,
    1957              :                                                pathkeys,
    1958              :                                                NULL,
    1959              :                                                TOTAL_COST,
    1960              :                                                false);
    1961              : 
    1962              :             /*
    1963              :              * If we can't find any paths with the right order just use the
    1964              :              * cheapest-total path; we'll have to sort it later.
    1965              :              */
    1966        15848 :             if (cheapest_startup == NULL || cheapest_total == NULL)
    1967              :             {
    1968          170 :                 cheapest_startup = cheapest_total =
    1969              :                     childrel->cheapest_total_path;
    1970              :                 /* Assert we do have an unparameterized path for this child */
    1971              :                 Assert(cheapest_total->param_info == NULL);
    1972              :             }
    1973              : 
    1974              :             /*
    1975              :              * When building a fractional path, determine a cheapest
    1976              :              * fractional path for each child relation too. Looking at startup
    1977              :              * and total costs is not enough, because the cheapest fractional
    1978              :              * path may be dominated by two separate paths (one for startup,
    1979              :              * one for total).
    1980              :              *
    1981              :              * When needed (building fractional path), determine the cheapest
    1982              :              * fractional path too.
    1983              :              */
    1984        15848 :             if (root->tuple_fraction > 0)
    1985              :             {
    1986          448 :                 double      path_fraction = root->tuple_fraction;
    1987              : 
    1988              :                 /*
    1989              :                  * We should not have a dummy child relation here.  However,
    1990              :                  * we cannot use childrel->rows to compute the tuple fraction,
    1991              :                  * as childrel can be an upper relation with an unset row
    1992              :                  * estimate.  Instead, we use the row estimate from the
    1993              :                  * cheapest_total path, which should already have been forced
    1994              :                  * to a sane value.
    1995              :                  */
    1996              :                 Assert(cheapest_total->rows > 0);
    1997              : 
    1998              :                 /* Convert absolute limit to a path fraction */
    1999          448 :                 if (path_fraction >= 1.0)
    2000          448 :                     path_fraction /= cheapest_total->rows;
    2001              : 
    2002              :                 cheapest_fractional =
    2003          448 :                     get_cheapest_fractional_path_for_pathkeys(childrel->pathlist,
    2004              :                                                               pathkeys,
    2005              :                                                               NULL,
    2006              :                                                               path_fraction);
    2007              : 
    2008              :                 /*
    2009              :                  * If we found no path with matching pathkeys, use the
    2010              :                  * cheapest total path instead.
    2011              :                  *
    2012              :                  * XXX We might consider partially sorted paths too (with an
    2013              :                  * incremental sort on top). But we'd have to build all the
    2014              :                  * incremental paths, do the costing etc.
    2015              :                  *
    2016              :                  * Also, notice whether we actually have different paths for
    2017              :                  * the "fractional" and "total" cases.  This helps avoid
    2018              :                  * generating two identical ordered append paths.
    2019              :                  */
    2020          448 :                 if (cheapest_fractional == NULL)
    2021           22 :                     cheapest_fractional = cheapest_total;
    2022          426 :                 else if (cheapest_fractional != cheapest_total)
    2023            0 :                     fraction_neq_total = true;
    2024              :             }
    2025              : 
    2026              :             /*
    2027              :              * Notice whether we actually have different paths for the
    2028              :              * "cheapest" and "total" cases.  This helps avoid generating two
    2029              :              * identical ordered append paths.
    2030              :              */
    2031        15848 :             if (cheapest_startup != cheapest_total)
    2032           48 :                 startup_neq_total = true;
    2033              : 
    2034              :             /*
    2035              :              * Collect the appropriate child paths.  The required logic varies
    2036              :              * for the Append and MergeAppend cases.
    2037              :              */
    2038        15848 :             if (match_partition_order)
    2039              :             {
    2040              :                 /*
    2041              :                  * We're going to make a plain Append path.  We don't need
    2042              :                  * most of what accumulate_append_subpath would do, but we do
    2043              :                  * want to cut out child Appends or MergeAppends if they have
    2044              :                  * just a single subpath (and hence aren't doing anything
    2045              :                  * useful).
    2046              :                  */
    2047              :                 cheapest_startup =
    2048         3345 :                     get_singleton_append_subpath(cheapest_startup,
    2049              :                                                  &startup.child_append_relid_sets);
    2050              :                 cheapest_total =
    2051         3345 :                     get_singleton_append_subpath(cheapest_total,
    2052              :                                                  &total.child_append_relid_sets);
    2053              : 
    2054         3345 :                 startup.subpaths = lappend(startup.subpaths, cheapest_startup);
    2055         3345 :                 total.subpaths = lappend(total.subpaths, cheapest_total);
    2056              : 
    2057         3345 :                 if (cheapest_fractional)
    2058              :                 {
    2059              :                     cheapest_fractional =
    2060           72 :                         get_singleton_append_subpath(cheapest_fractional,
    2061              :                                                      &fractional.child_append_relid_sets);
    2062           72 :                     fractional.subpaths =
    2063           72 :                         lappend(fractional.subpaths, cheapest_fractional);
    2064              :                 }
    2065              :             }
    2066              :             else
    2067              :             {
    2068              :                 /*
    2069              :                  * Otherwise, rely on accumulate_append_subpath to collect the
    2070              :                  * child paths for the MergeAppend.
    2071              :                  */
    2072        12503 :                 accumulate_append_subpath(cheapest_startup,
    2073              :                                           &startup.subpaths, NULL,
    2074              :                                           &startup.child_append_relid_sets);
    2075        12503 :                 accumulate_append_subpath(cheapest_total,
    2076              :                                           &total.subpaths, NULL,
    2077              :                                           &total.child_append_relid_sets);
    2078              : 
    2079        12503 :                 if (cheapest_fractional)
    2080          376 :                     accumulate_append_subpath(cheapest_fractional,
    2081              :                                               &fractional.subpaths, NULL,
    2082              :                                               &fractional.child_append_relid_sets);
    2083              :             }
    2084              :         }
    2085              : 
    2086              :         /* ... and build the Append or MergeAppend paths */
    2087         6116 :         if (match_partition_order)
    2088              :         {
    2089              :             /* We only need Append */
    2090         1256 :             add_path(rel, (Path *) create_append_path(root,
    2091              :                                                       rel,
    2092              :                                                       startup,
    2093              :                                                       pathkeys,
    2094              :                                                       NULL,
    2095              :                                                       0,
    2096              :                                                       false,
    2097              :                                                       -1));
    2098         1256 :             if (startup_neq_total)
    2099            0 :                 add_path(rel, (Path *) create_append_path(root,
    2100              :                                                           rel,
    2101              :                                                           total,
    2102              :                                                           pathkeys,
    2103              :                                                           NULL,
    2104              :                                                           0,
    2105              :                                                           false,
    2106              :                                                           -1));
    2107              : 
    2108         1256 :             if (fractional.subpaths && fraction_neq_total)
    2109            0 :                 add_path(rel, (Path *) create_append_path(root,
    2110              :                                                           rel,
    2111              :                                                           fractional,
    2112              :                                                           pathkeys,
    2113              :                                                           NULL,
    2114              :                                                           0,
    2115              :                                                           false,
    2116              :                                                           -1));
    2117              :         }
    2118              :         else
    2119              :         {
    2120              :             /* We need MergeAppend */
    2121         4860 :             add_path(rel, (Path *) create_merge_append_path(root,
    2122              :                                                             rel,
    2123              :                                                             startup.subpaths,
    2124              :                                                             startup.child_append_relid_sets,
    2125              :                                                             pathkeys,
    2126              :                                                             NULL));
    2127         4860 :             if (startup_neq_total)
    2128           30 :                 add_path(rel, (Path *) create_merge_append_path(root,
    2129              :                                                                 rel,
    2130              :                                                                 total.subpaths,
    2131              :                                                                 total.child_append_relid_sets,
    2132              :                                                                 pathkeys,
    2133              :                                                                 NULL));
    2134              : 
    2135         4860 :             if (fractional.subpaths && fraction_neq_total)
    2136            0 :                 add_path(rel, (Path *) create_merge_append_path(root,
    2137              :                                                                 rel,
    2138              :                                                                 fractional.subpaths,
    2139              :                                                                 fractional.child_append_relid_sets,
    2140              :                                                                 pathkeys,
    2141              :                                                                 NULL));
    2142              :         }
    2143              :     }
    2144        23823 : }
    2145              : 
    2146              : /*
    2147              :  * get_cheapest_parameterized_child_path
    2148              :  *      Get cheapest path for this relation that has exactly the requested
    2149              :  *      parameterization.
    2150              :  *
    2151              :  * Returns NULL if unable to create such a path.
    2152              :  */
    2153              : static Path *
    2154         3483 : get_cheapest_parameterized_child_path(PlannerInfo *root, RelOptInfo *rel,
    2155              :                                       Relids required_outer)
    2156              : {
    2157              :     Path       *cheapest;
    2158              :     ListCell   *lc;
    2159              : 
    2160              :     /*
    2161              :      * Look up the cheapest existing path with no more than the needed
    2162              :      * parameterization.  If it has exactly the needed parameterization, we're
    2163              :      * done.
    2164              :      */
    2165         3483 :     cheapest = get_cheapest_path_for_pathkeys(rel->pathlist,
    2166              :                                               NIL,
    2167              :                                               required_outer,
    2168              :                                               TOTAL_COST,
    2169              :                                               false);
    2170              :     Assert(cheapest != NULL);
    2171         3483 :     if (bms_equal(PATH_REQ_OUTER(cheapest), required_outer))
    2172         3313 :         return cheapest;
    2173              : 
    2174              :     /*
    2175              :      * Otherwise, we can "reparameterize" an existing path to match the given
    2176              :      * parameterization, which effectively means pushing down additional
    2177              :      * joinquals to be checked within the path's scan.  However, some existing
    2178              :      * paths might check the available joinquals already while others don't;
    2179              :      * therefore, it's not clear which existing path will be cheapest after
    2180              :      * reparameterization.  We have to go through them all and find out.
    2181              :      */
    2182          170 :     cheapest = NULL;
    2183          590 :     foreach(lc, rel->pathlist)
    2184              :     {
    2185          420 :         Path       *path = (Path *) lfirst(lc);
    2186              : 
    2187              :         /* Can't use it if it needs more than requested parameterization */
    2188          420 :         if (!bms_is_subset(PATH_REQ_OUTER(path), required_outer))
    2189           12 :             continue;
    2190              : 
    2191              :         /*
    2192              :          * Reparameterization can only increase the path's cost, so if it's
    2193              :          * already more expensive than the current cheapest, forget it.
    2194              :          */
    2195          636 :         if (cheapest != NULL &&
    2196          228 :             compare_path_costs(cheapest, path, TOTAL_COST) <= 0)
    2197          192 :             continue;
    2198              : 
    2199              :         /* Reparameterize if needed, then recheck cost */
    2200          216 :         if (!bms_equal(PATH_REQ_OUTER(path), required_outer))
    2201              :         {
    2202          178 :             path = reparameterize_path(root, path, required_outer, 1.0);
    2203          178 :             if (path == NULL)
    2204           16 :                 continue;       /* failed to reparameterize this one */
    2205              :             Assert(bms_equal(PATH_REQ_OUTER(path), required_outer));
    2206              : 
    2207          162 :             if (cheapest != NULL &&
    2208            0 :                 compare_path_costs(cheapest, path, TOTAL_COST) <= 0)
    2209            0 :                 continue;
    2210              :         }
    2211              : 
    2212              :         /* We have a new best path */
    2213          200 :         cheapest = path;
    2214              :     }
    2215              : 
    2216              :     /* Return the best path, or NULL if we found no suitable candidate */
    2217          170 :     return cheapest;
    2218              : }
    2219              : 
    2220              : /*
    2221              :  * accumulate_append_subpath
    2222              :  *      Add a subpath to the list being built for an Append or MergeAppend.
    2223              :  *
    2224              :  * It's possible that the child is itself an Append or MergeAppend path, in
    2225              :  * which case we can "cut out the middleman" and just add its child paths to
    2226              :  * our own list.  (We don't try to do this earlier because we need to apply
    2227              :  * both levels of transformation to the quals.)
    2228              :  *
    2229              :  * Note that if we omit a child MergeAppend in this way, we are effectively
    2230              :  * omitting a sort step, which seems fine: if the parent is to be an Append,
    2231              :  * its result would be unsorted anyway, while if the parent is to be a
    2232              :  * MergeAppend, there's no point in a separate sort on a child.
    2233              :  *
    2234              :  * Normally, either path is a partial path and subpaths is a list of partial
    2235              :  * paths, or else path is a non-partial plan and subpaths is a list of those.
    2236              :  * However, if path is a parallel-aware Append, then we add its partial path
    2237              :  * children to subpaths and the rest to special_subpaths.  If the latter is
    2238              :  * NULL, we don't flatten the path at all (unless it contains only partial
    2239              :  * paths).
    2240              :  */
    2241              : static void
    2242       156055 : accumulate_append_subpath(Path *path, List **subpaths, List **special_subpaths,
    2243              :                           List **child_append_relid_sets)
    2244              : {
    2245       156055 :     if (IsA(path, AppendPath))
    2246              :     {
    2247         7894 :         AppendPath *apath = (AppendPath *) path;
    2248              : 
    2249         7894 :         if (!apath->path.parallel_aware || apath->first_partial_path == 0)
    2250              :         {
    2251         7726 :             *subpaths = list_concat(*subpaths, apath->subpaths);
    2252         7726 :             *child_append_relid_sets =
    2253         7726 :                 lappend(*child_append_relid_sets, path->parent->relids);
    2254         7726 :             *child_append_relid_sets =
    2255         7726 :                 list_concat(*child_append_relid_sets,
    2256         7726 :                             apath->child_append_relid_sets);
    2257         7726 :             return;
    2258              :         }
    2259          168 :         else if (special_subpaths != NULL)
    2260              :         {
    2261              :             List       *new_special_subpaths;
    2262              : 
    2263              :             /* Split Parallel Append into partial and non-partial subpaths */
    2264           84 :             *subpaths = list_concat(*subpaths,
    2265           84 :                                     list_copy_tail(apath->subpaths,
    2266              :                                                    apath->first_partial_path));
    2267           84 :             new_special_subpaths = list_copy_head(apath->subpaths,
    2268              :                                                   apath->first_partial_path);
    2269           84 :             *special_subpaths = list_concat(*special_subpaths,
    2270              :                                             new_special_subpaths);
    2271           84 :             *child_append_relid_sets =
    2272           84 :                 lappend(*child_append_relid_sets, path->parent->relids);
    2273           84 :             *child_append_relid_sets =
    2274           84 :                 list_concat(*child_append_relid_sets,
    2275           84 :                             apath->child_append_relid_sets);
    2276           84 :             return;
    2277              :         }
    2278              :     }
    2279       148161 :     else if (IsA(path, MergeAppendPath))
    2280              :     {
    2281          538 :         MergeAppendPath *mpath = (MergeAppendPath *) path;
    2282              : 
    2283          538 :         *subpaths = list_concat(*subpaths, mpath->subpaths);
    2284          538 :         *child_append_relid_sets =
    2285          538 :             lappend(*child_append_relid_sets, path->parent->relids);
    2286          538 :         *child_append_relid_sets =
    2287          538 :             list_concat(*child_append_relid_sets,
    2288          538 :                         mpath->child_append_relid_sets);
    2289          538 :         return;
    2290              :     }
    2291              : 
    2292       147707 :     *subpaths = lappend(*subpaths, path);
    2293              : }
    2294              : 
    2295              : /*
    2296              :  * get_singleton_append_subpath
    2297              :  *      Returns the single subpath of an Append/MergeAppend, or just
    2298              :  *      return 'path' if it's not a single sub-path Append/MergeAppend.
    2299              :  *
    2300              :  * As a side effect, whenever we return a single subpath rather than the
    2301              :  * original path, add the relid sets for the original path to
    2302              :  * child_append_relid_sets, so that those relids don't entirely disappear
    2303              :  * from the final plan.
    2304              :  *
    2305              :  * Note: 'path' must not be a parallel-aware path.
    2306              :  */
    2307              : static Path *
    2308         6762 : get_singleton_append_subpath(Path *path, List **child_append_relid_sets)
    2309              : {
    2310              :     Assert(!path->parallel_aware);
    2311              : 
    2312         6762 :     if (IsA(path, AppendPath))
    2313              :     {
    2314          206 :         AppendPath *apath = (AppendPath *) path;
    2315              : 
    2316          206 :         if (list_length(apath->subpaths) == 1)
    2317              :         {
    2318          108 :             *child_append_relid_sets =
    2319          108 :                 lappend(*child_append_relid_sets, path->parent->relids);
    2320          108 :             *child_append_relid_sets =
    2321          108 :                 list_concat(*child_append_relid_sets,
    2322          108 :                             apath->child_append_relid_sets);
    2323          108 :             return (Path *) linitial(apath->subpaths);
    2324              :         }
    2325              :     }
    2326         6556 :     else if (IsA(path, MergeAppendPath))
    2327              :     {
    2328          174 :         MergeAppendPath *mpath = (MergeAppendPath *) path;
    2329              : 
    2330          174 :         if (list_length(mpath->subpaths) == 1)
    2331              :         {
    2332            0 :             *child_append_relid_sets =
    2333            0 :                 lappend(*child_append_relid_sets, path->parent->relids);
    2334            0 :             *child_append_relid_sets =
    2335            0 :                 list_concat(*child_append_relid_sets,
    2336            0 :                             mpath->child_append_relid_sets);
    2337            0 :             return (Path *) linitial(mpath->subpaths);
    2338              :         }
    2339              :     }
    2340              : 
    2341         6654 :     return path;
    2342              : }
    2343              : 
    2344              : /*
    2345              :  * set_dummy_rel_pathlist
    2346              :  *    Build a dummy path for a relation that's been excluded by constraints
    2347              :  *
    2348              :  * Rather than inventing a special "dummy" path type, we represent this as an
    2349              :  * AppendPath with no members (see also IS_DUMMY_APPEND/IS_DUMMY_REL macros).
    2350              :  *
    2351              :  * (See also mark_dummy_rel, which does basically the same thing, but is
    2352              :  * typically used to change a rel into dummy state after we already made
    2353              :  * paths for it.)
    2354              :  */
    2355              : static void
    2356          700 : set_dummy_rel_pathlist(RelOptInfo *rel)
    2357              : {
    2358          700 :     AppendPathInput in = {0};
    2359              : 
    2360              :     /* Set dummy size estimates --- we leave attr_widths[] as zeroes */
    2361          700 :     rel->rows = 0;
    2362          700 :     rel->reltarget->width = 0;
    2363              : 
    2364              :     /* Discard any pre-existing paths; no further need for them */
    2365          700 :     rel->pathlist = NIL;
    2366          700 :     rel->partial_pathlist = NIL;
    2367              : 
    2368              :     /* Set up the dummy path */
    2369          700 :     add_path(rel, (Path *) create_append_path(NULL, rel, in,
    2370              :                                               NIL, rel->lateral_relids,
    2371              :                                               0, false, -1));
    2372              : 
    2373              :     /*
    2374              :      * We set the cheapest-path fields immediately, just in case they were
    2375              :      * pointing at some discarded path.  This is redundant in current usage
    2376              :      * because set_rel_pathlist will do it later, but it's cheap so we keep it
    2377              :      * for safety and consistency with mark_dummy_rel.
    2378              :      */
    2379          700 :     set_cheapest(rel);
    2380          700 : }
    2381              : 
    2382              : /*
    2383              :  * find_window_run_conditions
    2384              :  *      Determine if 'wfunc' is really a WindowFunc and call its prosupport
    2385              :  *      function to determine the function's monotonic properties.  We then
    2386              :  *      see if 'opexpr' can be used to short-circuit execution.
    2387              :  *
    2388              :  * For example row_number() over (order by ...) always produces a value one
    2389              :  * higher than the previous.  If someone has a window function in a subquery
    2390              :  * and has a WHERE clause in the outer query to filter rows <= 10, then we may
    2391              :  * as well stop processing the windowagg once the row number reaches 11.  Here
    2392              :  * we check if 'opexpr' might help us to stop doing needless extra processing
    2393              :  * in WindowAgg nodes.
    2394              :  *
    2395              :  * '*keep_original' is set to true if the caller should also use 'opexpr' for
    2396              :  * its original purpose.  This is set to false if the caller can assume that
    2397              :  * the run condition will handle all of the required filtering.
    2398              :  *
    2399              :  * Returns true if 'opexpr' was found to be useful and was added to the
    2400              :  * WindowFunc's runCondition.  We also set *keep_original accordingly and add
    2401              :  * 'attno' to *run_cond_attrs offset by FirstLowInvalidHeapAttributeNumber.
    2402              :  * If the 'opexpr' cannot be used then we set *keep_original to true and
    2403              :  * return false.
    2404              :  */
    2405              : static bool
    2406          120 : find_window_run_conditions(Query *subquery, AttrNumber attno,
    2407              :                            WindowFunc *wfunc, OpExpr *opexpr, bool wfunc_left,
    2408              :                            bool *keep_original, Bitmapset **run_cond_attrs)
    2409              : {
    2410              :     Oid         prosupport;
    2411              :     Expr       *otherexpr;
    2412              :     SupportRequestWFuncMonotonic req;
    2413              :     SupportRequestWFuncMonotonic *res;
    2414              :     WindowClause *wclause;
    2415              :     List       *opinfos;
    2416              :     OpExpr     *runopexpr;
    2417              :     Oid         runoperator;
    2418              :     ListCell   *lc;
    2419              : 
    2420          120 :     *keep_original = true;
    2421              : 
    2422          120 :     while (IsA(wfunc, RelabelType))
    2423            0 :         wfunc = (WindowFunc *) ((RelabelType *) wfunc)->arg;
    2424              : 
    2425              :     /* we can only work with window functions */
    2426          120 :     if (!IsA(wfunc, WindowFunc))
    2427           12 :         return false;
    2428              : 
    2429              :     /* can't use it if there are subplans in the WindowFunc */
    2430          108 :     if (contain_subplans((Node *) wfunc))
    2431            3 :         return false;
    2432              : 
    2433          105 :     prosupport = get_func_support(wfunc->winfnoid);
    2434              : 
    2435              :     /* Check if there's a support function for 'wfunc' */
    2436          105 :     if (!OidIsValid(prosupport))
    2437            9 :         return false;
    2438              : 
    2439              :     /* get the Expr from the other side of the OpExpr */
    2440           96 :     if (wfunc_left)
    2441           84 :         otherexpr = lsecond(opexpr->args);
    2442              :     else
    2443           12 :         otherexpr = linitial(opexpr->args);
    2444              : 
    2445              :     /*
    2446              :      * The value being compared must not change during the evaluation of the
    2447              :      * window partition.
    2448              :      */
    2449           96 :     if (!is_pseudo_constant_clause((Node *) otherexpr))
    2450            0 :         return false;
    2451              : 
    2452              :     /* find the window clause belonging to the window function */
    2453           96 :     wclause = (WindowClause *) list_nth(subquery->windowClause,
    2454           96 :                                         wfunc->winref - 1);
    2455              : 
    2456           96 :     req.type = T_SupportRequestWFuncMonotonic;
    2457           96 :     req.window_func = wfunc;
    2458           96 :     req.window_clause = wclause;
    2459              : 
    2460              :     /* call the support function */
    2461              :     res = (SupportRequestWFuncMonotonic *)
    2462           96 :         DatumGetPointer(OidFunctionCall1(prosupport,
    2463              :                                          PointerGetDatum(&req)));
    2464              : 
    2465              :     /*
    2466              :      * Nothing to do if the function is neither monotonically increasing nor
    2467              :      * monotonically decreasing.
    2468              :      */
    2469           96 :     if (res == NULL || res->monotonic == MONOTONICFUNC_NONE)
    2470            0 :         return false;
    2471              : 
    2472           96 :     runopexpr = NULL;
    2473           96 :     runoperator = InvalidOid;
    2474           96 :     opinfos = get_op_index_interpretation(opexpr->opno);
    2475              : 
    2476           96 :     foreach(lc, opinfos)
    2477              :     {
    2478           96 :         OpIndexInterpretation *opinfo = (OpIndexInterpretation *) lfirst(lc);
    2479           96 :         CompareType cmptype = opinfo->cmptype;
    2480              : 
    2481              :         /* handle < / <= */
    2482           96 :         if (cmptype == COMPARE_LT || cmptype == COMPARE_LE)
    2483              :         {
    2484              :             /*
    2485              :              * < / <= is supported for monotonically increasing functions in
    2486              :              * the form <wfunc> op <pseudoconst> and <pseudoconst> op <wfunc>
    2487              :              * for monotonically decreasing functions.
    2488              :              */
    2489           69 :             if ((wfunc_left && (res->monotonic & MONOTONICFUNC_INCREASING)) ||
    2490            9 :                 (!wfunc_left && (res->monotonic & MONOTONICFUNC_DECREASING)))
    2491              :             {
    2492           63 :                 *keep_original = false;
    2493           63 :                 runopexpr = opexpr;
    2494           63 :                 runoperator = opexpr->opno;
    2495              :             }
    2496           69 :             break;
    2497              :         }
    2498              :         /* handle > / >= */
    2499           27 :         else if (cmptype == COMPARE_GT || cmptype == COMPARE_GE)
    2500              :         {
    2501              :             /*
    2502              :              * > / >= is supported for monotonically decreasing functions in
    2503              :              * the form <wfunc> op <pseudoconst> and <pseudoconst> op <wfunc>
    2504              :              * for monotonically increasing functions.
    2505              :              */
    2506            9 :             if ((wfunc_left && (res->monotonic & MONOTONICFUNC_DECREASING)) ||
    2507            6 :                 (!wfunc_left && (res->monotonic & MONOTONICFUNC_INCREASING)))
    2508              :             {
    2509            9 :                 *keep_original = false;
    2510            9 :                 runopexpr = opexpr;
    2511            9 :                 runoperator = opexpr->opno;
    2512              :             }
    2513            9 :             break;
    2514              :         }
    2515              :         /* handle = */
    2516           18 :         else if (cmptype == COMPARE_EQ)
    2517              :         {
    2518              :             CompareType newcmptype;
    2519              : 
    2520              :             /*
    2521              :              * When both monotonically increasing and decreasing then the
    2522              :              * return value of the window function will be the same each time.
    2523              :              * We can simply use 'opexpr' as the run condition without
    2524              :              * modifying it.
    2525              :              */
    2526           18 :             if ((res->monotonic & MONOTONICFUNC_BOTH) == MONOTONICFUNC_BOTH)
    2527              :             {
    2528            3 :                 *keep_original = false;
    2529            3 :                 runopexpr = opexpr;
    2530            3 :                 runoperator = opexpr->opno;
    2531            3 :                 break;
    2532              :             }
    2533              : 
    2534              :             /*
    2535              :              * When monotonically increasing we make a qual with <wfunc> <=
    2536              :              * <value> or <value> >= <wfunc> in order to filter out values
    2537              :              * which are above the value in the equality condition.  For
    2538              :              * monotonically decreasing functions we want to filter values
    2539              :              * below the value in the equality condition.
    2540              :              */
    2541           15 :             if (res->monotonic & MONOTONICFUNC_INCREASING)
    2542           15 :                 newcmptype = wfunc_left ? COMPARE_LE : COMPARE_GE;
    2543              :             else
    2544            0 :                 newcmptype = wfunc_left ? COMPARE_GE : COMPARE_LE;
    2545              : 
    2546              :             /* We must keep the original equality qual */
    2547           15 :             *keep_original = true;
    2548           15 :             runopexpr = opexpr;
    2549              : 
    2550              :             /* determine the operator to use for the WindowFuncRunCondition */
    2551           15 :             runoperator = get_opfamily_member_for_cmptype(opinfo->opfamily_id,
    2552              :                                                           opinfo->oplefttype,
    2553              :                                                           opinfo->oprighttype,
    2554              :                                                           newcmptype);
    2555           15 :             break;
    2556              :         }
    2557              :     }
    2558              : 
    2559           96 :     if (runopexpr != NULL)
    2560              :     {
    2561              :         WindowFuncRunCondition *wfuncrc;
    2562              : 
    2563           90 :         wfuncrc = makeNode(WindowFuncRunCondition);
    2564           90 :         wfuncrc->opno = runoperator;
    2565           90 :         wfuncrc->inputcollid = runopexpr->inputcollid;
    2566           90 :         wfuncrc->wfunc_left = wfunc_left;
    2567           90 :         wfuncrc->arg = copyObject(otherexpr);
    2568              : 
    2569           90 :         wfunc->runCondition = lappend(wfunc->runCondition, wfuncrc);
    2570              : 
    2571              :         /* record that this attno was used in a run condition */
    2572           90 :         *run_cond_attrs = bms_add_member(*run_cond_attrs,
    2573              :                                          attno - FirstLowInvalidHeapAttributeNumber);
    2574           90 :         return true;
    2575              :     }
    2576              : 
    2577              :     /* unsupported OpExpr */
    2578            6 :     return false;
    2579              : }
    2580              : 
    2581              : /*
    2582              :  * check_and_push_window_quals
    2583              :  *      Check if 'clause' is a qual that can be pushed into a WindowFunc
    2584              :  *      as a 'runCondition' qual.  These, when present, allow some unnecessary
    2585              :  *      work to be skipped during execution.
    2586              :  *
    2587              :  * 'run_cond_attrs' will be populated with all targetlist resnos of subquery
    2588              :  * targets (offset by FirstLowInvalidHeapAttributeNumber) that we pushed
    2589              :  * window quals for.
    2590              :  *
    2591              :  * Returns true if the caller still must keep the original qual or false if
    2592              :  * the caller can safely ignore the original qual because the WindowAgg node
    2593              :  * will use the runCondition to stop returning tuples.
    2594              :  */
    2595              : static bool
    2596          126 : check_and_push_window_quals(Query *subquery, Node *clause,
    2597              :                             Bitmapset **run_cond_attrs)
    2598              : {
    2599          126 :     OpExpr     *opexpr = (OpExpr *) clause;
    2600          126 :     bool        keep_original = true;
    2601              :     Var        *var1;
    2602              :     Var        *var2;
    2603              : 
    2604              :     /* We're only able to use OpExprs with 2 operands */
    2605          126 :     if (!IsA(opexpr, OpExpr))
    2606            9 :         return true;
    2607              : 
    2608          117 :     if (list_length(opexpr->args) != 2)
    2609            0 :         return true;
    2610              : 
    2611              :     /*
    2612              :      * Currently, we restrict this optimization to strict OpExprs.  The reason
    2613              :      * for this is that during execution, once the runcondition becomes false,
    2614              :      * we stop evaluating WindowFuncs.  To avoid leaving around stale window
    2615              :      * function result values, we set them to NULL.  Having only strict
    2616              :      * OpExprs here ensures that we properly filter out the tuples with NULLs
    2617              :      * in the top-level WindowAgg.
    2618              :      */
    2619          117 :     set_opfuncid(opexpr);
    2620          117 :     if (!func_strict(opexpr->opfuncid))
    2621            0 :         return true;
    2622              : 
    2623              :     /*
    2624              :      * Check for plain Vars that reference window functions in the subquery.
    2625              :      * If we find any, we'll ask find_window_run_conditions() if 'opexpr' can
    2626              :      * be used as part of the run condition.
    2627              :      */
    2628              : 
    2629              :     /* Check the left side of the OpExpr */
    2630          117 :     var1 = linitial(opexpr->args);
    2631          117 :     if (IsA(var1, Var) && var1->varattno > 0)
    2632              :     {
    2633           99 :         TargetEntry *tle = list_nth(subquery->targetList, var1->varattno - 1);
    2634           99 :         WindowFunc *wfunc = (WindowFunc *) tle->expr;
    2635              : 
    2636           99 :         if (find_window_run_conditions(subquery, tle->resno, wfunc, opexpr,
    2637              :                                        true, &keep_original, run_cond_attrs))
    2638           81 :             return keep_original;
    2639              :     }
    2640              : 
    2641              :     /* and check the right side */
    2642           36 :     var2 = lsecond(opexpr->args);
    2643           36 :     if (IsA(var2, Var) && var2->varattno > 0)
    2644              :     {
    2645           21 :         TargetEntry *tle = list_nth(subquery->targetList, var2->varattno - 1);
    2646           21 :         WindowFunc *wfunc = (WindowFunc *) tle->expr;
    2647              : 
    2648           21 :         if (find_window_run_conditions(subquery, tle->resno, wfunc, opexpr,
    2649              :                                        false, &keep_original, run_cond_attrs))
    2650            9 :             return keep_original;
    2651              :     }
    2652              : 
    2653           27 :     return true;
    2654              : }
    2655              : 
    2656              : /*
    2657              :  * set_subquery_pathlist
    2658              :  *      Generate SubqueryScan access paths for a subquery RTE
    2659              :  *
    2660              :  * We don't currently support generating parameterized paths for subqueries
    2661              :  * by pushing join clauses down into them; it seems too expensive to re-plan
    2662              :  * the subquery multiple times to consider different alternatives.
    2663              :  * (XXX that could stand to be reconsidered, now that we use Paths.)
    2664              :  * So the paths made here will be parameterized if the subquery contains
    2665              :  * LATERAL references, otherwise not.  As long as that's true, there's no need
    2666              :  * for a separate set_subquery_size phase: just make the paths right away.
    2667              :  */
    2668              : static void
    2669        13383 : set_subquery_pathlist(PlannerInfo *root, RelOptInfo *rel,
    2670              :                       Index rti, RangeTblEntry *rte)
    2671              : {
    2672        13383 :     Query      *parse = root->parse;
    2673        13383 :     Query      *subquery = rte->subquery;
    2674              :     bool        trivial_pathtarget;
    2675              :     Relids      required_outer;
    2676              :     pushdown_safety_info safetyInfo;
    2677              :     double      tuple_fraction;
    2678              :     RelOptInfo *sub_final_rel;
    2679        13383 :     Bitmapset  *run_cond_attrs = NULL;
    2680              :     ListCell   *lc;
    2681              :     char       *plan_name;
    2682              : 
    2683              :     /*
    2684              :      * Must copy the Query so that planning doesn't mess up the RTE contents
    2685              :      * (really really need to fix the planner to not scribble on its input,
    2686              :      * someday ... but see remove_unused_subquery_outputs to start with).
    2687              :      */
    2688        13383 :     subquery = copyObject(subquery);
    2689              : 
    2690              :     /*
    2691              :      * If it's a LATERAL subquery, it might contain some Vars of the current
    2692              :      * query level, requiring it to be treated as parameterized, even though
    2693              :      * we don't support pushing down join quals into subqueries.
    2694              :      */
    2695        13383 :     required_outer = rel->lateral_relids;
    2696              : 
    2697              :     /*
    2698              :      * Zero out result area for subquery_is_pushdown_safe, so that it can set
    2699              :      * flags as needed while recursing.  In particular, we need a workspace
    2700              :      * for keeping track of the reasons why columns are unsafe to reference.
    2701              :      * These reasons are stored in the bits inside unsafeFlags[i] when we
    2702              :      * discover reasons that column i of the subquery is unsafe to be used in
    2703              :      * a pushed-down qual.
    2704              :      */
    2705        13383 :     memset(&safetyInfo, 0, sizeof(safetyInfo));
    2706        13383 :     safetyInfo.unsafeFlags = (unsigned char *)
    2707        13383 :         palloc0((list_length(subquery->targetList) + 1) * sizeof(unsigned char));
    2708              : 
    2709              :     /*
    2710              :      * If the subquery has the "security_barrier" flag, it means the subquery
    2711              :      * originated from a view that must enforce row-level security.  Then we
    2712              :      * must not push down quals that contain leaky functions.  (Ideally this
    2713              :      * would be checked inside subquery_is_pushdown_safe, but since we don't
    2714              :      * currently pass the RTE to that function, we must do it here.)
    2715              :      */
    2716        13383 :     safetyInfo.unsafeLeaky = rte->security_barrier;
    2717              : 
    2718              :     /*
    2719              :      * If there are any restriction clauses that have been attached to the
    2720              :      * subquery relation, consider pushing them down to become WHERE or HAVING
    2721              :      * quals of the subquery itself.  This transformation is useful because it
    2722              :      * may allow us to generate a better plan for the subquery than evaluating
    2723              :      * all the subquery output rows and then filtering them.
    2724              :      *
    2725              :      * There are several cases where we cannot push down clauses. Restrictions
    2726              :      * involving the subquery are checked by subquery_is_pushdown_safe().
    2727              :      * Restrictions on individual clauses are checked by
    2728              :      * qual_is_pushdown_safe().  Also, we don't want to push down
    2729              :      * pseudoconstant clauses; better to have the gating node above the
    2730              :      * subquery.
    2731              :      *
    2732              :      * Non-pushed-down clauses will get evaluated as qpquals of the
    2733              :      * SubqueryScan node.
    2734              :      *
    2735              :      * XXX Are there any cases where we want to make a policy decision not to
    2736              :      * push down a pushable qual, because it'd result in a worse plan?
    2737              :      */
    2738        14944 :     if (rel->baserestrictinfo != NIL &&
    2739         1561 :         subquery_is_pushdown_safe(subquery, subquery, &safetyInfo))
    2740              :     {
    2741              :         /* OK to consider pushing down individual quals */
    2742         1488 :         List       *upperrestrictlist = NIL;
    2743              :         ListCell   *l;
    2744              : 
    2745         3998 :         foreach(l, rel->baserestrictinfo)
    2746              :         {
    2747         2510 :             RestrictInfo *rinfo = (RestrictInfo *) lfirst(l);
    2748         2510 :             Node       *clause = (Node *) rinfo->clause;
    2749              : 
    2750         2510 :             if (rinfo->pseudoconstant)
    2751              :             {
    2752            2 :                 upperrestrictlist = lappend(upperrestrictlist, rinfo);
    2753            2 :                 continue;
    2754              :             }
    2755              : 
    2756         2508 :             switch (qual_is_pushdown_safe(subquery, rti, rinfo, &safetyInfo))
    2757              :             {
    2758         1956 :                 case PUSHDOWN_SAFE:
    2759              :                     /* Push it down */
    2760         1956 :                     subquery_push_qual(subquery, rte, rti, clause);
    2761         1956 :                     break;
    2762              : 
    2763          126 :                 case PUSHDOWN_WINDOWCLAUSE_RUNCOND:
    2764              : 
    2765              :                     /*
    2766              :                      * Since we can't push the qual down into the subquery,
    2767              :                      * check if it happens to reference a window function.  If
    2768              :                      * so then it might be useful to use for the WindowAgg's
    2769              :                      * runCondition.
    2770              :                      */
    2771          252 :                     if (!subquery->hasWindowFuncs ||
    2772          126 :                         check_and_push_window_quals(subquery, clause,
    2773              :                                                     &run_cond_attrs))
    2774              :                     {
    2775              :                         /*
    2776              :                          * subquery has no window funcs or the clause is not a
    2777              :                          * suitable window run condition qual or it is, but
    2778              :                          * the original must also be kept in the upper query.
    2779              :                          */
    2780           51 :                         upperrestrictlist = lappend(upperrestrictlist, rinfo);
    2781              :                     }
    2782          126 :                     break;
    2783              : 
    2784          426 :                 case PUSHDOWN_UNSAFE:
    2785          426 :                     upperrestrictlist = lappend(upperrestrictlist, rinfo);
    2786          426 :                     break;
    2787              :             }
    2788              :         }
    2789         1488 :         rel->baserestrictinfo = upperrestrictlist;
    2790              :         /* We don't bother recomputing baserestrict_min_security */
    2791              :     }
    2792              : 
    2793        13383 :     pfree(safetyInfo.unsafeFlags);
    2794              : 
    2795              :     /*
    2796              :      * The upper query might not use all the subquery's output columns; if
    2797              :      * not, we can simplify.  Pass the attributes that were pushed down into
    2798              :      * WindowAgg run conditions to ensure we don't accidentally think those
    2799              :      * are unused.
    2800              :      */
    2801        13383 :     remove_unused_subquery_outputs(subquery, rel, run_cond_attrs);
    2802              : 
    2803              :     /*
    2804              :      * We can safely pass the outer tuple_fraction down to the subquery if the
    2805              :      * outer level has no joining, aggregation, or sorting to do. Otherwise
    2806              :      * we'd better tell the subquery to plan for full retrieval. (XXX This
    2807              :      * could probably be made more intelligent ...)
    2808              :      */
    2809        13383 :     if (parse->hasAggs ||
    2810         9832 :         parse->groupClause ||
    2811         9823 :         parse->groupingSets ||
    2812         9823 :         root->hasHavingQual ||
    2813         9823 :         parse->distinctClause ||
    2814        13245 :         parse->sortClause ||
    2815         3686 :         bms_membership(root->all_baserels) == BMS_MULTIPLE)
    2816        10707 :         tuple_fraction = 0.0;   /* default case */
    2817              :     else
    2818         2676 :         tuple_fraction = root->tuple_fraction;
    2819              : 
    2820              :     /* plan_params should not be in use in current query level */
    2821              :     Assert(root->plan_params == NIL);
    2822              : 
    2823              :     /* Generate a subroot and Paths for the subquery */
    2824        13383 :     plan_name = choose_plan_name(root->glob, rte->eref->aliasname, false);
    2825        13383 :     rel->subroot = subquery_planner(root->glob, subquery, plan_name,
    2826              :                                     root, false, tuple_fraction, NULL);
    2827              : 
    2828              :     /* Isolate the params needed by this specific subplan */
    2829        13383 :     rel->subplan_params = root->plan_params;
    2830        13383 :     root->plan_params = NIL;
    2831              : 
    2832              :     /*
    2833              :      * It's possible that constraint exclusion proved the subquery empty. If
    2834              :      * so, it's desirable to produce an unadorned dummy path so that we will
    2835              :      * recognize appropriate optimizations at this query level.
    2836              :      */
    2837        13383 :     sub_final_rel = fetch_upper_rel(rel->subroot, UPPERREL_FINAL, NULL);
    2838              : 
    2839        13383 :     if (IS_DUMMY_REL(sub_final_rel))
    2840              :     {
    2841           63 :         set_dummy_rel_pathlist(rel);
    2842           63 :         return;
    2843              :     }
    2844              : 
    2845              :     /*
    2846              :      * Mark rel with estimated output rows, width, etc.  Note that we have to
    2847              :      * do this before generating outer-query paths, else cost_subqueryscan is
    2848              :      * not happy.
    2849              :      */
    2850        13320 :     set_subquery_size_estimates(root, rel);
    2851              : 
    2852              :     /*
    2853              :      * Also detect whether the reltarget is trivial, so that we can pass that
    2854              :      * info to cost_subqueryscan (rather than re-deriving it multiple times).
    2855              :      * It's trivial if it fetches all the subplan output columns in order.
    2856              :      */
    2857        13320 :     if (list_length(rel->reltarget->exprs) != list_length(subquery->targetList))
    2858         8290 :         trivial_pathtarget = false;
    2859              :     else
    2860              :     {
    2861         5030 :         trivial_pathtarget = true;
    2862        16342 :         foreach(lc, rel->reltarget->exprs)
    2863              :         {
    2864        11461 :             Node       *node = (Node *) lfirst(lc);
    2865              :             Var        *var;
    2866              : 
    2867        11461 :             if (!IsA(node, Var))
    2868              :             {
    2869            0 :                 trivial_pathtarget = false;
    2870            0 :                 break;
    2871              :             }
    2872        11461 :             var = (Var *) node;
    2873        11461 :             if (var->varno != rti ||
    2874        11461 :                 var->varattno != foreach_current_index(lc) + 1)
    2875              :             {
    2876          149 :                 trivial_pathtarget = false;
    2877          149 :                 break;
    2878              :             }
    2879              :         }
    2880              :     }
    2881              : 
    2882              :     /*
    2883              :      * For each Path that subquery_planner produced, make a SubqueryScanPath
    2884              :      * in the outer query.
    2885              :      */
    2886        27730 :     foreach(lc, sub_final_rel->pathlist)
    2887              :     {
    2888        14410 :         Path       *subpath = (Path *) lfirst(lc);
    2889              :         List       *pathkeys;
    2890              : 
    2891              :         /* Convert subpath's pathkeys to outer representation */
    2892        14410 :         pathkeys = convert_subquery_pathkeys(root,
    2893              :                                              rel,
    2894              :                                              subpath->pathkeys,
    2895              :                                              make_tlist_from_pathtarget(subpath->pathtarget));
    2896              : 
    2897              :         /* Generate outer path using this subpath */
    2898        14410 :         add_path(rel, (Path *)
    2899        14410 :                  create_subqueryscan_path(root, rel, subpath,
    2900              :                                           trivial_pathtarget,
    2901              :                                           pathkeys, required_outer));
    2902              :     }
    2903              : 
    2904              :     /* If outer rel allows parallelism, do same for partial paths. */
    2905        13320 :     if (rel->consider_parallel && bms_is_empty(required_outer))
    2906              :     {
    2907              :         /* If consider_parallel is false, there should be no partial paths. */
    2908              :         Assert(sub_final_rel->consider_parallel ||
    2909              :                sub_final_rel->partial_pathlist == NIL);
    2910              : 
    2911              :         /* Same for partial paths. */
    2912         7881 :         foreach(lc, sub_final_rel->partial_pathlist)
    2913              :         {
    2914           27 :             Path       *subpath = (Path *) lfirst(lc);
    2915              :             List       *pathkeys;
    2916              : 
    2917              :             /* Convert subpath's pathkeys to outer representation */
    2918           27 :             pathkeys = convert_subquery_pathkeys(root,
    2919              :                                                  rel,
    2920              :                                                  subpath->pathkeys,
    2921              :                                                  make_tlist_from_pathtarget(subpath->pathtarget));
    2922              : 
    2923              :             /* Generate outer path using this subpath */
    2924           27 :             add_partial_path(rel, (Path *)
    2925           27 :                              create_subqueryscan_path(root, rel, subpath,
    2926              :                                                       trivial_pathtarget,
    2927              :                                                       pathkeys,
    2928              :                                                       required_outer));
    2929              :         }
    2930              :     }
    2931              : }
    2932              : 
    2933              : /*
    2934              :  * set_function_pathlist
    2935              :  *      Build the (single) access path for a function RTE
    2936              :  */
    2937              : static void
    2938        27429 : set_function_pathlist(PlannerInfo *root, RelOptInfo *rel, RangeTblEntry *rte)
    2939              : {
    2940              :     Relids      required_outer;
    2941        27429 :     List       *pathkeys = NIL;
    2942              : 
    2943              :     /*
    2944              :      * We don't support pushing join clauses into the quals of a function
    2945              :      * scan, but it could still have required parameterization due to LATERAL
    2946              :      * refs in the function expression.
    2947              :      */
    2948        27429 :     required_outer = rel->lateral_relids;
    2949              : 
    2950              :     /*
    2951              :      * The result is considered unordered unless ORDINALITY was used, in which
    2952              :      * case it is ordered by the ordinal column (the last one).  See if we
    2953              :      * care, by checking for uses of that Var in equivalence classes.
    2954              :      */
    2955        27429 :     if (rte->funcordinality)
    2956              :     {
    2957          477 :         AttrNumber  ordattno = rel->max_attr;
    2958          477 :         Var        *var = NULL;
    2959              :         ListCell   *lc;
    2960              : 
    2961              :         /*
    2962              :          * Is there a Var for it in rel's targetlist?  If not, the query did
    2963              :          * not reference the ordinality column, or at least not in any way
    2964              :          * that would be interesting for sorting.
    2965              :          */
    2966         1069 :         foreach(lc, rel->reltarget->exprs)
    2967              :         {
    2968         1066 :             Var        *node = (Var *) lfirst(lc);
    2969              : 
    2970              :             /* checking varno/varlevelsup is just paranoia */
    2971         1066 :             if (IsA(node, Var) &&
    2972         1066 :                 node->varattno == ordattno &&
    2973          474 :                 node->varno == rel->relid &&
    2974          474 :                 node->varlevelsup == 0)
    2975              :             {
    2976          474 :                 var = node;
    2977          474 :                 break;
    2978              :             }
    2979              :         }
    2980              : 
    2981              :         /*
    2982              :          * Try to build pathkeys for this Var with int8 sorting.  We tell
    2983              :          * build_expression_pathkey not to build any new equivalence class; if
    2984              :          * the Var isn't already mentioned in some EC, it means that nothing
    2985              :          * cares about the ordering.
    2986              :          */
    2987          477 :         if (var)
    2988          474 :             pathkeys = build_expression_pathkey(root,
    2989              :                                                 (Expr *) var,
    2990              :                                                 Int8LessOperator,
    2991              :                                                 rel->relids,
    2992              :                                                 false);
    2993              :     }
    2994              : 
    2995              :     /* Generate appropriate path */
    2996        27429 :     add_path(rel, create_functionscan_path(root, rel,
    2997              :                                            pathkeys, required_outer));
    2998        27429 : }
    2999              : 
    3000              : /*
    3001              :  * set_values_pathlist
    3002              :  *      Build the (single) access path for a VALUES RTE
    3003              :  */
    3004              : static void
    3005         4329 : set_values_pathlist(PlannerInfo *root, RelOptInfo *rel, RangeTblEntry *rte)
    3006              : {
    3007              :     Relids      required_outer;
    3008              : 
    3009              :     /*
    3010              :      * We don't support pushing join clauses into the quals of a values scan,
    3011              :      * but it could still have required parameterization due to LATERAL refs
    3012              :      * in the values expressions.
    3013              :      */
    3014         4329 :     required_outer = rel->lateral_relids;
    3015              : 
    3016              :     /* Generate appropriate path */
    3017         4329 :     add_path(rel, create_valuesscan_path(root, rel, required_outer));
    3018         4329 : }
    3019              : 
    3020              : /*
    3021              :  * set_tablefunc_pathlist
    3022              :  *      Build the (single) access path for a table func RTE
    3023              :  */
    3024              : static void
    3025          313 : set_tablefunc_pathlist(PlannerInfo *root, RelOptInfo *rel, RangeTblEntry *rte)
    3026              : {
    3027              :     Relids      required_outer;
    3028              : 
    3029              :     /*
    3030              :      * We don't support pushing join clauses into the quals of a tablefunc
    3031              :      * scan, but it could still have required parameterization due to LATERAL
    3032              :      * refs in the function expression.
    3033              :      */
    3034          313 :     required_outer = rel->lateral_relids;
    3035              : 
    3036              :     /* Generate appropriate path */
    3037          313 :     add_path(rel, create_tablefuncscan_path(root, rel,
    3038              :                                             required_outer));
    3039          313 : }
    3040              : 
    3041              : /*
    3042              :  * set_cte_pathlist
    3043              :  *      Build the (single) access path for a non-self-reference CTE RTE
    3044              :  *
    3045              :  * There's no need for a separate set_cte_size phase, since we don't
    3046              :  * support join-qual-parameterized paths for CTEs.
    3047              :  */
    3048              : static void
    3049         2378 : set_cte_pathlist(PlannerInfo *root, RelOptInfo *rel, RangeTblEntry *rte)
    3050              : {
    3051              :     Path       *ctepath;
    3052              :     Plan       *cteplan;
    3053              :     PlannerInfo *cteroot;
    3054              :     Index       levelsup;
    3055              :     List       *pathkeys;
    3056              :     int         ndx;
    3057              :     ListCell   *lc;
    3058              :     int         plan_id;
    3059              :     Relids      required_outer;
    3060              : 
    3061              :     /*
    3062              :      * Find the referenced CTE, and locate the path and plan previously made
    3063              :      * for it.
    3064              :      */
    3065         2378 :     levelsup = rte->ctelevelsup;
    3066         2378 :     cteroot = root;
    3067         4158 :     while (levelsup-- > 0)
    3068              :     {
    3069         1780 :         cteroot = cteroot->parent_root;
    3070         1780 :         if (!cteroot)           /* shouldn't happen */
    3071            0 :             elog(ERROR, "bad levelsup for CTE \"%s\"", rte->ctename);
    3072              :     }
    3073              : 
    3074              :     /*
    3075              :      * Note: cte_plan_ids can be shorter than cteList, if we are still working
    3076              :      * on planning the CTEs (ie, this is a side-reference from another CTE).
    3077              :      * So we mustn't use forboth here.
    3078              :      */
    3079         2378 :     ndx = 0;
    3080         3252 :     foreach(lc, cteroot->parse->cteList)
    3081              :     {
    3082         3252 :         CommonTableExpr *cte = (CommonTableExpr *) lfirst(lc);
    3083              : 
    3084         3252 :         if (strcmp(cte->ctename, rte->ctename) == 0)
    3085         2378 :             break;
    3086          874 :         ndx++;
    3087              :     }
    3088         2378 :     if (lc == NULL)             /* shouldn't happen */
    3089            0 :         elog(ERROR, "could not find CTE \"%s\"", rte->ctename);
    3090         2378 :     if (ndx >= list_length(cteroot->cte_plan_ids))
    3091            0 :         elog(ERROR, "could not find plan for CTE \"%s\"", rte->ctename);
    3092         2378 :     plan_id = list_nth_int(cteroot->cte_plan_ids, ndx);
    3093         2378 :     if (plan_id <= 0)
    3094            0 :         elog(ERROR, "no plan was made for CTE \"%s\"", rte->ctename);
    3095              : 
    3096              :     Assert(list_length(root->glob->subpaths) == list_length(root->glob->subplans));
    3097         2378 :     ctepath = (Path *) list_nth(root->glob->subpaths, plan_id - 1);
    3098         2378 :     cteplan = (Plan *) list_nth(root->glob->subplans, plan_id - 1);
    3099              : 
    3100              :     /* Mark rel with estimated output rows, width, etc */
    3101         2378 :     set_cte_size_estimates(root, rel, cteplan->plan_rows);
    3102              : 
    3103              :     /* Convert the ctepath's pathkeys to outer query's representation */
    3104         2378 :     pathkeys = convert_subquery_pathkeys(root,
    3105              :                                          rel,
    3106              :                                          ctepath->pathkeys,
    3107              :                                          cteplan->targetlist);
    3108              : 
    3109              :     /*
    3110              :      * We don't support pushing join clauses into the quals of a CTE scan, but
    3111              :      * it could still have required parameterization due to LATERAL refs in
    3112              :      * its tlist.
    3113              :      */
    3114         2378 :     required_outer = rel->lateral_relids;
    3115              : 
    3116              :     /* Generate appropriate path */
    3117         2378 :     add_path(rel, create_ctescan_path(root, rel, pathkeys, required_outer));
    3118         2378 : }
    3119              : 
    3120              : /*
    3121              :  * set_namedtuplestore_pathlist
    3122              :  *      Build the (single) access path for a named tuplestore RTE
    3123              :  *
    3124              :  * There's no need for a separate set_namedtuplestore_size phase, since we
    3125              :  * don't support join-qual-parameterized paths for tuplestores.
    3126              :  */
    3127              : static void
    3128          237 : set_namedtuplestore_pathlist(PlannerInfo *root, RelOptInfo *rel,
    3129              :                              RangeTblEntry *rte)
    3130              : {
    3131              :     Relids      required_outer;
    3132              : 
    3133              :     /* Mark rel with estimated output rows, width, etc */
    3134          237 :     set_namedtuplestore_size_estimates(root, rel);
    3135              : 
    3136              :     /*
    3137              :      * We don't support pushing join clauses into the quals of a tuplestore
    3138              :      * scan, but it could still have required parameterization due to LATERAL
    3139              :      * refs in its tlist.
    3140              :      */
    3141          237 :     required_outer = rel->lateral_relids;
    3142              : 
    3143              :     /* Generate appropriate path */
    3144          237 :     add_path(rel, create_namedtuplestorescan_path(root, rel, required_outer));
    3145          237 : }
    3146              : 
    3147              : /*
    3148              :  * set_result_pathlist
    3149              :  *      Build the (single) access path for an RTE_RESULT RTE
    3150              :  *
    3151              :  * There's no need for a separate set_result_size phase, since we
    3152              :  * don't support join-qual-parameterized paths for these RTEs.
    3153              :  */
    3154              : static void
    3155         2172 : set_result_pathlist(PlannerInfo *root, RelOptInfo *rel,
    3156              :                     RangeTblEntry *rte)
    3157              : {
    3158              :     Relids      required_outer;
    3159              : 
    3160              :     /* Mark rel with estimated output rows, width, etc */
    3161         2172 :     set_result_size_estimates(root, rel);
    3162              : 
    3163              :     /*
    3164              :      * We don't support pushing join clauses into the quals of a Result scan,
    3165              :      * but it could still have required parameterization due to LATERAL refs
    3166              :      * in its tlist.
    3167              :      */
    3168         2172 :     required_outer = rel->lateral_relids;
    3169              : 
    3170              :     /* Generate appropriate path */
    3171         2172 :     add_path(rel, create_resultscan_path(root, rel, required_outer));
    3172         2172 : }
    3173              : 
    3174              : /*
    3175              :  * set_worktable_pathlist
    3176              :  *      Build the (single) access path for a self-reference CTE RTE
    3177              :  *
    3178              :  * There's no need for a separate set_worktable_size phase, since we don't
    3179              :  * support join-qual-parameterized paths for CTEs.
    3180              :  */
    3181              : static void
    3182          540 : set_worktable_pathlist(PlannerInfo *root, RelOptInfo *rel, RangeTblEntry *rte)
    3183              : {
    3184              :     Path       *ctepath;
    3185              :     PlannerInfo *cteroot;
    3186              :     Index       levelsup;
    3187              :     Relids      required_outer;
    3188              : 
    3189              :     /*
    3190              :      * We need to find the non-recursive term's path, which is in the plan
    3191              :      * level that's processing the recursive UNION, which is one level *below*
    3192              :      * where the CTE comes from.
    3193              :      */
    3194          540 :     levelsup = rte->ctelevelsup;
    3195          540 :     if (levelsup == 0)          /* shouldn't happen */
    3196            0 :         elog(ERROR, "bad levelsup for CTE \"%s\"", rte->ctename);
    3197          540 :     levelsup--;
    3198          540 :     cteroot = root;
    3199         1294 :     while (levelsup-- > 0)
    3200              :     {
    3201          754 :         cteroot = cteroot->parent_root;
    3202          754 :         if (!cteroot)           /* shouldn't happen */
    3203            0 :             elog(ERROR, "bad levelsup for CTE \"%s\"", rte->ctename);
    3204              :     }
    3205          540 :     ctepath = cteroot->non_recursive_path;
    3206          540 :     if (!ctepath)               /* shouldn't happen */
    3207            0 :         elog(ERROR, "could not find path for CTE \"%s\"", rte->ctename);
    3208              : 
    3209              :     /* Mark rel with estimated output rows, width, etc */
    3210          540 :     set_cte_size_estimates(root, rel, ctepath->rows);
    3211              : 
    3212              :     /*
    3213              :      * We don't support pushing join clauses into the quals of a worktable
    3214              :      * scan, but it could still have required parameterization due to LATERAL
    3215              :      * refs in its tlist.  (I'm not sure this is actually possible given the
    3216              :      * restrictions on recursive references, but it's easy enough to support.)
    3217              :      */
    3218          540 :     required_outer = rel->lateral_relids;
    3219              : 
    3220              :     /* Generate appropriate path */
    3221          540 :     add_path(rel, create_worktablescan_path(root, rel, required_outer));
    3222          540 : }
    3223              : 
    3224              : /*
    3225              :  * generate_gather_paths
    3226              :  *      Generate parallel access paths for a relation by pushing a Gather or
    3227              :  *      Gather Merge on top of a partial path.
    3228              :  *
    3229              :  * This must not be called until after we're done creating all partial paths
    3230              :  * for the specified relation.  (Otherwise, add_partial_path might delete a
    3231              :  * path that some GatherPath or GatherMergePath has a reference to.)
    3232              :  *
    3233              :  * If we're generating paths for a scan or join relation, override_rows will
    3234              :  * be false, and we'll just use the relation's size estimate.  When we're
    3235              :  * being called for a partially-grouped or partially-distinct path, though, we
    3236              :  * need to override the rowcount estimate.  (It's not clear that the
    3237              :  * particular value we're using here is actually best, but the underlying rel
    3238              :  * has no estimate so we must do something.)
    3239              :  */
    3240              : void
    3241        13547 : generate_gather_paths(PlannerInfo *root, RelOptInfo *rel, bool override_rows)
    3242              : {
    3243              :     Path       *cheapest_partial_path;
    3244              :     Path       *simple_gather_path;
    3245              :     ListCell   *lc;
    3246              :     double      rows;
    3247        13547 :     double     *rowsp = NULL;
    3248              : 
    3249              :     /* If there are no partial paths, there's nothing to do here. */
    3250        13547 :     if (rel->partial_pathlist == NIL)
    3251            0 :         return;
    3252              : 
    3253              :     /* Should we override the rel's rowcount estimate? */
    3254        13547 :     if (override_rows)
    3255         3486 :         rowsp = &rows;
    3256              : 
    3257              :     /*
    3258              :      * The output of Gather is always unsorted, so there's only one partial
    3259              :      * path of interest: the cheapest one.  That will be the one at the front
    3260              :      * of partial_pathlist because of the way add_partial_path works.
    3261              :      */
    3262        13547 :     cheapest_partial_path = linitial(rel->partial_pathlist);
    3263        13547 :     rows = compute_gather_rows(cheapest_partial_path);
    3264              :     simple_gather_path = (Path *)
    3265        13547 :         create_gather_path(root, rel, cheapest_partial_path, rel->reltarget,
    3266              :                            NULL, rowsp);
    3267        13547 :     add_path(rel, simple_gather_path);
    3268              : 
    3269              :     /*
    3270              :      * For each useful ordering, we can consider an order-preserving Gather
    3271              :      * Merge.
    3272              :      */
    3273        30221 :     foreach(lc, rel->partial_pathlist)
    3274              :     {
    3275        16674 :         Path       *subpath = (Path *) lfirst(lc);
    3276              :         GatherMergePath *path;
    3277              : 
    3278        16674 :         if (subpath->pathkeys == NIL)
    3279        13212 :             continue;
    3280              : 
    3281         3462 :         rows = compute_gather_rows(subpath);
    3282         3462 :         path = create_gather_merge_path(root, rel, subpath, rel->reltarget,
    3283              :                                         subpath->pathkeys, NULL, rowsp);
    3284         3462 :         add_path(rel, &path->path);
    3285              :     }
    3286              : }
    3287              : 
    3288              : /*
    3289              :  * get_useful_pathkeys_for_relation
    3290              :  *      Determine which orderings of a relation might be useful.
    3291              :  *
    3292              :  * Getting data in sorted order can be useful either because the requested
    3293              :  * order matches the final output ordering for the overall query we're
    3294              :  * planning, or because it enables an efficient merge join.  Here, we try
    3295              :  * to figure out which pathkeys to consider.
    3296              :  *
    3297              :  * This allows us to do incremental sort on top of an index scan under a gather
    3298              :  * merge node, i.e. parallelized.
    3299              :  *
    3300              :  * If the require_parallel_safe is true, we also require the expressions to
    3301              :  * be parallel safe (which allows pushing the sort below Gather Merge).
    3302              :  *
    3303              :  * XXX At the moment this can only ever return a list with a single element,
    3304              :  * because it looks at query_pathkeys only. So we might return the pathkeys
    3305              :  * directly, but it seems plausible we'll want to consider other orderings
    3306              :  * in the future. For example, we might want to consider pathkeys useful for
    3307              :  * merge joins.
    3308              :  */
    3309              : static List *
    3310        13547 : get_useful_pathkeys_for_relation(PlannerInfo *root, RelOptInfo *rel,
    3311              :                                  bool require_parallel_safe)
    3312              : {
    3313        13547 :     List       *useful_pathkeys_list = NIL;
    3314              : 
    3315              :     /*
    3316              :      * Considering query_pathkeys is always worth it, because it might allow
    3317              :      * us to avoid a total sort when we have a partially presorted path
    3318              :      * available or to push the total sort into the parallel portion of the
    3319              :      * query.
    3320              :      */
    3321        13547 :     if (root->query_pathkeys)
    3322              :     {
    3323              :         ListCell   *lc;
    3324         7771 :         int         npathkeys = 0;  /* useful pathkeys */
    3325              : 
    3326        13789 :         foreach(lc, root->query_pathkeys)
    3327              :         {
    3328         9973 :             PathKey    *pathkey = (PathKey *) lfirst(lc);
    3329         9973 :             EquivalenceClass *pathkey_ec = pathkey->pk_eclass;
    3330              : 
    3331              :             /*
    3332              :              * We can only build a sort for pathkeys that contain a
    3333              :              * safe-to-compute-early EC member computable from the current
    3334              :              * relation's reltarget, so ignore the remainder of the list as
    3335              :              * soon as we find a pathkey without such a member.
    3336              :              *
    3337              :              * It's still worthwhile to return any prefix of the pathkeys list
    3338              :              * that meets this requirement, as we may be able to do an
    3339              :              * incremental sort.
    3340              :              *
    3341              :              * If requested, ensure the sort expression is parallel-safe too.
    3342              :              */
    3343         9973 :             if (!relation_can_be_sorted_early(root, rel, pathkey_ec,
    3344              :                                               require_parallel_safe))
    3345         3955 :                 break;
    3346              : 
    3347         6018 :             npathkeys++;
    3348              :         }
    3349              : 
    3350              :         /*
    3351              :          * The whole query_pathkeys list matches, so append it directly, to
    3352              :          * allow comparing pathkeys easily by comparing list pointer. If we
    3353              :          * have to truncate the pathkeys, we gotta do a copy though.
    3354              :          */
    3355         7771 :         if (npathkeys == list_length(root->query_pathkeys))
    3356         3816 :             useful_pathkeys_list = lappend(useful_pathkeys_list,
    3357         3816 :                                            root->query_pathkeys);
    3358         3955 :         else if (npathkeys > 0)
    3359          237 :             useful_pathkeys_list = lappend(useful_pathkeys_list,
    3360          237 :                                            list_copy_head(root->query_pathkeys,
    3361              :                                                           npathkeys));
    3362              :     }
    3363              : 
    3364        13547 :     return useful_pathkeys_list;
    3365              : }
    3366              : 
    3367              : /*
    3368              :  * generate_useful_gather_paths
    3369              :  *      Generate parallel access paths for a relation by pushing a Gather or
    3370              :  *      Gather Merge on top of a partial path.
    3371              :  *
    3372              :  * Unlike plain generate_gather_paths, this looks both at pathkeys of input
    3373              :  * paths (aiming to preserve the ordering), but also considers ordering that
    3374              :  * might be useful for nodes above the gather merge node, and tries to add
    3375              :  * a sort (regular or incremental) to provide that.
    3376              :  */
    3377              : void
    3378       351118 : generate_useful_gather_paths(PlannerInfo *root, RelOptInfo *rel, bool override_rows)
    3379              : {
    3380              :     ListCell   *lc;
    3381              :     double      rows;
    3382       351118 :     double     *rowsp = NULL;
    3383       351118 :     List       *useful_pathkeys_list = NIL;
    3384       351118 :     Path       *cheapest_partial_path = NULL;
    3385              : 
    3386              :     /* If there are no partial paths, there's nothing to do here. */
    3387       351118 :     if (rel->partial_pathlist == NIL)
    3388       337571 :         return;
    3389              : 
    3390              :     /* Should we override the rel's rowcount estimate? */
    3391        13547 :     if (override_rows)
    3392         3486 :         rowsp = &rows;
    3393              : 
    3394              :     /* generate the regular gather (merge) paths */
    3395        13547 :     generate_gather_paths(root, rel, override_rows);
    3396              : 
    3397              :     /* consider incremental sort for interesting orderings */
    3398        13547 :     useful_pathkeys_list = get_useful_pathkeys_for_relation(root, rel, true);
    3399              : 
    3400              :     /* used for explicit (full) sort paths */
    3401        13547 :     cheapest_partial_path = linitial(rel->partial_pathlist);
    3402              : 
    3403              :     /*
    3404              :      * Consider sorted paths for each interesting ordering. We generate both
    3405              :      * incremental and full sort.
    3406              :      */
    3407        17600 :     foreach(lc, useful_pathkeys_list)
    3408              :     {
    3409         4053 :         List       *useful_pathkeys = lfirst(lc);
    3410              :         ListCell   *lc2;
    3411              :         bool        is_sorted;
    3412              :         int         presorted_keys;
    3413              : 
    3414         9566 :         foreach(lc2, rel->partial_pathlist)
    3415              :         {
    3416         5513 :             Path       *subpath = (Path *) lfirst(lc2);
    3417              :             GatherMergePath *path;
    3418              : 
    3419         5513 :             is_sorted = pathkeys_count_contained_in(useful_pathkeys,
    3420              :                                                     subpath->pathkeys,
    3421              :                                                     &presorted_keys);
    3422              : 
    3423              :             /*
    3424              :              * We don't need to consider the case where a subpath is already
    3425              :              * fully sorted because generate_gather_paths already creates a
    3426              :              * gather merge path for every subpath that has pathkeys present.
    3427              :              *
    3428              :              * But since the subpath is already sorted, we know we don't need
    3429              :              * to consider adding a sort (full or incremental) on top of it,
    3430              :              * so we can continue here.
    3431              :              */
    3432         5513 :             if (is_sorted)
    3433         1518 :                 continue;
    3434              : 
    3435              :             /*
    3436              :              * Try at least sorting the cheapest path and also try
    3437              :              * incrementally sorting any path which is partially sorted
    3438              :              * already (no need to deal with paths which have presorted keys
    3439              :              * when incremental sort is disabled unless it's the cheapest
    3440              :              * input path).
    3441              :              */
    3442         3995 :             if (subpath != cheapest_partial_path &&
    3443          189 :                 (presorted_keys == 0 || !enable_incremental_sort))
    3444           51 :                 continue;
    3445              : 
    3446              :             /*
    3447              :              * Consider regular sort for any path that's not presorted or if
    3448              :              * incremental sort is disabled.  We've no need to consider both
    3449              :              * sort and incremental sort on the same path.  We assume that
    3450              :              * incremental sort is always faster when there are presorted
    3451              :              * keys.
    3452              :              *
    3453              :              * This is not redundant with the gather paths created in
    3454              :              * generate_gather_paths, because that doesn't generate ordered
    3455              :              * output. Here we add an explicit sort to match the useful
    3456              :              * ordering.
    3457              :              */
    3458         3944 :             if (presorted_keys == 0 || !enable_incremental_sort)
    3459              :             {
    3460         3800 :                 subpath = (Path *) create_sort_path(root,
    3461              :                                                     rel,
    3462              :                                                     subpath,
    3463              :                                                     useful_pathkeys,
    3464              :                                                     -1.0);
    3465              :             }
    3466              :             else
    3467          144 :                 subpath = (Path *) create_incremental_sort_path(root,
    3468              :                                                                 rel,
    3469              :                                                                 subpath,
    3470              :                                                                 useful_pathkeys,
    3471              :                                                                 presorted_keys,
    3472              :                                                                 -1);
    3473         3944 :             rows = compute_gather_rows(subpath);
    3474         3944 :             path = create_gather_merge_path(root, rel,
    3475              :                                             subpath,
    3476         3944 :                                             rel->reltarget,
    3477              :                                             subpath->pathkeys,
    3478              :                                             NULL,
    3479              :                                             rowsp);
    3480              : 
    3481         3944 :             add_path(rel, &path->path);
    3482              :         }
    3483              :     }
    3484              : }
    3485              : 
    3486              : /*
    3487              :  * generate_grouped_paths
    3488              :  *      Generate paths for a grouped relation by adding sorted and hashed
    3489              :  *      partial aggregation paths on top of paths of the ungrouped relation.
    3490              :  *
    3491              :  * The information needed is provided by the RelAggInfo structure stored in
    3492              :  * "grouped_rel".
    3493              :  */
    3494              : void
    3495          449 : generate_grouped_paths(PlannerInfo *root, RelOptInfo *grouped_rel,
    3496              :                        RelOptInfo *rel)
    3497              : {
    3498          449 :     RelAggInfo *agg_info = grouped_rel->agg_info;
    3499              :     AggClauseCosts agg_costs;
    3500              :     bool        can_hash;
    3501              :     bool        can_sort;
    3502          449 :     Path       *cheapest_total_path = NULL;
    3503          449 :     Path       *cheapest_partial_path = NULL;
    3504          449 :     double      dNumGroups = 0;
    3505          449 :     double      dNumPartialGroups = 0;
    3506          449 :     List       *group_pathkeys = NIL;
    3507              : 
    3508          449 :     if (IS_DUMMY_REL(rel))
    3509              :     {
    3510            0 :         mark_dummy_rel(grouped_rel);
    3511            0 :         return;
    3512              :     }
    3513              : 
    3514              :     /*
    3515              :      * We push partial aggregation only to the lowest possible level in the
    3516              :      * join tree that is deemed useful.
    3517              :      */
    3518          449 :     if (!bms_equal(agg_info->apply_agg_at, rel->relids) ||
    3519          449 :         !agg_info->agg_useful)
    3520            0 :         return;
    3521              : 
    3522         2694 :     MemSet(&agg_costs, 0, sizeof(AggClauseCosts));
    3523          449 :     get_agg_clause_costs(root, AGGSPLIT_INITIAL_SERIAL, &agg_costs);
    3524              : 
    3525              :     /*
    3526              :      * Determine whether it's possible to perform sort-based implementations
    3527              :      * of grouping, and generate the pathkeys that represent the grouping
    3528              :      * requirements in that case.
    3529              :      */
    3530          449 :     can_sort = grouping_is_sortable(agg_info->group_clauses);
    3531          449 :     if (can_sort)
    3532              :     {
    3533              :         RelOptInfo *top_grouped_rel;
    3534              :         List       *top_group_tlist;
    3535              : 
    3536          251 :         top_grouped_rel = IS_OTHER_REL(rel) ?
    3537          700 :             rel->top_parent->grouped_rel : grouped_rel;
    3538              :         top_group_tlist =
    3539          449 :             make_tlist_from_pathtarget(top_grouped_rel->agg_info->target);
    3540              : 
    3541              :         group_pathkeys =
    3542          449 :             make_pathkeys_for_sortclauses(root, agg_info->group_clauses,
    3543              :                                           top_group_tlist);
    3544              :     }
    3545              : 
    3546              :     /*
    3547              :      * Determine whether we should consider hash-based implementations of
    3548              :      * grouping.
    3549              :      */
    3550              :     Assert(root->numOrderedAggs == 0);
    3551          898 :     can_hash = (agg_info->group_clauses != NIL &&
    3552          449 :                 grouping_is_hashable(agg_info->group_clauses));
    3553              : 
    3554              :     /*
    3555              :      * Consider whether we should generate partially aggregated non-partial
    3556              :      * paths.  We can only do this if we have a non-partial path.
    3557              :      */
    3558          449 :     if (rel->pathlist != NIL)
    3559              :     {
    3560          449 :         cheapest_total_path = rel->cheapest_total_path;
    3561              :         Assert(cheapest_total_path != NULL);
    3562              :     }
    3563              : 
    3564              :     /*
    3565              :      * If parallelism is possible for grouped_rel, then we should consider
    3566              :      * generating partially-grouped partial paths.  However, if the ungrouped
    3567              :      * rel has no partial paths, then we can't.
    3568              :      */
    3569          449 :     if (grouped_rel->consider_parallel && rel->partial_pathlist != NIL)
    3570              :     {
    3571          366 :         cheapest_partial_path = linitial(rel->partial_pathlist);
    3572              :         Assert(cheapest_partial_path != NULL);
    3573              :     }
    3574              : 
    3575              :     /* Estimate number of partial groups. */
    3576          449 :     if (cheapest_total_path != NULL)
    3577          449 :         dNumGroups = estimate_num_groups(root,
    3578              :                                          agg_info->group_exprs,
    3579              :                                          cheapest_total_path->rows,
    3580              :                                          NULL, NULL);
    3581          449 :     if (cheapest_partial_path != NULL)
    3582          366 :         dNumPartialGroups = estimate_num_groups(root,
    3583              :                                                 agg_info->group_exprs,
    3584              :                                                 cheapest_partial_path->rows,
    3585              :                                                 NULL, NULL);
    3586              : 
    3587          449 :     if (can_sort && cheapest_total_path != NULL)
    3588              :     {
    3589              :         ListCell   *lc;
    3590              : 
    3591              :         /*
    3592              :          * Use any available suitably-sorted path as input, and also consider
    3593              :          * sorting the cheapest-total path and incremental sort on any paths
    3594              :          * with presorted keys.
    3595              :          *
    3596              :          * To save planning time, we ignore parameterized input paths unless
    3597              :          * they are the cheapest-total path.
    3598              :          */
    3599         1087 :         foreach(lc, rel->pathlist)
    3600              :         {
    3601          638 :             Path       *input_path = (Path *) lfirst(lc);
    3602              :             Path       *path;
    3603              :             bool        is_sorted;
    3604              :             int         presorted_keys;
    3605              : 
    3606              :             /*
    3607              :              * Ignore parameterized paths that are not the cheapest-total
    3608              :              * path.
    3609              :              */
    3610          638 :             if (input_path->param_info &&
    3611              :                 input_path != cheapest_total_path)
    3612           15 :                 continue;
    3613              : 
    3614          635 :             is_sorted = pathkeys_count_contained_in(group_pathkeys,
    3615              :                                                     input_path->pathkeys,
    3616              :                                                     &presorted_keys);
    3617              : 
    3618              :             /*
    3619              :              * Ignore paths that are not suitably or partially sorted, unless
    3620              :              * they are the cheapest total path (no need to deal with paths
    3621              :              * which have presorted keys when incremental sort is disabled).
    3622              :              */
    3623          635 :             if (!is_sorted && input_path != cheapest_total_path &&
    3624           84 :                 (presorted_keys == 0 || !enable_incremental_sort))
    3625           12 :                 continue;
    3626              : 
    3627              :             /*
    3628              :              * Since the path originates from a non-grouped relation that is
    3629              :              * not aware of eager aggregation, we must ensure that it provides
    3630              :              * the correct input for partial aggregation.
    3631              :              */
    3632          623 :             path = (Path *) create_projection_path(root,
    3633              :                                                    grouped_rel,
    3634              :                                                    input_path,
    3635          623 :                                                    agg_info->agg_input);
    3636              : 
    3637          623 :             if (!is_sorted)
    3638              :             {
    3639              :                 /*
    3640              :                  * We've no need to consider both a sort and incremental sort.
    3641              :                  * We'll just do a sort if there are no presorted keys and an
    3642              :                  * incremental sort when there are presorted keys.
    3643              :                  */
    3644          518 :                 if (presorted_keys == 0 || !enable_incremental_sort)
    3645          446 :                     path = (Path *) create_sort_path(root,
    3646              :                                                      grouped_rel,
    3647              :                                                      path,
    3648              :                                                      group_pathkeys,
    3649              :                                                      -1.0);
    3650              :                 else
    3651           72 :                     path = (Path *) create_incremental_sort_path(root,
    3652              :                                                                  grouped_rel,
    3653              :                                                                  path,
    3654              :                                                                  group_pathkeys,
    3655              :                                                                  presorted_keys,
    3656              :                                                                  -1.0);
    3657              :             }
    3658              : 
    3659              :             /*
    3660              :              * qual is NIL because the HAVING clause cannot be evaluated until
    3661              :              * the final value of the aggregate is known.
    3662              :              */
    3663          623 :             path = (Path *) create_agg_path(root,
    3664              :                                             grouped_rel,
    3665              :                                             path,
    3666          623 :                                             agg_info->target,
    3667              :                                             AGG_SORTED,
    3668              :                                             AGGSPLIT_INITIAL_SERIAL,
    3669              :                                             agg_info->group_clauses,
    3670              :                                             NIL,
    3671              :                                             &agg_costs,
    3672              :                                             dNumGroups);
    3673              : 
    3674          623 :             add_path(grouped_rel, path);
    3675              :         }
    3676              :     }
    3677              : 
    3678          449 :     if (can_sort && cheapest_partial_path != NULL)
    3679              :     {
    3680              :         ListCell   *lc;
    3681              : 
    3682              :         /* Similar to above logic, but for partial paths. */
    3683          852 :         foreach(lc, rel->partial_pathlist)
    3684              :         {
    3685          486 :             Path       *input_path = (Path *) lfirst(lc);
    3686              :             Path       *path;
    3687              :             bool        is_sorted;
    3688              :             int         presorted_keys;
    3689              : 
    3690          486 :             is_sorted = pathkeys_count_contained_in(group_pathkeys,
    3691              :                                                     input_path->pathkeys,
    3692              :                                                     &presorted_keys);
    3693              : 
    3694              :             /*
    3695              :              * Ignore paths that are not suitably or partially sorted, unless
    3696              :              * they are the cheapest partial path (no need to deal with paths
    3697              :              * which have presorted keys when incremental sort is disabled).
    3698              :              */
    3699          486 :             if (!is_sorted && input_path != cheapest_partial_path &&
    3700           48 :                 (presorted_keys == 0 || !enable_incremental_sort))
    3701            0 :                 continue;
    3702              : 
    3703              :             /*
    3704              :              * Since the path originates from a non-grouped relation that is
    3705              :              * not aware of eager aggregation, we must ensure that it provides
    3706              :              * the correct input for partial aggregation.
    3707              :              */
    3708          486 :             path = (Path *) create_projection_path(root,
    3709              :                                                    grouped_rel,
    3710              :                                                    input_path,
    3711          486 :                                                    agg_info->agg_input);
    3712              : 
    3713          486 :             if (!is_sorted)
    3714              :             {
    3715              :                 /*
    3716              :                  * We've no need to consider both a sort and incremental sort.
    3717              :                  * We'll just do a sort if there are no presorted keys and an
    3718              :                  * incremental sort when there are presorted keys.
    3719              :                  */
    3720          414 :                 if (presorted_keys == 0 || !enable_incremental_sort)
    3721          366 :                     path = (Path *) create_sort_path(root,
    3722              :                                                      grouped_rel,
    3723              :                                                      path,
    3724              :                                                      group_pathkeys,
    3725              :                                                      -1.0);
    3726              :                 else
    3727           48 :                     path = (Path *) create_incremental_sort_path(root,
    3728              :                                                                  grouped_rel,
    3729              :                                                                  path,
    3730              :                                                                  group_pathkeys,
    3731              :                                                                  presorted_keys,
    3732              :                                                                  -1.0);
    3733              :             }
    3734              : 
    3735              :             /*
    3736              :              * qual is NIL because the HAVING clause cannot be evaluated until
    3737              :              * the final value of the aggregate is known.
    3738              :              */
    3739          486 :             path = (Path *) create_agg_path(root,
    3740              :                                             grouped_rel,
    3741              :                                             path,
    3742          486 :                                             agg_info->target,
    3743              :                                             AGG_SORTED,
    3744              :                                             AGGSPLIT_INITIAL_SERIAL,
    3745              :                                             agg_info->group_clauses,
    3746              :                                             NIL,
    3747              :                                             &agg_costs,
    3748              :                                             dNumPartialGroups);
    3749              : 
    3750          486 :             add_partial_path(grouped_rel, path);
    3751              :         }
    3752              :     }
    3753              : 
    3754              :     /*
    3755              :      * Add a partially-grouped HashAgg Path where possible
    3756              :      */
    3757          449 :     if (can_hash && cheapest_total_path != NULL)
    3758              :     {
    3759              :         Path       *path;
    3760              : 
    3761              :         /*
    3762              :          * Since the path originates from a non-grouped relation that is not
    3763              :          * aware of eager aggregation, we must ensure that it provides the
    3764              :          * correct input for partial aggregation.
    3765              :          */
    3766          449 :         path = (Path *) create_projection_path(root,
    3767              :                                                grouped_rel,
    3768              :                                                cheapest_total_path,
    3769          449 :                                                agg_info->agg_input);
    3770              : 
    3771              :         /*
    3772              :          * qual is NIL because the HAVING clause cannot be evaluated until the
    3773              :          * final value of the aggregate is known.
    3774              :          */
    3775          449 :         path = (Path *) create_agg_path(root,
    3776              :                                         grouped_rel,
    3777              :                                         path,
    3778          449 :                                         agg_info->target,
    3779              :                                         AGG_HASHED,
    3780              :                                         AGGSPLIT_INITIAL_SERIAL,
    3781              :                                         agg_info->group_clauses,
    3782              :                                         NIL,
    3783              :                                         &agg_costs,
    3784              :                                         dNumGroups);
    3785              : 
    3786          449 :         add_path(grouped_rel, path);
    3787              :     }
    3788              : 
    3789              :     /*
    3790              :      * Now add a partially-grouped HashAgg partial Path where possible
    3791              :      */
    3792          449 :     if (can_hash && cheapest_partial_path != NULL)
    3793              :     {
    3794              :         Path       *path;
    3795              : 
    3796              :         /*
    3797              :          * Since the path originates from a non-grouped relation that is not
    3798              :          * aware of eager aggregation, we must ensure that it provides the
    3799              :          * correct input for partial aggregation.
    3800              :          */
    3801          366 :         path = (Path *) create_projection_path(root,
    3802              :                                                grouped_rel,
    3803              :                                                cheapest_partial_path,
    3804          366 :                                                agg_info->agg_input);
    3805              : 
    3806              :         /*
    3807              :          * qual is NIL because the HAVING clause cannot be evaluated until the
    3808              :          * final value of the aggregate is known.
    3809              :          */
    3810          366 :         path = (Path *) create_agg_path(root,
    3811              :                                         grouped_rel,
    3812              :                                         path,
    3813          366 :                                         agg_info->target,
    3814              :                                         AGG_HASHED,
    3815              :                                         AGGSPLIT_INITIAL_SERIAL,
    3816              :                                         agg_info->group_clauses,
    3817              :                                         NIL,
    3818              :                                         &agg_costs,
    3819              :                                         dNumPartialGroups);
    3820              : 
    3821          366 :         add_partial_path(grouped_rel, path);
    3822              :     }
    3823              : }
    3824              : 
    3825              : /*
    3826              :  * make_rel_from_joinlist
    3827              :  *    Build access paths using a "joinlist" to guide the join path search.
    3828              :  *
    3829              :  * See comments for deconstruct_jointree() for definition of the joinlist
    3830              :  * data structure.
    3831              :  */
    3832              : static RelOptInfo *
    3833       184704 : make_rel_from_joinlist(PlannerInfo *root, List *joinlist)
    3834              : {
    3835              :     int         levels_needed;
    3836              :     List       *initial_rels;
    3837              :     ListCell   *jl;
    3838              : 
    3839              :     /*
    3840              :      * Count the number of child joinlist nodes.  This is the depth of the
    3841              :      * dynamic-programming algorithm we must employ to consider all ways of
    3842              :      * joining the child nodes.
    3843              :      */
    3844       184704 :     levels_needed = list_length(joinlist);
    3845              : 
    3846       184704 :     if (levels_needed <= 0)
    3847            0 :         return NULL;            /* nothing to do? */
    3848              : 
    3849              :     /*
    3850              :      * Construct a list of rels corresponding to the child joinlist nodes.
    3851              :      * This may contain both base rels and rels constructed according to
    3852              :      * sub-joinlists.
    3853              :      */
    3854       184704 :     initial_rels = NIL;
    3855       449234 :     foreach(jl, joinlist)
    3856              :     {
    3857       264530 :         Node       *jlnode = (Node *) lfirst(jl);
    3858              :         RelOptInfo *thisrel;
    3859              : 
    3860       264530 :         if (IsA(jlnode, RangeTblRef))
    3861              :         {
    3862       262784 :             int         varno = ((RangeTblRef *) jlnode)->rtindex;
    3863              : 
    3864       262784 :             thisrel = find_base_rel(root, varno);
    3865              :         }
    3866         1746 :         else if (IsA(jlnode, List))
    3867              :         {
    3868              :             /* Recurse to handle subproblem */
    3869         1746 :             thisrel = make_rel_from_joinlist(root, (List *) jlnode);
    3870              :         }
    3871              :         else
    3872              :         {
    3873            0 :             elog(ERROR, "unrecognized joinlist node type: %d",
    3874              :                  (int) nodeTag(jlnode));
    3875              :             thisrel = NULL;     /* keep compiler quiet */
    3876              :         }
    3877              : 
    3878       264530 :         initial_rels = lappend(initial_rels, thisrel);
    3879              :     }
    3880              : 
    3881       184704 :     if (levels_needed == 1)
    3882              :     {
    3883              :         /*
    3884              :          * Single joinlist node, so we're done.
    3885              :          */
    3886       126867 :         return (RelOptInfo *) linitial(initial_rels);
    3887              :     }
    3888              :     else
    3889              :     {
    3890              :         /*
    3891              :          * Consider the different orders in which we could join the rels,
    3892              :          * using a plugin, GEQO, or the regular join search code.
    3893              :          *
    3894              :          * We put the initial_rels list into a PlannerInfo field because
    3895              :          * has_legal_joinclause() needs to look at it (ugly :-().
    3896              :          */
    3897        57837 :         root->initial_rels = initial_rels;
    3898              : 
    3899        57837 :         if (join_search_hook)
    3900            0 :             return (*join_search_hook) (root, levels_needed, initial_rels);
    3901        57837 :         else if (enable_geqo && levels_needed >= geqo_threshold)
    3902           21 :             return geqo(root, levels_needed, initial_rels);
    3903              :         else
    3904        57816 :             return standard_join_search(root, levels_needed, initial_rels);
    3905              :     }
    3906              : }
    3907              : 
    3908              : /*
    3909              :  * standard_join_search
    3910              :  *    Find possible joinpaths for a query by successively finding ways
    3911              :  *    to join component relations into join relations.
    3912              :  *
    3913              :  * 'levels_needed' is the number of iterations needed, ie, the number of
    3914              :  *      independent jointree items in the query.  This is > 1.
    3915              :  *
    3916              :  * 'initial_rels' is a list of RelOptInfo nodes for each independent
    3917              :  *      jointree item.  These are the components to be joined together.
    3918              :  *      Note that levels_needed == list_length(initial_rels).
    3919              :  *
    3920              :  * Returns the final level of join relations, i.e., the relation that is
    3921              :  * the result of joining all the original relations together.
    3922              :  * At least one implementation path must be provided for this relation and
    3923              :  * all required sub-relations.
    3924              :  *
    3925              :  * To support loadable plugins that modify planner behavior by changing the
    3926              :  * join searching algorithm, we provide a hook variable that lets a plugin
    3927              :  * replace or supplement this function.  Any such hook must return the same
    3928              :  * final join relation as the standard code would, but it might have a
    3929              :  * different set of implementation paths attached, and only the sub-joinrels
    3930              :  * needed for these paths need have been instantiated.
    3931              :  *
    3932              :  * Note to plugin authors: the functions invoked during standard_join_search()
    3933              :  * modify root->join_rel_list and root->join_rel_hash.  If you want to do more
    3934              :  * than one join-order search, you'll probably need to save and restore the
    3935              :  * original states of those data structures.  See geqo_eval() for an example.
    3936              :  */
    3937              : RelOptInfo *
    3938        57816 : standard_join_search(PlannerInfo *root, int levels_needed, List *initial_rels)
    3939              : {
    3940              :     int         lev;
    3941              :     RelOptInfo *rel;
    3942              : 
    3943              :     /*
    3944              :      * This function cannot be invoked recursively within any one planning
    3945              :      * problem, so join_rel_level[] can't be in use already.
    3946              :      */
    3947              :     Assert(root->join_rel_level == NULL);
    3948              : 
    3949              :     /*
    3950              :      * We employ a simple "dynamic programming" algorithm: we first find all
    3951              :      * ways to build joins of two jointree items, then all ways to build joins
    3952              :      * of three items (from two-item joins and single items), then four-item
    3953              :      * joins, and so on until we have considered all ways to join all the
    3954              :      * items into one rel.
    3955              :      *
    3956              :      * root->join_rel_level[j] is a list of all the j-item rels.  Initially we
    3957              :      * set root->join_rel_level[1] to represent all the single-jointree-item
    3958              :      * relations.
    3959              :      */
    3960        57816 :     root->join_rel_level = (List **) palloc0((levels_needed + 1) * sizeof(List *));
    3961              : 
    3962        57816 :     root->join_rel_level[1] = initial_rels;
    3963              : 
    3964       137612 :     for (lev = 2; lev <= levels_needed; lev++)
    3965              :     {
    3966              :         ListCell   *lc;
    3967              : 
    3968              :         /*
    3969              :          * Determine all possible pairs of relations to be joined at this
    3970              :          * level, and build paths for making each one from every available
    3971              :          * pair of lower-level relations.
    3972              :          */
    3973        79796 :         join_search_one_level(root, lev);
    3974              : 
    3975              :         /*
    3976              :          * Run generate_partitionwise_join_paths() and
    3977              :          * generate_useful_gather_paths() for each just-processed joinrel.  We
    3978              :          * could not do this earlier because both regular and partial paths
    3979              :          * can get added to a particular joinrel at multiple times within
    3980              :          * join_search_one_level.
    3981              :          *
    3982              :          * After that, we're done creating paths for the joinrel, so run
    3983              :          * set_cheapest().
    3984              :          *
    3985              :          * In addition, we also run generate_grouped_paths() for the grouped
    3986              :          * relation of each just-processed joinrel, and run set_cheapest() for
    3987              :          * the grouped relation afterwards.
    3988              :          */
    3989       205876 :         foreach(lc, root->join_rel_level[lev])
    3990              :         {
    3991              :             bool        is_top_rel;
    3992              : 
    3993       126080 :             rel = (RelOptInfo *) lfirst(lc);
    3994              : 
    3995       126080 :             is_top_rel = bms_equal(rel->relids, root->all_query_rels);
    3996              : 
    3997              :             /* Create paths for partitionwise joins. */
    3998       126080 :             generate_partitionwise_join_paths(root, rel);
    3999              : 
    4000              :             /*
    4001              :              * Except for the topmost scan/join rel, consider gathering
    4002              :              * partial paths.  We'll do the same for the topmost scan/join rel
    4003              :              * once we know the final targetlist (see grouping_planner's and
    4004              :              * its call to apply_scanjoin_target_to_paths).
    4005              :              */
    4006       126080 :             if (!is_top_rel)
    4007        68519 :                 generate_useful_gather_paths(root, rel, false);
    4008              : 
    4009              :             /* Find and save the cheapest paths for this rel */
    4010       126080 :             set_cheapest(rel);
    4011              : 
    4012              :             /*
    4013              :              * Except for the topmost scan/join rel, consider generating
    4014              :              * partial aggregation paths for the grouped relation on top of
    4015              :              * the paths of this rel.  After that, we're done creating paths
    4016              :              * for the grouped relation, so run set_cheapest().
    4017              :              */
    4018       126080 :             if (rel->grouped_rel != NULL && !is_top_rel)
    4019              :             {
    4020           36 :                 RelOptInfo *grouped_rel = rel->grouped_rel;
    4021              : 
    4022              :                 Assert(IS_GROUPED_REL(grouped_rel));
    4023              : 
    4024           36 :                 generate_grouped_paths(root, grouped_rel, rel);
    4025           36 :                 set_cheapest(grouped_rel);
    4026              :             }
    4027              : 
    4028              : #ifdef OPTIMIZER_DEBUG
    4029              :             pprint(rel);
    4030              : #endif
    4031              :         }
    4032              :     }
    4033              : 
    4034              :     /*
    4035              :      * We should have a single rel at the final level.
    4036              :      */
    4037        57816 :     if (root->join_rel_level[levels_needed] == NIL)
    4038            0 :         elog(ERROR, "failed to build any %d-way joins", levels_needed);
    4039              :     Assert(list_length(root->join_rel_level[levels_needed]) == 1);
    4040              : 
    4041        57816 :     rel = (RelOptInfo *) linitial(root->join_rel_level[levels_needed]);
    4042              : 
    4043        57816 :     root->join_rel_level = NULL;
    4044              : 
    4045        57816 :     return rel;
    4046              : }
    4047              : 
    4048              : /*****************************************************************************
    4049              :  *          PUSHING QUALS DOWN INTO SUBQUERIES
    4050              :  *****************************************************************************/
    4051              : 
    4052              : /*
    4053              :  * subquery_is_pushdown_safe - is a subquery safe for pushing down quals?
    4054              :  *
    4055              :  * subquery is the particular component query being checked.  topquery
    4056              :  * is the top component of a set-operations tree (the same Query if no
    4057              :  * set-op is involved).
    4058              :  *
    4059              :  * Conditions checked here:
    4060              :  *
    4061              :  * 1. If the subquery has a LIMIT clause, we must not push down any quals,
    4062              :  * since that could change the set of rows returned.
    4063              :  *
    4064              :  * 2. If the subquery contains EXCEPT or EXCEPT ALL set ops we cannot push
    4065              :  * quals into it, because that could change the results.
    4066              :  *
    4067              :  * 3. If the subquery uses DISTINCT, we cannot push volatile quals into it.
    4068              :  * This is because upper-level quals should semantically be evaluated only
    4069              :  * once per distinct row, not once per original row, and if the qual is
    4070              :  * volatile then extra evaluations could change the results.  (This issue
    4071              :  * does not apply to other forms of aggregation such as GROUP BY, because
    4072              :  * when those are present we push into HAVING not WHERE, so that the quals
    4073              :  * are still applied after aggregation.)
    4074              :  *
    4075              :  * 4. If the subquery contains window functions, we cannot push volatile quals
    4076              :  * into it.  The issue here is a bit different from DISTINCT: a volatile qual
    4077              :  * might succeed for some rows of a window partition and fail for others,
    4078              :  * thereby changing the partition contents and thus the window functions'
    4079              :  * results for rows that remain.
    4080              :  *
    4081              :  * 5. If the subquery contains any set-returning functions in its targetlist,
    4082              :  * we cannot push volatile quals into it.  That would push them below the SRFs
    4083              :  * and thereby change the number of times they are evaluated.  Also, a
    4084              :  * volatile qual could succeed for some SRF output rows and fail for others,
    4085              :  * a behavior that cannot occur if it's evaluated before SRF expansion.
    4086              :  *
    4087              :  * 6. If the subquery has nonempty grouping sets, we cannot push down any
    4088              :  * quals.  The concern here is that a qual referencing a "constant" grouping
    4089              :  * column could get constant-folded, which would be improper because the value
    4090              :  * is potentially nullable by grouping-set expansion.  This restriction could
    4091              :  * be removed if we had a parsetree representation that shows that such
    4092              :  * grouping columns are not really constant.  (There are other ideas that
    4093              :  * could be used to relax this restriction, but that's the approach most
    4094              :  * likely to get taken in the future.  Note that there's not much to be gained
    4095              :  * so long as subquery_planner can't move HAVING clauses to WHERE within such
    4096              :  * a subquery.)
    4097              :  *
    4098              :  * In addition, we make several checks on the subquery's output columns to see
    4099              :  * if it is safe to reference them in pushed-down quals.  If output column k
    4100              :  * is found to be unsafe to reference, we set the reason for that inside
    4101              :  * safetyInfo->unsafeFlags[k], but we don't reject the subquery overall since
    4102              :  * column k might not be referenced by some/all quals.  The unsafeFlags[]
    4103              :  * array will be consulted later by qual_is_pushdown_safe().  It's better to
    4104              :  * do it this way than to make the checks directly in qual_is_pushdown_safe(),
    4105              :  * because when the subquery involves set operations we have to check the
    4106              :  * output expressions in each arm of the set op.
    4107              :  *
    4108              :  * Note: pushing quals into a DISTINCT subquery is theoretically dubious:
    4109              :  * we're effectively assuming that the quals cannot distinguish values that
    4110              :  * the DISTINCT's equality operator sees as equal, yet there are many
    4111              :  * counterexamples to that assumption.  However use of such a qual with a
    4112              :  * DISTINCT subquery would be unsafe anyway, since there's no guarantee which
    4113              :  * "equal" value will be chosen as the output value by the DISTINCT operation.
    4114              :  * So we don't worry too much about that.  Another objection is that if the
    4115              :  * qual is expensive to evaluate, running it for each original row might cost
    4116              :  * more than we save by eliminating rows before the DISTINCT step.  But it
    4117              :  * would be very hard to estimate that at this stage, and in practice pushdown
    4118              :  * seldom seems to make things worse, so we ignore that problem too.
    4119              :  *
    4120              :  * Note: likewise, pushing quals into a subquery with window functions is a
    4121              :  * bit dubious: the quals might remove some rows of a window partition while
    4122              :  * leaving others, causing changes in the window functions' results for the
    4123              :  * surviving rows.  We insist that such a qual reference only partitioning
    4124              :  * columns, but again that only protects us if the qual does not distinguish
    4125              :  * values that the partitioning equality operator sees as equal.  The risks
    4126              :  * here are perhaps larger than for DISTINCT, since no de-duplication of rows
    4127              :  * occurs and thus there is no theoretical problem with such a qual.  But
    4128              :  * we'll do this anyway because the potential performance benefits are very
    4129              :  * large, and we've seen no field complaints about the longstanding comparable
    4130              :  * behavior with DISTINCT.
    4131              :  */
    4132              : static bool
    4133         1717 : subquery_is_pushdown_safe(Query *subquery, Query *topquery,
    4134              :                           pushdown_safety_info *safetyInfo)
    4135              : {
    4136              :     SetOperationStmt *topop;
    4137              : 
    4138              :     /* Check point 1 */
    4139         1717 :     if (subquery->limitOffset != NULL || subquery->limitCount != NULL)
    4140           67 :         return false;
    4141              : 
    4142              :     /* Check point 6 */
    4143         1650 :     if (subquery->groupClause && subquery->groupingSets)
    4144            6 :         return false;
    4145              : 
    4146              :     /* Check points 3, 4, and 5 */
    4147         1644 :     if (subquery->distinctClause ||
    4148         1602 :         subquery->hasWindowFuncs ||
    4149         1469 :         subquery->hasTargetSRFs)
    4150          466 :         safetyInfo->unsafeVolatile = true;
    4151              : 
    4152              :     /*
    4153              :      * If we're at a leaf query, check for unsafe expressions in its target
    4154              :      * list, and mark any reasons why they're unsafe in unsafeFlags[].
    4155              :      * (Non-leaf nodes in setop trees have only simple Vars in their tlists,
    4156              :      * so no need to check them.)
    4157              :      */
    4158         1644 :     if (subquery->setOperations == NULL)
    4159         1566 :         check_output_expressions(subquery, safetyInfo);
    4160              : 
    4161              :     /* Are we at top level, or looking at a setop component? */
    4162         1644 :     if (subquery == topquery)
    4163              :     {
    4164              :         /* Top level, so check any component queries */
    4165         1488 :         if (subquery->setOperations != NULL)
    4166           78 :             if (!recurse_pushdown_safe(subquery->setOperations, topquery,
    4167              :                                        safetyInfo))
    4168            0 :                 return false;
    4169              :     }
    4170              :     else
    4171              :     {
    4172              :         /* Setop component must not have more components (too weird) */
    4173          156 :         if (subquery->setOperations != NULL)
    4174            0 :             return false;
    4175              :         /* Check whether setop component output types match top level */
    4176          156 :         topop = castNode(SetOperationStmt, topquery->setOperations);
    4177              :         Assert(topop);
    4178          156 :         compare_tlist_datatypes(subquery->targetList,
    4179              :                                 topop->colTypes,
    4180              :                                 safetyInfo);
    4181              :     }
    4182         1644 :     return true;
    4183              : }
    4184              : 
    4185              : /*
    4186              :  * Helper routine to recurse through setOperations tree
    4187              :  */
    4188              : static bool
    4189          234 : recurse_pushdown_safe(Node *setOp, Query *topquery,
    4190              :                       pushdown_safety_info *safetyInfo)
    4191              : {
    4192          234 :     if (IsA(setOp, RangeTblRef))
    4193              :     {
    4194          156 :         RangeTblRef *rtr = (RangeTblRef *) setOp;
    4195          156 :         RangeTblEntry *rte = rt_fetch(rtr->rtindex, topquery->rtable);
    4196          156 :         Query      *subquery = rte->subquery;
    4197              : 
    4198              :         Assert(subquery != NULL);
    4199          156 :         return subquery_is_pushdown_safe(subquery, topquery, safetyInfo);
    4200              :     }
    4201           78 :     else if (IsA(setOp, SetOperationStmt))
    4202              :     {
    4203           78 :         SetOperationStmt *op = (SetOperationStmt *) setOp;
    4204              : 
    4205              :         /* EXCEPT is no good (point 2 for subquery_is_pushdown_safe) */
    4206           78 :         if (op->op == SETOP_EXCEPT)
    4207            0 :             return false;
    4208              :         /* Else recurse */
    4209           78 :         if (!recurse_pushdown_safe(op->larg, topquery, safetyInfo))
    4210            0 :             return false;
    4211           78 :         if (!recurse_pushdown_safe(op->rarg, topquery, safetyInfo))
    4212            0 :             return false;
    4213              :     }
    4214              :     else
    4215              :     {
    4216            0 :         elog(ERROR, "unrecognized node type: %d",
    4217              :              (int) nodeTag(setOp));
    4218              :     }
    4219           78 :     return true;
    4220              : }
    4221              : 
    4222              : /*
    4223              :  * check_output_expressions - check subquery's output expressions for safety
    4224              :  *
    4225              :  * There are several cases in which it's unsafe to push down an upper-level
    4226              :  * qual if it references a particular output column of a subquery.  We check
    4227              :  * each output column of the subquery and set flags in unsafeFlags[k] when we
    4228              :  * see that column is unsafe for a pushed-down qual to reference.  The
    4229              :  * conditions checked here are:
    4230              :  *
    4231              :  * 1. We must not push down any quals that refer to subselect outputs that
    4232              :  * return sets, else we'd introduce functions-returning-sets into the
    4233              :  * subquery's WHERE/HAVING quals.
    4234              :  *
    4235              :  * 2. We must not push down any quals that refer to subselect outputs that
    4236              :  * contain volatile functions, for fear of introducing strange results due
    4237              :  * to multiple evaluation of a volatile function.
    4238              :  *
    4239              :  * 3. If the subquery uses DISTINCT ON, we must not push down any quals that
    4240              :  * refer to non-DISTINCT output columns, because that could change the set
    4241              :  * of rows returned.  (This condition is vacuous for DISTINCT, because then
    4242              :  * there are no non-DISTINCT output columns, so we needn't check.  Note that
    4243              :  * subquery_is_pushdown_safe already reported that we can't use volatile
    4244              :  * quals if there's DISTINCT or DISTINCT ON.)
    4245              :  *
    4246              :  * 4. If the subquery has any window functions, we must not push down quals
    4247              :  * that reference any output columns that are not listed in all the subquery's
    4248              :  * window PARTITION BY clauses.  We can push down quals that use only
    4249              :  * partitioning columns because they should succeed or fail identically for
    4250              :  * every row of any one window partition, and totally excluding some
    4251              :  * partitions will not change a window function's results for remaining
    4252              :  * partitions.  (Again, this also requires nonvolatile quals, but
    4253              :  * subquery_is_pushdown_safe handles that.).  Subquery columns marked as
    4254              :  * unsafe for this reason can still have WindowClause run conditions pushed
    4255              :  * down.
    4256              :  */
    4257              : static void
    4258         1566 : check_output_expressions(Query *subquery, pushdown_safety_info *safetyInfo)
    4259              : {
    4260         1566 :     List       *flattened_targetList = subquery->targetList;
    4261              :     ListCell   *lc;
    4262              : 
    4263              :     /*
    4264              :      * We must be careful with grouping Vars and join alias Vars in the
    4265              :      * subquery's outputs, as they hide the underlying expressions.
    4266              :      *
    4267              :      * We need to expand grouping Vars to their underlying expressions (the
    4268              :      * grouping clauses) because the grouping expressions themselves might be
    4269              :      * volatile or set-returning.  However, we do not need to expand join
    4270              :      * alias Vars, as their underlying structure does not introduce volatile
    4271              :      * or set-returning functions at the current level.
    4272              :      *
    4273              :      * In neither case do we need to recursively examine the Vars contained in
    4274              :      * these underlying expressions.  Even if they reference outputs from
    4275              :      * lower-level subqueries (at any depth), those references are guaranteed
    4276              :      * not to expand to volatile or set-returning functions, because
    4277              :      * subqueries containing such functions in their targetlists are never
    4278              :      * pulled up.
    4279              :      */
    4280         1566 :     if (subquery->hasGroupRTE)
    4281              :     {
    4282              :         /*
    4283              :          * We can safely pass NULL for the root here.  This function uses the
    4284              :          * expanded expressions solely to check for volatile or set-returning
    4285              :          * functions, which is independent of the Vars' nullingrels.
    4286              :          */
    4287              :         flattened_targetList = (List *)
    4288          160 :             flatten_group_exprs(NULL, subquery, (Node *) subquery->targetList);
    4289              :     }
    4290              : 
    4291        18139 :     foreach(lc, flattened_targetList)
    4292              :     {
    4293        16573 :         TargetEntry *tle = (TargetEntry *) lfirst(lc);
    4294              : 
    4295        16573 :         if (tle->resjunk)
    4296           67 :             continue;           /* ignore resjunk columns */
    4297              : 
    4298              :         /* Functions returning sets are unsafe (point 1) */
    4299        16506 :         if (subquery->hasTargetSRFs &&
    4300          720 :             (safetyInfo->unsafeFlags[tle->resno] &
    4301          720 :              UNSAFE_HAS_SET_FUNC) == 0 &&
    4302          720 :             expression_returns_set((Node *) tle->expr))
    4303              :         {
    4304          568 :             safetyInfo->unsafeFlags[tle->resno] |= UNSAFE_HAS_SET_FUNC;
    4305          568 :             continue;
    4306              :         }
    4307              : 
    4308              :         /* Volatile functions are unsafe (point 2) */
    4309        15938 :         if ((safetyInfo->unsafeFlags[tle->resno] &
    4310        15932 :              UNSAFE_HAS_VOLATILE_FUNC) == 0 &&
    4311        15932 :             contain_volatile_functions((Node *) tle->expr))
    4312              :         {
    4313           45 :             safetyInfo->unsafeFlags[tle->resno] |= UNSAFE_HAS_VOLATILE_FUNC;
    4314           45 :             continue;
    4315              :         }
    4316              : 
    4317              :         /* If subquery uses DISTINCT ON, check point 3 */
    4318        15893 :         if (subquery->hasDistinctOn &&
    4319            0 :             (safetyInfo->unsafeFlags[tle->resno] &
    4320            0 :              UNSAFE_NOTIN_DISTINCTON_CLAUSE) == 0 &&
    4321            0 :             !targetIsInSortList(tle, InvalidOid, subquery->distinctClause))
    4322              :         {
    4323              :             /* non-DISTINCT column, so mark it unsafe */
    4324            0 :             safetyInfo->unsafeFlags[tle->resno] |= UNSAFE_NOTIN_DISTINCTON_CLAUSE;
    4325            0 :             continue;
    4326              :         }
    4327              : 
    4328              :         /* If subquery uses window functions, check point 4 */
    4329        15893 :         if (subquery->hasWindowFuncs &&
    4330          545 :             (safetyInfo->unsafeFlags[tle->resno] &
    4331         1046 :              UNSAFE_NOTIN_DISTINCTON_CLAUSE) == 0 &&
    4332          545 :             !targetIsInAllPartitionLists(tle, subquery))
    4333              :         {
    4334              :             /* not present in all PARTITION BY clauses, so mark it unsafe */
    4335          501 :             safetyInfo->unsafeFlags[tle->resno] |= UNSAFE_NOTIN_PARTITIONBY_CLAUSE;
    4336          501 :             continue;
    4337              :         }
    4338              :     }
    4339         1566 : }
    4340              : 
    4341              : /*
    4342              :  * For subqueries using UNION/UNION ALL/INTERSECT/INTERSECT ALL, we can
    4343              :  * push quals into each component query, but the quals can only reference
    4344              :  * subquery columns that suffer no type coercions in the set operation.
    4345              :  * Otherwise there are possible semantic gotchas.  So, we check the
    4346              :  * component queries to see if any of them have output types different from
    4347              :  * the top-level setop outputs.  We set the UNSAFE_TYPE_MISMATCH bit in
    4348              :  * unsafeFlags[k] if column k has different type in any component.
    4349              :  *
    4350              :  * We don't have to care about typmods here: the only allowed difference
    4351              :  * between set-op input and output typmods is input is a specific typmod
    4352              :  * and output is -1, and that does not require a coercion.
    4353              :  *
    4354              :  * tlist is a subquery tlist.
    4355              :  * colTypes is an OID list of the top-level setop's output column types.
    4356              :  * safetyInfo is the pushdown_safety_info to set unsafeFlags[] for.
    4357              :  */
    4358              : static void
    4359          156 : compare_tlist_datatypes(List *tlist, List *colTypes,
    4360              :                         pushdown_safety_info *safetyInfo)
    4361              : {
    4362              :     ListCell   *l;
    4363          156 :     ListCell   *colType = list_head(colTypes);
    4364              : 
    4365          492 :     foreach(l, tlist)
    4366              :     {
    4367          336 :         TargetEntry *tle = (TargetEntry *) lfirst(l);
    4368              : 
    4369          336 :         if (tle->resjunk)
    4370            0 :             continue;           /* ignore resjunk columns */
    4371          336 :         if (colType == NULL)
    4372            0 :             elog(ERROR, "wrong number of tlist entries");
    4373          336 :         if (exprType((Node *) tle->expr) != lfirst_oid(colType))
    4374           52 :             safetyInfo->unsafeFlags[tle->resno] |= UNSAFE_TYPE_MISMATCH;
    4375          336 :         colType = lnext(colTypes, colType);
    4376              :     }
    4377          156 :     if (colType != NULL)
    4378            0 :         elog(ERROR, "wrong number of tlist entries");
    4379          156 : }
    4380              : 
    4381              : /*
    4382              :  * targetIsInAllPartitionLists
    4383              :  *      True if the TargetEntry is listed in the PARTITION BY clause
    4384              :  *      of every window defined in the query.
    4385              :  *
    4386              :  * It would be safe to ignore windows not actually used by any window
    4387              :  * function, but it's not easy to get that info at this stage; and it's
    4388              :  * unlikely to be useful to spend any extra cycles getting it, since
    4389              :  * unreferenced window definitions are probably infrequent in practice.
    4390              :  */
    4391              : static bool
    4392          545 : targetIsInAllPartitionLists(TargetEntry *tle, Query *query)
    4393              : {
    4394              :     ListCell   *lc;
    4395              : 
    4396          601 :     foreach(lc, query->windowClause)
    4397              :     {
    4398          557 :         WindowClause *wc = (WindowClause *) lfirst(lc);
    4399              : 
    4400          557 :         if (!targetIsInSortList(tle, InvalidOid, wc->partitionClause))
    4401          501 :             return false;
    4402              :     }
    4403           44 :     return true;
    4404              : }
    4405              : 
    4406              : /*
    4407              :  * qual_is_pushdown_safe - is a particular rinfo safe to push down?
    4408              :  *
    4409              :  * rinfo is a restriction clause applying to the given subquery (whose RTE
    4410              :  * has index rti in the parent query).
    4411              :  *
    4412              :  * Conditions checked here:
    4413              :  *
    4414              :  * 1. rinfo's clause must not contain any SubPlans (mainly because it's
    4415              :  * unclear that it will work correctly: SubLinks will already have been
    4416              :  * transformed into SubPlans in the qual, but not in the subquery).  Note that
    4417              :  * SubLinks that transform to initplans are safe, and will be accepted here
    4418              :  * because what we'll see in the qual is just a Param referencing the initplan
    4419              :  * output.
    4420              :  *
    4421              :  * 2. If unsafeVolatile is set, rinfo's clause must not contain any volatile
    4422              :  * functions.
    4423              :  *
    4424              :  * 3. If unsafeLeaky is set, rinfo's clause must not contain any leaky
    4425              :  * functions that are passed Var nodes, and therefore might reveal values from
    4426              :  * the subquery as side effects.
    4427              :  *
    4428              :  * 4. rinfo's clause must not refer to the whole-row output of the subquery
    4429              :  * (since there is no easy way to name that within the subquery itself).
    4430              :  *
    4431              :  * 5. rinfo's clause must not refer to any subquery output columns that were
    4432              :  * found to be unsafe to reference by subquery_is_pushdown_safe().
    4433              :  */
    4434              : static pushdown_safe_type
    4435         2508 : qual_is_pushdown_safe(Query *subquery, Index rti, RestrictInfo *rinfo,
    4436              :                       pushdown_safety_info *safetyInfo)
    4437              : {
    4438         2508 :     pushdown_safe_type safe = PUSHDOWN_SAFE;
    4439         2508 :     Node       *qual = (Node *) rinfo->clause;
    4440              :     List       *vars;
    4441              :     ListCell   *vl;
    4442              : 
    4443              :     /* Refuse subselects (point 1) */
    4444         2508 :     if (contain_subplans(qual))
    4445           33 :         return PUSHDOWN_UNSAFE;
    4446              : 
    4447              :     /* Refuse volatile quals if we found they'd be unsafe (point 2) */
    4448         2994 :     if (safetyInfo->unsafeVolatile &&
    4449          519 :         contain_volatile_functions((Node *) rinfo))
    4450            9 :         return PUSHDOWN_UNSAFE;
    4451              : 
    4452              :     /* Refuse leaky quals if told to (point 3) */
    4453         3974 :     if (safetyInfo->unsafeLeaky &&
    4454         1508 :         contain_leaked_vars(qual))
    4455           81 :         return PUSHDOWN_UNSAFE;
    4456              : 
    4457              :     /*
    4458              :      * Examine all Vars used in clause.  Since it's a restriction clause, all
    4459              :      * such Vars must refer to subselect output columns ... unless this is
    4460              :      * part of a LATERAL subquery, in which case there could be lateral
    4461              :      * references.
    4462              :      *
    4463              :      * By omitting the relevant flags, this also gives us a cheap sanity check
    4464              :      * that no aggregates or window functions appear in the qual.  Those would
    4465              :      * be unsafe to push down, but at least for the moment we could never see
    4466              :      * any in a qual anyhow.
    4467              :      */
    4468         2385 :     vars = pull_var_clause(qual, PVC_INCLUDE_PLACEHOLDERS);
    4469         4521 :     foreach(vl, vars)
    4470              :     {
    4471         2439 :         Var        *var = (Var *) lfirst(vl);
    4472              : 
    4473              :         /*
    4474              :          * XXX Punt if we find any PlaceHolderVars in the restriction clause.
    4475              :          * It's not clear whether a PHV could safely be pushed down, and even
    4476              :          * less clear whether such a situation could arise in any cases of
    4477              :          * practical interest anyway.  So for the moment, just refuse to push
    4478              :          * down.
    4479              :          */
    4480         2439 :         if (!IsA(var, Var))
    4481              :         {
    4482            0 :             safe = PUSHDOWN_UNSAFE;
    4483            0 :             break;
    4484              :         }
    4485              : 
    4486              :         /*
    4487              :          * Punt if we find any lateral references.  It would be safe to push
    4488              :          * these down, but we'd have to convert them into outer references,
    4489              :          * which subquery_push_qual lacks the infrastructure to do.  The case
    4490              :          * arises so seldom that it doesn't seem worth working hard on.
    4491              :          */
    4492         2439 :         if (var->varno != rti)
    4493              :         {
    4494            6 :             safe = PUSHDOWN_UNSAFE;
    4495            6 :             break;
    4496              :         }
    4497              : 
    4498              :         /* Subqueries have no system columns */
    4499              :         Assert(var->varattno >= 0);
    4500              : 
    4501              :         /* Check point 4 */
    4502         2433 :         if (var->varattno == 0)
    4503              :         {
    4504            0 :             safe = PUSHDOWN_UNSAFE;
    4505            0 :             break;
    4506              :         }
    4507              : 
    4508              :         /* Check point 5 */
    4509         2433 :         if (safetyInfo->unsafeFlags[var->varattno] != 0)
    4510              :         {
    4511          462 :             if (safetyInfo->unsafeFlags[var->varattno] &
    4512              :                 (UNSAFE_HAS_VOLATILE_FUNC | UNSAFE_HAS_SET_FUNC |
    4513              :                  UNSAFE_NOTIN_DISTINCTON_CLAUSE | UNSAFE_TYPE_MISMATCH))
    4514              :             {
    4515          297 :                 safe = PUSHDOWN_UNSAFE;
    4516          297 :                 break;
    4517              :             }
    4518              :             else
    4519              :             {
    4520              :                 /* UNSAFE_NOTIN_PARTITIONBY_CLAUSE is ok for run conditions */
    4521          165 :                 safe = PUSHDOWN_WINDOWCLAUSE_RUNCOND;
    4522              :                 /* don't break, we might find another Var that's unsafe */
    4523              :             }
    4524              :         }
    4525              :     }
    4526              : 
    4527         2385 :     list_free(vars);
    4528              : 
    4529         2385 :     return safe;
    4530              : }
    4531              : 
    4532              : /*
    4533              :  * subquery_push_qual - push down a qual that we have determined is safe
    4534              :  */
    4535              : static void
    4536         2088 : subquery_push_qual(Query *subquery, RangeTblEntry *rte, Index rti, Node *qual)
    4537              : {
    4538         2088 :     if (subquery->setOperations != NULL)
    4539              :     {
    4540              :         /* Recurse to push it separately to each component query */
    4541           66 :         recurse_push_qual(subquery->setOperations, subquery,
    4542              :                           rte, rti, qual);
    4543              :     }
    4544              :     else
    4545              :     {
    4546              :         /*
    4547              :          * We need to replace Vars in the qual (which must refer to outputs of
    4548              :          * the subquery) with copies of the subquery's targetlist expressions.
    4549              :          * Note that at this point, any uplevel Vars in the qual should have
    4550              :          * been replaced with Params, so they need no work.
    4551              :          *
    4552              :          * This step also ensures that when we are pushing into a setop tree,
    4553              :          * each component query gets its own copy of the qual.
    4554              :          */
    4555         2022 :         qual = ReplaceVarsFromTargetList(qual, rti, 0, rte,
    4556              :                                          subquery->targetList,
    4557              :                                          subquery->resultRelation,
    4558              :                                          REPLACEVARS_REPORT_ERROR, 0,
    4559              :                                          &subquery->hasSubLinks);
    4560              : 
    4561              :         /*
    4562              :          * Now attach the qual to the proper place: normally WHERE, but if the
    4563              :          * subquery uses grouping or aggregation, put it in HAVING (since the
    4564              :          * qual really refers to the group-result rows).
    4565              :          */
    4566         2022 :         if (subquery->hasAggs || subquery->groupClause || subquery->groupingSets || subquery->havingQual)
    4567          196 :             subquery->havingQual = make_and_qual(subquery->havingQual, qual);
    4568              :         else
    4569         1826 :             subquery->jointree->quals =
    4570         1826 :                 make_and_qual(subquery->jointree->quals, qual);
    4571              : 
    4572              :         /*
    4573              :          * We need not change the subquery's hasAggs or hasSubLinks flags,
    4574              :          * since we can't be pushing down any aggregates that weren't there
    4575              :          * before, and we don't push down subselects at all.
    4576              :          */
    4577              :     }
    4578         2088 : }
    4579              : 
    4580              : /*
    4581              :  * Helper routine to recurse through setOperations tree
    4582              :  */
    4583              : static void
    4584          198 : recurse_push_qual(Node *setOp, Query *topquery,
    4585              :                   RangeTblEntry *rte, Index rti, Node *qual)
    4586              : {
    4587          198 :     if (IsA(setOp, RangeTblRef))
    4588              :     {
    4589          132 :         RangeTblRef *rtr = (RangeTblRef *) setOp;
    4590          132 :         RangeTblEntry *subrte = rt_fetch(rtr->rtindex, topquery->rtable);
    4591          132 :         Query      *subquery = subrte->subquery;
    4592              : 
    4593              :         Assert(subquery != NULL);
    4594          132 :         subquery_push_qual(subquery, rte, rti, qual);
    4595              :     }
    4596           66 :     else if (IsA(setOp, SetOperationStmt))
    4597              :     {
    4598           66 :         SetOperationStmt *op = (SetOperationStmt *) setOp;
    4599              : 
    4600           66 :         recurse_push_qual(op->larg, topquery, rte, rti, qual);
    4601           66 :         recurse_push_qual(op->rarg, topquery, rte, rti, qual);
    4602              :     }
    4603              :     else
    4604              :     {
    4605            0 :         elog(ERROR, "unrecognized node type: %d",
    4606              :              (int) nodeTag(setOp));
    4607              :     }
    4608          198 : }
    4609              : 
    4610              : /*****************************************************************************
    4611              :  *          SIMPLIFYING SUBQUERY TARGETLISTS
    4612              :  *****************************************************************************/
    4613              : 
    4614              : /*
    4615              :  * remove_unused_subquery_outputs
    4616              :  *      Remove subquery targetlist items we don't need
    4617              :  *
    4618              :  * It's possible, even likely, that the upper query does not read all the
    4619              :  * output columns of the subquery.  We can remove any such outputs that are
    4620              :  * not needed by the subquery itself (e.g., as sort/group columns) and do not
    4621              :  * affect semantics otherwise (e.g., volatile functions can't be removed).
    4622              :  * This is useful not only because we might be able to remove expensive-to-
    4623              :  * compute expressions, but because deletion of output columns might allow
    4624              :  * optimizations such as join removal to occur within the subquery.
    4625              :  *
    4626              :  * extra_used_attrs can be passed as non-NULL to mark any columns (offset by
    4627              :  * FirstLowInvalidHeapAttributeNumber) that we should not remove.  This
    4628              :  * parameter is modified by the function, so callers must make a copy if they
    4629              :  * need to use the passed in Bitmapset after calling this function.
    4630              :  *
    4631              :  * To avoid affecting column numbering in the targetlist, we don't physically
    4632              :  * remove unused tlist entries, but rather replace their expressions with NULL
    4633              :  * constants.  This is implemented by modifying subquery->targetList.
    4634              :  */
    4635              : static void
    4636        13383 : remove_unused_subquery_outputs(Query *subquery, RelOptInfo *rel,
    4637              :                                Bitmapset *extra_used_attrs)
    4638              : {
    4639              :     Bitmapset  *attrs_used;
    4640              :     ListCell   *lc;
    4641              : 
    4642              :     /*
    4643              :      * Just point directly to extra_used_attrs. No need to bms_copy as none of
    4644              :      * the current callers use the Bitmapset after calling this function.
    4645              :      */
    4646        13383 :     attrs_used = extra_used_attrs;
    4647              : 
    4648              :     /*
    4649              :      * Do nothing if subquery has UNION/INTERSECT/EXCEPT: in principle we
    4650              :      * could update all the child SELECTs' tlists, but it seems not worth the
    4651              :      * trouble presently.
    4652              :      */
    4653        13383 :     if (subquery->setOperations)
    4654         1065 :         return;
    4655              : 
    4656              :     /*
    4657              :      * If subquery has regular DISTINCT (not DISTINCT ON), we're wasting our
    4658              :      * time: all its output columns must be used in the distinctClause.
    4659              :      */
    4660        12922 :     if (subquery->distinctClause && !subquery->hasDistinctOn)
    4661          447 :         return;
    4662              : 
    4663              :     /*
    4664              :      * Collect a bitmap of all the output column numbers used by the upper
    4665              :      * query.
    4666              :      *
    4667              :      * Add all the attributes needed for joins or final output.  Note: we must
    4668              :      * look at rel's targetlist, not the attr_needed data, because attr_needed
    4669              :      * isn't computed for inheritance child rels, cf set_append_rel_size().
    4670              :      * (XXX might be worth changing that sometime.)
    4671              :      */
    4672        12475 :     pull_varattnos((Node *) rel->reltarget->exprs, rel->relid, &attrs_used);
    4673              : 
    4674              :     /* Add all the attributes used by un-pushed-down restriction clauses. */
    4675        13042 :     foreach(lc, rel->baserestrictinfo)
    4676              :     {
    4677          567 :         RestrictInfo *rinfo = (RestrictInfo *) lfirst(lc);
    4678              : 
    4679          567 :         pull_varattnos((Node *) rinfo->clause, rel->relid, &attrs_used);
    4680              :     }
    4681              : 
    4682              :     /*
    4683              :      * If there's a whole-row reference to the subquery, we can't remove
    4684              :      * anything.
    4685              :      */
    4686        12475 :     if (bms_is_member(0 - FirstLowInvalidHeapAttributeNumber, attrs_used))
    4687          157 :         return;
    4688              : 
    4689              :     /*
    4690              :      * Run through the tlist and zap entries we don't need.  It's okay to
    4691              :      * modify the tlist items in-place because set_subquery_pathlist made a
    4692              :      * copy of the subquery.
    4693              :      */
    4694        70855 :     foreach(lc, subquery->targetList)
    4695              :     {
    4696        58537 :         TargetEntry *tle = (TargetEntry *) lfirst(lc);
    4697        58537 :         Node       *texpr = (Node *) tle->expr;
    4698              : 
    4699              :         /*
    4700              :          * If it has a sortgroupref number, it's used in some sort/group
    4701              :          * clause so we'd better not remove it.  Also, don't remove any
    4702              :          * resjunk columns, since their reason for being has nothing to do
    4703              :          * with anybody reading the subquery's output.  (It's likely that
    4704              :          * resjunk columns in a sub-SELECT would always have ressortgroupref
    4705              :          * set, but even if they don't, it seems imprudent to remove them.)
    4706              :          */
    4707        58537 :         if (tle->ressortgroupref || tle->resjunk)
    4708         1502 :             continue;
    4709              : 
    4710              :         /*
    4711              :          * If it's used by the upper query, we can't remove it.
    4712              :          */
    4713        57035 :         if (bms_is_member(tle->resno - FirstLowInvalidHeapAttributeNumber,
    4714              :                           attrs_used))
    4715        32600 :             continue;
    4716              : 
    4717              :         /*
    4718              :          * If it contains a set-returning function, we can't remove it since
    4719              :          * that could change the number of rows returned by the subquery.
    4720              :          */
    4721        24981 :         if (subquery->hasTargetSRFs &&
    4722          546 :             expression_returns_set(texpr))
    4723          412 :             continue;
    4724              : 
    4725              :         /*
    4726              :          * If it contains volatile functions, we daren't remove it for fear
    4727              :          * that the user is expecting their side-effects to happen.
    4728              :          */
    4729        24023 :         if (contain_volatile_functions(texpr))
    4730           16 :             continue;
    4731              : 
    4732              :         /*
    4733              :          * OK, we don't need it.  Replace the expression with a NULL constant.
    4734              :          * Preserve the exposed type of the expression, in case something
    4735              :          * looks at the rowtype of the subquery's result.
    4736              :          */
    4737        24007 :         tle->expr = (Expr *) makeNullConst(exprType(texpr),
    4738              :                                            exprTypmod(texpr),
    4739              :                                            exprCollation(texpr));
    4740              :     }
    4741              : }
    4742              : 
    4743              : /*
    4744              :  * create_partial_bitmap_paths
    4745              :  *    Build partial bitmap heap path for the relation
    4746              :  */
    4747              : void
    4748        81359 : create_partial_bitmap_paths(PlannerInfo *root, RelOptInfo *rel,
    4749              :                             Path *bitmapqual)
    4750              : {
    4751              :     int         parallel_workers;
    4752              :     double      pages_fetched;
    4753              : 
    4754              :     /* Compute heap pages for bitmap heap scan */
    4755        81359 :     pages_fetched = compute_bitmap_pages(root, rel, bitmapqual, 1.0,
    4756              :                                          NULL, NULL);
    4757              : 
    4758        81359 :     parallel_workers = compute_parallel_worker(rel, pages_fetched, -1,
    4759              :                                                max_parallel_workers_per_gather);
    4760              : 
    4761        81359 :     if (parallel_workers <= 0)
    4762        78871 :         return;
    4763              : 
    4764         2488 :     add_partial_path(rel, (Path *) create_bitmap_heap_path(root, rel,
    4765              :                                                            bitmapqual, rel->lateral_relids, 1.0, parallel_workers));
    4766              : }
    4767              : 
    4768              : /*
    4769              :  * Compute the number of parallel workers that should be used to scan a
    4770              :  * relation.  We compute the parallel workers based on the size of the heap to
    4771              :  * be scanned and the size of the index to be scanned, then choose a minimum
    4772              :  * of those.
    4773              :  *
    4774              :  * "heap_pages" is the number of pages from the table that we expect to scan, or
    4775              :  * -1 if we don't expect to scan any.
    4776              :  *
    4777              :  * "index_pages" is the number of pages from the index that we expect to scan, or
    4778              :  * -1 if we don't expect to scan any.
    4779              :  *
    4780              :  * "max_workers" is caller's limit on the number of workers.  This typically
    4781              :  * comes from a GUC.
    4782              :  */
    4783              : int
    4784       434901 : compute_parallel_worker(RelOptInfo *rel, double heap_pages, double index_pages,
    4785              :                         int max_workers)
    4786              : {
    4787       434901 :     int         parallel_workers = 0;
    4788              : 
    4789              :     /*
    4790              :      * If the user has set the parallel_workers reloption, use that; otherwise
    4791              :      * select a default number of workers.
    4792              :      */
    4793       434901 :     if (rel->rel_parallel_workers != -1)
    4794         1650 :         parallel_workers = rel->rel_parallel_workers;
    4795              :     else
    4796              :     {
    4797              :         /*
    4798              :          * If the number of pages being scanned is insufficient to justify a
    4799              :          * parallel scan, just return zero ... unless it's an inheritance
    4800              :          * child. In that case, we want to generate a parallel path here
    4801              :          * anyway.  It might not be worthwhile just for this relation, but
    4802              :          * when combined with all of its inheritance siblings it may well pay
    4803              :          * off.
    4804              :          */
    4805       433251 :         if (rel->reloptkind == RELOPT_BASEREL &&
    4806       412853 :             ((heap_pages >= 0 && heap_pages < min_parallel_table_scan_size) ||
    4807        14334 :              (index_pages >= 0 && index_pages < min_parallel_index_scan_size)))
    4808       412365 :             return 0;
    4809              : 
    4810        20886 :         if (heap_pages >= 0)
    4811              :         {
    4812              :             int         heap_parallel_threshold;
    4813        19820 :             int         heap_parallel_workers = 1;
    4814              : 
    4815              :             /*
    4816              :              * Select the number of workers based on the log of the size of
    4817              :              * the relation.  This probably needs to be a good deal more
    4818              :              * sophisticated, but we need something here for now.  Note that
    4819              :              * the upper limit of the min_parallel_table_scan_size GUC is
    4820              :              * chosen to prevent overflow here.
    4821              :              */
    4822        19820 :             heap_parallel_threshold = Max(min_parallel_table_scan_size, 1);
    4823        22587 :             while (heap_pages >= (BlockNumber) (heap_parallel_threshold * 3))
    4824              :             {
    4825         2767 :                 heap_parallel_workers++;
    4826         2767 :                 heap_parallel_threshold *= 3;
    4827         2767 :                 if (heap_parallel_threshold > INT_MAX / 3)
    4828            0 :                     break;      /* avoid overflow */
    4829              :             }
    4830              : 
    4831        19820 :             parallel_workers = heap_parallel_workers;
    4832              :         }
    4833              : 
    4834        20886 :         if (index_pages >= 0)
    4835              :         {
    4836         4991 :             int         index_parallel_workers = 1;
    4837              :             int         index_parallel_threshold;
    4838              : 
    4839              :             /* same calculation as for heap_pages above */
    4840         4991 :             index_parallel_threshold = Max(min_parallel_index_scan_size, 1);
    4841         5129 :             while (index_pages >= (BlockNumber) (index_parallel_threshold * 3))
    4842              :             {
    4843          138 :                 index_parallel_workers++;
    4844          138 :                 index_parallel_threshold *= 3;
    4845          138 :                 if (index_parallel_threshold > INT_MAX / 3)
    4846            0 :                     break;      /* avoid overflow */
    4847              :             }
    4848              : 
    4849         4991 :             if (parallel_workers > 0)
    4850         3925 :                 parallel_workers = Min(parallel_workers, index_parallel_workers);
    4851              :             else
    4852         1066 :                 parallel_workers = index_parallel_workers;
    4853              :         }
    4854              :     }
    4855              : 
    4856              :     /* In no case use more than caller supplied maximum number of workers */
    4857        22536 :     parallel_workers = Min(parallel_workers, max_workers);
    4858              : 
    4859        22536 :     return parallel_workers;
    4860              : }
    4861              : 
    4862              : /*
    4863              :  * generate_partitionwise_join_paths
    4864              :  *      Create paths representing partitionwise join for given partitioned
    4865              :  *      join relation.
    4866              :  *
    4867              :  * This must not be called until after we are done adding paths for all
    4868              :  * child-joins. Otherwise, add_path might delete a path to which some path
    4869              :  * generated here has a reference.
    4870              :  */
    4871              : void
    4872       138637 : generate_partitionwise_join_paths(PlannerInfo *root, RelOptInfo *rel)
    4873              : {
    4874       138637 :     List       *live_children = NIL;
    4875              :     int         cnt_parts;
    4876              :     int         num_parts;
    4877              :     RelOptInfo **part_rels;
    4878              : 
    4879              :     /* Handle only join relations here. */
    4880       138637 :     if (!IS_JOIN_REL(rel))
    4881            0 :         return;
    4882              : 
    4883              :     /* We've nothing to do if the relation is not partitioned. */
    4884       138637 :     if (!IS_PARTITIONED_REL(rel))
    4885       135040 :         return;
    4886              : 
    4887              :     /* The relation should have consider_partitionwise_join set. */
    4888              :     Assert(rel->consider_partitionwise_join);
    4889              : 
    4890              :     /* Guard against stack overflow due to overly deep partition hierarchy. */
    4891         3597 :     check_stack_depth();
    4892              : 
    4893         3597 :     num_parts = rel->nparts;
    4894         3597 :     part_rels = rel->part_rels;
    4895              : 
    4896              :     /* Collect non-dummy child-joins. */
    4897        12820 :     for (cnt_parts = 0; cnt_parts < num_parts; cnt_parts++)
    4898              :     {
    4899         9223 :         RelOptInfo *child_rel = part_rels[cnt_parts];
    4900              : 
    4901              :         /* If it's been pruned entirely, it's certainly dummy. */
    4902         9223 :         if (child_rel == NULL)
    4903           32 :             continue;
    4904              : 
    4905              :         /* Make partitionwise join paths for this partitioned child-join. */
    4906         9191 :         generate_partitionwise_join_paths(root, child_rel);
    4907              : 
    4908              :         /* If we failed to make any path for this child, we must give up. */
    4909         9191 :         if (child_rel->pathlist == NIL)
    4910              :         {
    4911              :             /*
    4912              :              * Mark the parent joinrel as unpartitioned so that later
    4913              :              * functions treat it correctly.
    4914              :              */
    4915            0 :             rel->nparts = 0;
    4916            0 :             return;
    4917              :         }
    4918              : 
    4919              :         /* Else, identify the cheapest path for it. */
    4920         9191 :         set_cheapest(child_rel);
    4921              : 
    4922              :         /* Dummy children need not be scanned, so ignore those. */
    4923         9191 :         if (IS_DUMMY_REL(child_rel))
    4924            0 :             continue;
    4925              : 
    4926              :         /*
    4927              :          * Except for the topmost scan/join rel, consider generating partial
    4928              :          * aggregation paths for the grouped relation on top of the paths of
    4929              :          * this partitioned child-join.  After that, we're done creating paths
    4930              :          * for the grouped relation, so run set_cheapest().
    4931              :          */
    4932         9191 :         if (child_rel->grouped_rel != NULL &&
    4933         6438 :             !bms_equal(IS_OTHER_REL(rel) ?
    4934              :                        rel->top_parent_relids : rel->relids,
    4935         6438 :                        root->all_query_rels))
    4936              :         {
    4937          120 :             RelOptInfo *grouped_rel = child_rel->grouped_rel;
    4938              : 
    4939              :             Assert(IS_GROUPED_REL(grouped_rel));
    4940              : 
    4941          120 :             generate_grouped_paths(root, grouped_rel, child_rel);
    4942          120 :             set_cheapest(grouped_rel);
    4943              :         }
    4944              : 
    4945              : #ifdef OPTIMIZER_DEBUG
    4946              :         pprint(child_rel);
    4947              : #endif
    4948              : 
    4949         9191 :         live_children = lappend(live_children, child_rel);
    4950              :     }
    4951              : 
    4952              :     /* If all child-joins are dummy, parent join is also dummy. */
    4953         3597 :     if (!live_children)
    4954              :     {
    4955            0 :         mark_dummy_rel(rel);
    4956            0 :         return;
    4957              :     }
    4958              : 
    4959              :     /* Build additional paths for this rel from child-join paths. */
    4960         3597 :     add_paths_to_append_rel(root, rel, live_children);
    4961         3597 :     list_free(live_children);
    4962              : }
        

Generated by: LCOV version 2.0-1