aboutsummaryrefslogtreecommitdiff
path: root/src/include
diff options
context:
space:
mode:
Diffstat (limited to 'src/include')
-rw-r--r--src/include/nodes/nodes.h54
-rw-r--r--src/include/nodes/plannodes.h32
-rw-r--r--src/include/nodes/relation.h295
-rw-r--r--src/include/optimizer/cost.h7
-rw-r--r--src/include/optimizer/pathnode.h98
-rw-r--r--src/include/optimizer/paths.h8
-rw-r--r--src/include/optimizer/planmain.h45
-rw-r--r--src/include/optimizer/planner.h11
-rw-r--r--src/include/optimizer/prep.h3
-rw-r--r--src/include/optimizer/subselect.h8
-rw-r--r--src/include/optimizer/tlist.h11
11 files changed, 449 insertions, 123 deletions
diff --git a/src/include/nodes/nodes.h b/src/include/nodes/nodes.h
index c407fa2cd49..fad9988119f 100644
--- a/src/include/nodes/nodes.h
+++ b/src/include/nodes/nodes.h
@@ -229,18 +229,33 @@ typedef enum NodeTag
T_BitmapHeapPath,
T_BitmapAndPath,
T_BitmapOrPath,
- T_NestPath,
- T_MergePath,
- T_HashPath,
T_TidPath,
+ T_SubqueryScanPath,
T_ForeignPath,
T_CustomPath,
+ T_NestPath,
+ T_MergePath,
+ T_HashPath,
T_AppendPath,
T_MergeAppendPath,
T_ResultPath,
T_MaterialPath,
T_UniquePath,
T_GatherPath,
+ T_ProjectionPath,
+ T_SortPath,
+ T_GroupPath,
+ T_UpperUniquePath,
+ T_AggPath,
+ T_GroupingSetsPath,
+ T_MinMaxAggPath,
+ T_WindowAggPath,
+ T_SetOpPath,
+ T_RecursiveUnionPath,
+ T_LockRowsPath,
+ T_ModifyTablePath,
+ T_LimitPath,
+ /* these aren't subclasses of Path: */
T_EquivalenceClass,
T_EquivalenceMember,
T_PathKey,
@@ -654,6 +669,39 @@ typedef enum JoinType
(1 << JOIN_ANTI))) != 0)
/*
+ * AggStrategy -
+ * overall execution strategies for Agg plan nodes
+ *
+ * This is needed in both plannodes.h and relation.h, so put it here...
+ */
+typedef enum AggStrategy
+{
+ AGG_PLAIN, /* simple agg across all input rows */
+ AGG_SORTED, /* grouped agg, input must be sorted */
+ AGG_HASHED /* grouped agg, use internal hashtable */
+} AggStrategy;
+
+/*
+ * SetOpCmd and SetOpStrategy -
+ * overall semantics and execution strategies for SetOp plan nodes
+ *
+ * This is needed in both plannodes.h and relation.h, so put it here...
+ */
+typedef enum SetOpCmd
+{
+ SETOPCMD_INTERSECT,
+ SETOPCMD_INTERSECT_ALL,
+ SETOPCMD_EXCEPT,
+ SETOPCMD_EXCEPT_ALL
+} SetOpCmd;
+
+typedef enum SetOpStrategy
+{
+ SETOP_SORTED, /* input must be sorted */
+ SETOP_HASHED /* use internal hashtable */
+} SetOpStrategy;
+
+/*
* OnConflictAction -
* "ON CONFLICT" clause type of query
*
diff --git a/src/include/nodes/plannodes.h b/src/include/nodes/plannodes.h
index ae224cfa314..5961f2c9884 100644
--- a/src/include/nodes/plannodes.h
+++ b/src/include/nodes/plannodes.h
@@ -714,23 +714,17 @@ typedef struct Group
* we are using the Agg node to implement hash-based grouping.)
* ---------------
*/
-typedef enum AggStrategy
-{
- AGG_PLAIN, /* simple agg across all input rows */
- AGG_SORTED, /* grouped agg, input must be sorted */
- AGG_HASHED /* grouped agg, use internal hashtable */
-} AggStrategy;
-
typedef struct Agg
{
Plan plan;
- AggStrategy aggstrategy;
- int numCols; /* number of grouping columns */
- AttrNumber *grpColIdx; /* their indexes in the target list */
+ AggStrategy aggstrategy; /* basic strategy, see nodes.h */
bool combineStates; /* input tuples contain transition states */
bool finalizeAggs; /* should we call the finalfn on agg states? */
+ int numCols; /* number of grouping columns */
+ AttrNumber *grpColIdx; /* their indexes in the target list */
Oid *grpOperators; /* equality operators to compare with */
long numGroups; /* estimated number of groups in input */
+ /* Note: the planner only provides numGroups in AGG_HASHED case */
List *groupingSets; /* grouping sets to use */
List *chain; /* chained Agg/Sort nodes */
} Agg;
@@ -802,25 +796,11 @@ typedef struct Hash
* setop node
* ----------------
*/
-typedef enum SetOpCmd
-{
- SETOPCMD_INTERSECT,
- SETOPCMD_INTERSECT_ALL,
- SETOPCMD_EXCEPT,
- SETOPCMD_EXCEPT_ALL
-} SetOpCmd;
-
-typedef enum SetOpStrategy
-{
- SETOP_SORTED, /* input must be sorted */
- SETOP_HASHED /* use internal hashtable */
-} SetOpStrategy;
-
typedef struct SetOp
{
Plan plan;
- SetOpCmd cmd; /* what to do */
- SetOpStrategy strategy; /* how to do it */
+ SetOpCmd cmd; /* what to do, see nodes.h */
+ SetOpStrategy strategy; /* how to do it, see nodes.h */
int numCols; /* number of columns to check for
* duplicate-ness */
AttrNumber *dupColIdx; /* their indexes in the target list */
diff --git a/src/include/nodes/relation.h b/src/include/nodes/relation.h
index af8cb6be687..098a48690fb 100644
--- a/src/include/nodes/relation.h
+++ b/src/include/nodes/relation.h
@@ -70,16 +70,40 @@ typedef struct AggClauseCosts
* example, an indexscan might return index expressions that would otherwise
* need to be explicitly calculated.
*
- * Note that PathTarget.exprs is just a list of expressions; they do not have
- * TargetEntry nodes on top, though those will appear in the finished Plan.
+ * exprs contains bare expressions; they do not have TargetEntry nodes on top,
+ * though those will appear in finished Plans.
+ *
+ * sortgrouprefs[] is an array of the same length as exprs, containing the
+ * corresponding sort/group refnos, or zeroes for expressions not referenced
+ * by sort/group clauses. If sortgrouprefs is NULL (which it always is in
+ * RelOptInfo.reltarget structs; only upper-level Paths contain this info), we
+ * have not identified sort/group columns in this tlist. This allows us to
+ * deal with sort/group refnos when needed with less expense than including
+ * TargetEntry nodes in the exprs list.
*/
typedef struct PathTarget
{
List *exprs; /* list of expressions to be computed */
- QualCost cost; /* cost of evaluating the above */
+ Index *sortgrouprefs; /* corresponding sort/group refnos, or 0 */
+ QualCost cost; /* cost of evaluating the expressions */
int width; /* estimated avg width of result tuples */
} PathTarget;
+/*
+ * This enum identifies the different types of "upper" (post-scan/join)
+ * relations that we might deal with during planning.
+ */
+typedef enum UpperRelationKind
+{
+ UPPERREL_SETOP, /* result of UNION/INTERSECT/EXCEPT, if any */
+ UPPERREL_GROUP_AGG, /* result of grouping/aggregation, if any */
+ UPPERREL_WINDOW, /* result of window functions, if any */
+ UPPERREL_DISTINCT, /* result of "SELECT DISTINCT", if any */
+ UPPERREL_ORDERED, /* result of ORDER BY, if any */
+ UPPERREL_FINAL /* result of any remaining top-level actions */
+ /* NB: UPPERREL_FINAL must be last enum entry; it's used to size arrays */
+} UpperRelationKind;
+
/*----------
* PlannerGlobal
@@ -255,18 +279,28 @@ typedef struct PlannerInfo
List *placeholder_list; /* list of PlaceHolderInfos */
- List *query_pathkeys; /* desired pathkeys for query_planner(), and
- * actual pathkeys after planning */
+ List *query_pathkeys; /* desired pathkeys for query_planner() */
List *group_pathkeys; /* groupClause pathkeys, if any */
List *window_pathkeys; /* pathkeys of bottom window, if any */
List *distinct_pathkeys; /* distinctClause pathkeys, if any */
List *sort_pathkeys; /* sortClause pathkeys, if any */
- List *minmax_aggs; /* List of MinMaxAggInfos */
-
List *initial_rels; /* RelOptInfos we are now trying to join */
+ /* Use fetch_upper_rel() to get any particular upper rel */
+ List *upper_rels[UPPERREL_FINAL + 1]; /* upper-rel RelOptInfos */
+
+ /*
+ * grouping_planner passes back its final processed targetlist here, for
+ * use in relabeling the topmost tlist of the finished Plan.
+ */
+ List *processed_tlist;
+
+ /* Fields filled during create_plan() for use in setrefs.c */
+ AttrNumber *grouping_map; /* for GroupingFunc fixup */
+ List *minmax_aggs; /* List of MinMaxAggInfos */
+
MemoryContext planner_cxt; /* context holding PlannerInfo */
double total_table_pages; /* # of pages in all tables of query */
@@ -286,7 +320,7 @@ typedef struct PlannerInfo
/* These fields are used only when hasRecursion is true: */
int wt_param_id; /* PARAM_EXEC ID for the work table */
- struct Plan *non_recursive_plan; /* plan for non-recursive term */
+ struct Path *non_recursive_path; /* a path for non-recursive term */
/* These fields are workspace for createplan.c */
Relids curOuterRels; /* outer rels above current node */
@@ -294,9 +328,6 @@ typedef struct PlannerInfo
/* optional private data for join_search_hook, e.g., GEQO */
void *join_search_private;
-
- /* for GroupingFunc fixup in setrefs */
- AttrNumber *grouping_map;
} PlannerInfo;
@@ -328,10 +359,7 @@ typedef struct PlannerInfo
*
* We also have "other rels", which are like base rels in that they refer to
* single RT indexes; but they are not part of the join tree, and are given
- * a different RelOptKind to identify them. Lastly, there is a RelOptKind
- * for "dead" relations, which are base rels that we have proven we don't
- * need to join after all.
- *
+ * a different RelOptKind to identify them.
* Currently the only kind of otherrels are those made for member relations
* of an "append relation", that is an inheritance set or UNION ALL subquery.
* An append relation has a parent RTE that is a base rel, which represents
@@ -346,6 +374,14 @@ typedef struct PlannerInfo
* handling join alias Vars. Currently this is not needed because all join
* alias Vars are expanded to non-aliased form during preprocess_expression.
*
+ * There is also a RelOptKind for "upper" relations, which are RelOptInfos
+ * that describe post-scan/join processing steps, such as aggregation.
+ * Many of the fields in these RelOptInfos are meaningless, but their Path
+ * fields always hold Paths showing ways to do that processing step.
+ *
+ * Lastly, there is a RelOptKind for "dead" relations, which are base rels
+ * that we have proven we don't need to join after all.
+ *
* Parts of this data structure are specific to various scan and join
* mechanisms. It didn't seem worth creating new node types for them.
*
@@ -401,11 +437,10 @@ typedef struct PlannerInfo
* pages - number of disk pages in relation (zero if not a table)
* tuples - number of tuples in relation (not considering restrictions)
* allvisfrac - fraction of disk pages that are marked all-visible
- * subplan - plan for subquery (NULL if it's not a subquery)
* subroot - PlannerInfo for subquery (NULL if it's not a subquery)
* subplan_params - list of PlannerParamItems to be passed to subquery
*
- * Note: for a subquery, tuples, subplan, subroot are not set immediately
+ * Note: for a subquery, tuples and subroot are not set immediately
* upon creation of the RelOptInfo object; they are filled in when
* set_subquery_pathlist processes the object.
*
@@ -455,6 +490,7 @@ typedef enum RelOptKind
RELOPT_BASEREL,
RELOPT_JOINREL,
RELOPT_OTHER_MEMBER_REL,
+ RELOPT_UPPER_REL,
RELOPT_DEADREL
} RelOptKind;
@@ -506,8 +542,6 @@ typedef struct RelOptInfo
BlockNumber pages; /* size estimates derived from pg_class */
double tuples;
double allvisfrac;
- /* use "struct Plan" to avoid including plannodes.h here */
- struct Plan *subplan; /* if subquery */
PlannerInfo *subroot; /* if subquery */
List *subplan_params; /* if subquery */
@@ -939,6 +973,20 @@ typedef struct TidPath
} TidPath;
/*
+ * SubqueryScanPath represents a scan of an unflattened subquery-in-FROM
+ *
+ * Note that the subpath comes from a different planning domain; for example
+ * RTE indexes within it mean something different from those known to the
+ * SubqueryScanPath. path.parent->subroot is the planning context needed to
+ * interpret the subpath.
+ */
+typedef struct SubqueryScanPath
+{
+ Path path;
+ Path *subpath; /* path representing subquery execution */
+} SubqueryScanPath;
+
+/*
* ForeignPath represents a potential scan of a foreign table
*
* fdw_private stores FDW private data about the scan. While fdw_private is
@@ -1062,14 +1110,13 @@ typedef struct MaterialPath
* UniquePath represents elimination of distinct rows from the output of
* its subpath.
*
- * This is unlike the other Path nodes in that it can actually generate
- * different plans: either hash-based or sort-based implementation, or a
- * no-op if the input path can be proven distinct already. The decision
- * is sufficiently localized that it's not worth having separate Path node
- * types. (Note: in the no-op case, we could eliminate the UniquePath node
- * entirely and just return the subpath; but it's convenient to have a
- * UniquePath in the path tree to signal upper-level routines that the input
- * is known distinct.)
+ * This can represent significantly different plans: either hash-based or
+ * sort-based implementation, or a no-op if the input path can be proven
+ * distinct already. The decision is sufficiently localized that it's not
+ * worth having separate Path node types. (Note: in the no-op case, we could
+ * eliminate the UniquePath node entirely and just return the subpath; but
+ * it's convenient to have a UniquePath in the path tree to signal upper-level
+ * routines that the input is known distinct.)
*/
typedef enum
{
@@ -1181,6 +1228,195 @@ typedef struct HashPath
} HashPath;
/*
+ * ProjectionPath represents a projection (that is, targetlist computation)
+ *
+ * This path node represents using a Result plan node to do a projection.
+ * It's only needed atop a node that doesn't support projection (such as
+ * Sort); otherwise we just jam the new desired PathTarget into the lower
+ * path node, and adjust that node's estimated cost accordingly.
+ */
+typedef struct ProjectionPath
+{
+ Path path;
+ Path *subpath; /* path representing input source */
+} ProjectionPath;
+
+/*
+ * SortPath represents an explicit sort step
+ *
+ * The sort keys are, by definition, the same as path.pathkeys.
+ *
+ * Note: the Sort plan node cannot project, so path.pathtarget must be the
+ * same as the input's pathtarget.
+ */
+typedef struct SortPath
+{
+ Path path;
+ Path *subpath; /* path representing input source */
+} SortPath;
+
+/*
+ * GroupPath represents grouping (of presorted input)
+ *
+ * groupClause represents the columns to be grouped on; the input path
+ * must be at least that well sorted.
+ *
+ * We can also apply a qual to the grouped rows (equivalent of HAVING)
+ */
+typedef struct GroupPath
+{
+ Path path;
+ Path *subpath; /* path representing input source */
+ List *groupClause; /* a list of SortGroupClause's */
+ List *qual; /* quals (HAVING quals), if any */
+} GroupPath;
+
+/*
+ * UpperUniquePath represents adjacent-duplicate removal (in presorted input)
+ *
+ * The columns to be compared are the first numkeys columns of the path's
+ * pathkeys. The input is presumed already sorted that way.
+ */
+typedef struct UpperUniquePath
+{
+ Path path;
+ Path *subpath; /* path representing input source */
+ int numkeys; /* number of pathkey columns to compare */
+} UpperUniquePath;
+
+/*
+ * AggPath represents generic computation of aggregate functions
+ *
+ * This may involve plain grouping (but not grouping sets), using either
+ * sorted or hashed grouping; for the AGG_SORTED case, the input must be
+ * appropriately presorted.
+ */
+typedef struct AggPath
+{
+ Path path;
+ Path *subpath; /* path representing input source */
+ AggStrategy aggstrategy; /* basic strategy, see nodes.h */
+ double numGroups; /* estimated number of groups in input */
+ List *groupClause; /* a list of SortGroupClause's */
+ List *qual; /* quals (HAVING quals), if any */
+} AggPath;
+
+/*
+ * GroupingSetsPath represents a GROUPING SETS aggregation
+ *
+ * Currently we only support this in sorted not hashed form, so the input
+ * must always be appropriately presorted.
+ */
+typedef struct GroupingSetsPath
+{
+ Path path;
+ Path *subpath; /* path representing input source */
+ AttrNumber *groupColIdx; /* grouping col indexes */
+ List *rollup_groupclauses; /* list of lists of SortGroupClause's */
+ List *rollup_lists; /* parallel list of lists of grouping sets */
+ List *qual; /* quals (HAVING quals), if any */
+} GroupingSetsPath;
+
+/*
+ * MinMaxAggPath represents computation of MIN/MAX aggregates from indexes
+ */
+typedef struct MinMaxAggPath
+{
+ Path path;
+ List *mmaggregates; /* list of MinMaxAggInfo */
+ List *quals; /* HAVING quals, if any */
+} MinMaxAggPath;
+
+/*
+ * WindowAggPath represents generic computation of window functions
+ *
+ * Note: winpathkeys is separate from path.pathkeys because the actual sort
+ * order might be an extension of winpathkeys; but createplan.c needs to
+ * know exactly how many pathkeys match the window clause.
+ */
+typedef struct WindowAggPath
+{
+ Path path;
+ Path *subpath; /* path representing input source */
+ WindowClause *winclause; /* WindowClause we'll be using */
+ List *winpathkeys; /* PathKeys for PARTITION keys + ORDER keys */
+} WindowAggPath;
+
+/*
+ * SetOpPath represents a set-operation, that is INTERSECT or EXCEPT
+ */
+typedef struct SetOpPath
+{
+ Path path;
+ Path *subpath; /* path representing input source */
+ SetOpCmd cmd; /* what to do, see nodes.h */
+ SetOpStrategy strategy; /* how to do it, see nodes.h */
+ List *distinctList; /* SortGroupClauses identifying target cols */
+ AttrNumber flagColIdx; /* where is the flag column, if any */
+ int firstFlag; /* flag value for first input relation */
+ double numGroups; /* estimated number of groups in input */
+} SetOpPath;
+
+/*
+ * RecursiveUnionPath represents a recursive UNION node
+ */
+typedef struct RecursiveUnionPath
+{
+ Path path;
+ Path *leftpath; /* paths representing input sources */
+ Path *rightpath;
+ List *distinctList; /* SortGroupClauses identifying target cols */
+ int wtParam; /* ID of Param representing work table */
+ double numGroups; /* estimated number of groups in input */
+} RecursiveUnionPath;
+
+/*
+ * LockRowsPath represents acquiring row locks for SELECT FOR UPDATE/SHARE
+ */
+typedef struct LockRowsPath
+{
+ Path path;
+ Path *subpath; /* path representing input source */
+ List *rowMarks; /* a list of PlanRowMark's */
+ int epqParam; /* ID of Param for EvalPlanQual re-eval */
+} LockRowsPath;
+
+/*
+ * ModifyTablePath represents performing INSERT/UPDATE/DELETE modifications
+ *
+ * We represent most things that will be in the ModifyTable plan node
+ * literally, except we have child Path(s) not Plan(s). But analysis of the
+ * OnConflictExpr is deferred to createplan.c, as is collection of FDW data.
+ */
+typedef struct ModifyTablePath
+{
+ Path path;
+ CmdType operation; /* INSERT, UPDATE, or DELETE */
+ bool canSetTag; /* do we set the command tag/es_processed? */
+ Index nominalRelation; /* Parent RT index for use of EXPLAIN */
+ List *resultRelations; /* integer list of RT indexes */
+ List *subpaths; /* Path(s) producing source data */
+ List *subroots; /* per-target-table PlannerInfos */
+ List *withCheckOptionLists; /* per-target-table WCO lists */
+ List *returningLists; /* per-target-table RETURNING tlists */
+ List *rowMarks; /* PlanRowMarks (non-locking only) */
+ OnConflictExpr *onconflict; /* ON CONFLICT clause, or NULL */
+ int epqParam; /* ID of Param for EvalPlanQual re-eval */
+} ModifyTablePath;
+
+/*
+ * LimitPath represents applying LIMIT/OFFSET restrictions
+ */
+typedef struct LimitPath
+{
+ Path path;
+ Path *subpath; /* path representing input source */
+ Node *limitOffset; /* OFFSET parameter, or NULL if none */
+ Node *limitCount; /* COUNT parameter, or NULL if none */
+} LimitPath;
+
+
+/*
* Restriction clause info.
*
* We create one of these for each AND sub-clause of a restriction condition
@@ -1615,8 +1851,9 @@ typedef struct PlaceHolderInfo
} PlaceHolderInfo;
/*
- * For each potentially index-optimizable MIN/MAX aggregate function,
- * root->minmax_aggs stores a MinMaxAggInfo describing it.
+ * This struct describes one potentially index-optimizable MIN/MAX aggregate
+ * function. MinMaxAggPath contains a list of these, and if we accept that
+ * path, the list is stored into root->minmax_aggs for use during setrefs.c.
*/
typedef struct MinMaxAggInfo
{
diff --git a/src/include/optimizer/cost.h b/src/include/optimizer/cost.h
index 78c7cae99be..fea2bb77f4d 100644
--- a/src/include/optimizer/cost.h
+++ b/src/include/optimizer/cost.h
@@ -85,7 +85,7 @@ extern void cost_bitmap_or_node(BitmapOrPath *path, PlannerInfo *root);
extern void cost_bitmap_tree_node(Path *path, Cost *cost, Selectivity *selec);
extern void cost_tidscan(Path *path, PlannerInfo *root,
RelOptInfo *baserel, List *tidquals, ParamPathInfo *param_info);
-extern void cost_subqueryscan(Path *path, PlannerInfo *root,
+extern void cost_subqueryscan(SubqueryScanPath *path, PlannerInfo *root,
RelOptInfo *baserel, ParamPathInfo *param_info);
extern void cost_functionscan(Path *path, PlannerInfo *root,
RelOptInfo *baserel, ParamPathInfo *param_info);
@@ -93,7 +93,7 @@ extern void cost_valuesscan(Path *path, PlannerInfo *root,
RelOptInfo *baserel, ParamPathInfo *param_info);
extern void cost_ctescan(Path *path, PlannerInfo *root,
RelOptInfo *baserel, ParamPathInfo *param_info);
-extern void cost_recursive_union(Plan *runion, Plan *nrterm, Plan *rterm);
+extern void cost_recursive_union(Path *runion, Path *nrterm, Path *rterm);
extern void cost_sort(Path *path, PlannerInfo *root,
List *pathkeys, Cost input_cost, double tuples, int width,
Cost comparison_cost, int sort_mem,
@@ -180,8 +180,9 @@ extern void set_subquery_size_estimates(PlannerInfo *root, RelOptInfo *rel);
extern void set_function_size_estimates(PlannerInfo *root, RelOptInfo *rel);
extern void set_values_size_estimates(PlannerInfo *root, RelOptInfo *rel);
extern void set_cte_size_estimates(PlannerInfo *root, RelOptInfo *rel,
- Plan *cteplan);
+ double cte_rows);
extern void set_foreign_size_estimates(PlannerInfo *root, RelOptInfo *rel);
+extern PathTarget *set_pathtarget_cost_width(PlannerInfo *root, PathTarget *target);
/*
* prototypes for clausesel.c
diff --git a/src/include/optimizer/pathnode.h b/src/include/optimizer/pathnode.h
index f479981d37e..37744bf9725 100644
--- a/src/include/optimizer/pathnode.h
+++ b/src/include/optimizer/pathnode.h
@@ -68,13 +68,15 @@ extern MergeAppendPath *create_merge_append_path(PlannerInfo *root,
List *subpaths,
List *pathkeys,
Relids required_outer);
-extern ResultPath *create_result_path(RelOptInfo *rel, List *quals);
+extern ResultPath *create_result_path(RelOptInfo *rel,
+ PathTarget *target, List *quals);
extern MaterialPath *create_material_path(RelOptInfo *rel, Path *subpath);
extern UniquePath *create_unique_path(PlannerInfo *root, RelOptInfo *rel,
Path *subpath, SpecialJoinInfo *sjinfo);
extern GatherPath *create_gather_path(PlannerInfo *root,
RelOptInfo *rel, Path *subpath, Relids required_outer);
-extern Path *create_subqueryscan_path(PlannerInfo *root, RelOptInfo *rel,
+extern SubqueryScanPath *create_subqueryscan_path(PlannerInfo *root,
+ RelOptInfo *rel, Path *subpath,
List *pathkeys, Relids required_outer);
extern Path *create_functionscan_path(PlannerInfo *root, RelOptInfo *rel,
List *pathkeys, Relids required_outer);
@@ -132,6 +134,96 @@ extern HashPath *create_hashjoin_path(PlannerInfo *root,
Relids required_outer,
List *hashclauses);
+extern ProjectionPath *create_projection_path(PlannerInfo *root,
+ RelOptInfo *rel,
+ Path *subpath,
+ PathTarget *target);
+extern Path *apply_projection_to_path(PlannerInfo *root,
+ RelOptInfo *rel,
+ Path *path,
+ PathTarget *target);
+extern SortPath *create_sort_path(PlannerInfo *root,
+ RelOptInfo *rel,
+ Path *subpath,
+ List *pathkeys,
+ double limit_tuples);
+extern GroupPath *create_group_path(PlannerInfo *root,
+ RelOptInfo *rel,
+ Path *subpath,
+ PathTarget *target,
+ List *groupClause,
+ List *qual,
+ double numGroups);
+extern UpperUniquePath *create_upper_unique_path(PlannerInfo *root,
+ RelOptInfo *rel,
+ Path *subpath,
+ int numCols,
+ double numGroups);
+extern AggPath *create_agg_path(PlannerInfo *root,
+ RelOptInfo *rel,
+ Path *subpath,
+ PathTarget *target,
+ AggStrategy aggstrategy,
+ List *groupClause,
+ List *qual,
+ const AggClauseCosts *aggcosts,
+ double numGroups);
+extern GroupingSetsPath *create_groupingsets_path(PlannerInfo *root,
+ RelOptInfo *rel,
+ Path *subpath,
+ PathTarget *target,
+ List *having_qual,
+ AttrNumber *groupColIdx,
+ List *rollup_lists,
+ List *rollup_groupclauses,
+ const AggClauseCosts *agg_costs,
+ double numGroups);
+extern MinMaxAggPath *create_minmaxagg_path(PlannerInfo *root,
+ RelOptInfo *rel,
+ PathTarget *target,
+ List *mmaggregates,
+ List *quals);
+extern WindowAggPath *create_windowagg_path(PlannerInfo *root,
+ RelOptInfo *rel,
+ Path *subpath,
+ PathTarget *target,
+ List *windowFuncs,
+ WindowClause *winclause,
+ List *winpathkeys);
+extern SetOpPath *create_setop_path(PlannerInfo *root,
+ RelOptInfo *rel,
+ Path *subpath,
+ SetOpCmd cmd,
+ SetOpStrategy strategy,
+ List *distinctList,
+ AttrNumber flagColIdx,
+ int firstFlag,
+ double numGroups,
+ double outputRows);
+extern RecursiveUnionPath *create_recursiveunion_path(PlannerInfo *root,
+ RelOptInfo *rel,
+ Path *leftpath,
+ Path *rightpath,
+ PathTarget *target,
+ List *distinctList,
+ int wtParam,
+ double numGroups);
+extern LockRowsPath *create_lockrows_path(PlannerInfo *root, RelOptInfo *rel,
+ Path *subpath, List *rowMarks, int epqParam);
+extern ModifyTablePath *create_modifytable_path(PlannerInfo *root,
+ RelOptInfo *rel,
+ CmdType operation, bool canSetTag,
+ Index nominalRelation,
+ List *resultRelations, List *subpaths,
+ List *subroots,
+ List *withCheckOptionLists, List *returningLists,
+ List *rowMarks, OnConflictExpr *onconflict,
+ int epqParam);
+extern LimitPath *create_limit_path(PlannerInfo *root, RelOptInfo *rel,
+ Path *subpath,
+ Node *limitOffset, Node *limitCount,
+ int64 offset_est, int64 count_est);
+
extern Path *reparameterize_path(PlannerInfo *root, Path *path,
Relids required_outer,
double loop_count);
@@ -155,6 +247,8 @@ extern Relids min_join_parameterization(PlannerInfo *root,
RelOptInfo *outer_rel,
RelOptInfo *inner_rel);
extern RelOptInfo *build_empty_join_rel(PlannerInfo *root);
+extern RelOptInfo *fetch_upper_rel(PlannerInfo *root, UpperRelationKind kind,
+ Relids relids);
extern AppendRelInfo *find_childrel_appendrelinfo(PlannerInfo *root,
RelOptInfo *rel);
extern RelOptInfo *find_childrel_top_parent(PlannerInfo *root, RelOptInfo *rel);
diff --git a/src/include/optimizer/paths.h b/src/include/optimizer/paths.h
index 20474c3e1fe..2fccc3a998a 100644
--- a/src/include/optimizer/paths.h
+++ b/src/include/optimizer/paths.h
@@ -47,6 +47,7 @@ extern PGDLLIMPORT join_search_hook_type join_search_hook;
extern RelOptInfo *make_one_rel(PlannerInfo *root, List *joinlist);
+extern void set_dummy_rel_pathlist(RelOptInfo *rel);
extern RelOptInfo *standard_join_search(PlannerInfo *root, int levels_needed,
List *initial_rels);
@@ -137,10 +138,6 @@ extern void add_child_rel_equivalences(PlannerInfo *root,
AppendRelInfo *appinfo,
RelOptInfo *parent_rel,
RelOptInfo *child_rel);
-extern void mutate_eclass_expressions(PlannerInfo *root,
- Node *(*mutator) (),
- void *context,
- bool include_child_exprs);
extern List *generate_implied_equalities_for_column(PlannerInfo *root,
RelOptInfo *rel,
ec_matches_callback_type callback,
@@ -182,7 +179,8 @@ extern List *build_expression_pathkey(PlannerInfo *root, Expr *expr,
Relids nullable_relids, Oid opno,
Relids rel, bool create_it);
extern List *convert_subquery_pathkeys(PlannerInfo *root, RelOptInfo *rel,
- List *subquery_pathkeys);
+ List *subquery_pathkeys,
+ List *subquery_tlist);
extern List *build_join_pathkeys(PlannerInfo *root,
RelOptInfo *joinrel,
JoinType jointype,
diff --git a/src/include/optimizer/planmain.h b/src/include/optimizer/planmain.h
index eaa642bc57e..cd7338a98c6 100644
--- a/src/include/optimizer/planmain.h
+++ b/src/include/optimizer/planmain.h
@@ -43,60 +43,17 @@ extern RelOptInfo *query_planner(PlannerInfo *root, List *tlist,
* prototypes for plan/planagg.c
*/
extern void preprocess_minmax_aggregates(PlannerInfo *root, List *tlist);
-extern Plan *optimize_minmax_aggregates(PlannerInfo *root, List *tlist,
- const AggClauseCosts *aggcosts, Path *best_path);
/*
* prototypes for plan/createplan.c
*/
extern Plan *create_plan(PlannerInfo *root, Path *best_path);
-extern SubqueryScan *make_subqueryscan(List *qptlist, List *qpqual,
- Index scanrelid, Plan *subplan);
extern ForeignScan *make_foreignscan(List *qptlist, List *qpqual,
Index scanrelid, List *fdw_exprs, List *fdw_private,
List *fdw_scan_tlist, List *fdw_recheck_quals,
Plan *outer_plan);
-extern Append *make_append(List *appendplans, List *tlist);
-extern RecursiveUnion *make_recursive_union(List *tlist,
- Plan *lefttree, Plan *righttree, int wtParam,
- List *distinctList, long numGroups);
-extern Sort *make_sort_from_pathkeys(PlannerInfo *root, Plan *lefttree,
- List *pathkeys, double limit_tuples);
-extern Sort *make_sort_from_sortclauses(PlannerInfo *root, List *sortcls,
- Plan *lefttree);
-extern Sort *make_sort_from_groupcols(PlannerInfo *root, List *groupcls,
- AttrNumber *grpColIdx, Plan *lefttree);
-extern Agg *make_agg(PlannerInfo *root, List *tlist, List *qual,
- AggStrategy aggstrategy, const AggClauseCosts *aggcosts,
- int numGroupCols, AttrNumber *grpColIdx, Oid *grpOperators,
- List *groupingSets, long numGroups, bool combineStates,
- bool finalizeAggs, Plan *lefttree);
-extern WindowAgg *make_windowagg(PlannerInfo *root, List *tlist,
- List *windowFuncs, Index winref,
- int partNumCols, AttrNumber *partColIdx, Oid *partOperators,
- int ordNumCols, AttrNumber *ordColIdx, Oid *ordOperators,
- int frameOptions, Node *startOffset, Node *endOffset,
- Plan *lefttree);
-extern Group *make_group(PlannerInfo *root, List *tlist, List *qual,
- int numGroupCols, AttrNumber *grpColIdx, Oid *grpOperators,
- double numGroups,
- Plan *lefttree);
extern Plan *materialize_finished_plan(Plan *subplan);
-extern Unique *make_unique(Plan *lefttree, List *distinctList);
-extern LockRows *make_lockrows(Plan *lefttree, List *rowMarks, int epqParam);
-extern Limit *make_limit(Plan *lefttree, Node *limitOffset, Node *limitCount,
- int64 offset_est, int64 count_est);
-extern SetOp *make_setop(SetOpCmd cmd, SetOpStrategy strategy, Plan *lefttree,
- List *distinctList, AttrNumber flagColIdx, int firstFlag,
- long numGroups, double outputRows);
-extern Result *make_result(PlannerInfo *root, List *tlist,
- Node *resconstantqual, Plan *subplan);
-extern ModifyTable *make_modifytable(PlannerInfo *root,
- CmdType operation, bool canSetTag,
- Index nominalRelation,
- List *resultRelations, List *subplans,
- List *withCheckOptionLists, List *returningLists,
- List *rowMarks, OnConflictExpr *onconflict, int epqParam);
+extern bool is_projection_capable_path(Path *path);
extern bool is_projection_capable_plan(Plan *plan);
/*
diff --git a/src/include/optimizer/planner.h b/src/include/optimizer/planner.h
index 886acfeac01..3fb7cb58cbd 100644
--- a/src/include/optimizer/planner.h
+++ b/src/include/optimizer/planner.h
@@ -30,19 +30,18 @@ extern PlannedStmt *planner(Query *parse, int cursorOptions,
extern PlannedStmt *standard_planner(Query *parse, int cursorOptions,
ParamListInfo boundParams);
-extern Plan *subquery_planner(PlannerGlobal *glob, Query *parse,
+extern PlannerInfo *subquery_planner(PlannerGlobal *glob, Query *parse,
PlannerInfo *parent_root,
- bool hasRecursion, double tuple_fraction,
- PlannerInfo **subroot);
-
-extern void add_tlist_costs_to_plan(PlannerInfo *root, Plan *plan,
- List *tlist);
+ bool hasRecursion, double tuple_fraction);
extern bool is_dummy_plan(Plan *plan);
extern RowMarkType select_rowmark_type(RangeTblEntry *rte,
LockClauseStrength strength);
+extern Path *get_cheapest_fractional_path(RelOptInfo *rel,
+ double tuple_fraction);
+
extern Expr *expression_planner(Expr *expr);
extern Expr *preprocess_phv_expression(PlannerInfo *root, Expr *expr);
diff --git a/src/include/optimizer/prep.h b/src/include/optimizer/prep.h
index cebd8b6b0f9..fb35b689bb9 100644
--- a/src/include/optimizer/prep.h
+++ b/src/include/optimizer/prep.h
@@ -53,8 +53,7 @@ extern PlanRowMark *get_plan_rowmark(List *rowmarks, Index rtindex);
/*
* prototypes for prepunion.c
*/
-extern Plan *plan_set_operations(PlannerInfo *root, double tuple_fraction,
- List **sortClauses);
+extern RelOptInfo *plan_set_operations(PlannerInfo *root);
extern void expand_inherited_tables(PlannerInfo *root);
diff --git a/src/include/optimizer/subselect.h b/src/include/optimizer/subselect.h
index 4c652fa9bbf..f100d02940b 100644
--- a/src/include/optimizer/subselect.h
+++ b/src/include/optimizer/subselect.h
@@ -26,11 +26,15 @@ extern JoinExpr *convert_EXISTS_sublink_to_join(PlannerInfo *root,
extern Node *SS_replace_correlation_vars(PlannerInfo *root, Node *expr);
extern Node *SS_process_sublinks(PlannerInfo *root, Node *expr, bool isQual);
extern void SS_identify_outer_params(PlannerInfo *root);
+extern void SS_charge_for_initplans(PlannerInfo *root, RelOptInfo *final_rel);
extern void SS_attach_initplans(PlannerInfo *root, Plan *plan);
extern void SS_finalize_plan(PlannerInfo *root, Plan *plan);
-extern Param *SS_make_initplan_from_plan(PlannerInfo *root,
+extern Param *SS_make_initplan_output_param(PlannerInfo *root,
+ Oid resulttype, int32 resulttypmod,
+ Oid resultcollation);
+extern void SS_make_initplan_from_plan(PlannerInfo *root,
PlannerInfo *subroot, Plan *plan,
- Oid resulttype, int32 resulttypmod, Oid resultcollation);
+ Param *prm);
extern Param *assign_nestloop_param_var(PlannerInfo *root, Var *var);
extern Param *assign_nestloop_param_placeholdervar(PlannerInfo *root,
PlaceHolderVar *phv);
diff --git a/src/include/optimizer/tlist.h b/src/include/optimizer/tlist.h
index 25e2581c7a2..fc6bc088b17 100644
--- a/src/include/optimizer/tlist.h
+++ b/src/include/optimizer/tlist.h
@@ -19,7 +19,6 @@
extern TargetEntry *tlist_member(Node *node, List *targetlist);
extern TargetEntry *tlist_member_ignore_relabel(Node *node, List *targetlist);
-extern TargetEntry *tlist_member_match_var(Var *var, List *targetlist);
extern List *flatten_tlist(List *tlist, PVCAggregateBehavior aggbehavior,
PVCPlaceHolderBehavior phbehavior);
@@ -34,6 +33,8 @@ extern bool tlist_same_exprs(List *tlist1, List *tlist2);
extern bool tlist_same_datatypes(List *tlist, List *colTypes, bool junkOK);
extern bool tlist_same_collations(List *tlist, List *colCollations, bool junkOK);
+extern void apply_tlist_labeling(List *dest_tlist, List *src_tlist);
+
extern TargetEntry *get_sortgroupref_tle(Index sortref,
List *targetList);
extern TargetEntry *get_sortgroupclause_tle(SortGroupClause *sgClause,
@@ -51,4 +52,12 @@ extern AttrNumber *extract_grouping_cols(List *groupClause, List *tlist);
extern bool grouping_is_sortable(List *groupClause);
extern bool grouping_is_hashable(List *groupClause);
+extern PathTarget *make_pathtarget_from_tlist(List *tlist);
+extern List *make_tlist_from_pathtarget(PathTarget *target);
+extern void apply_pathtarget_labeling_to_tlist(List *tlist, PathTarget *target);
+
+/* Convenience macro to get a PathTarget with valid cost/width fields */
+#define create_pathtarget(root, tlist) \
+ set_pathtarget_cost_width(root, make_pathtarget_from_tlist(tlist))
+
#endif /* TLIST_H */