diff options
Diffstat (limited to 'src/include')
-rw-r--r-- | src/include/nodes/nodes.h | 54 | ||||
-rw-r--r-- | src/include/nodes/plannodes.h | 32 | ||||
-rw-r--r-- | src/include/nodes/relation.h | 295 | ||||
-rw-r--r-- | src/include/optimizer/cost.h | 7 | ||||
-rw-r--r-- | src/include/optimizer/pathnode.h | 98 | ||||
-rw-r--r-- | src/include/optimizer/paths.h | 8 | ||||
-rw-r--r-- | src/include/optimizer/planmain.h | 45 | ||||
-rw-r--r-- | src/include/optimizer/planner.h | 11 | ||||
-rw-r--r-- | src/include/optimizer/prep.h | 3 | ||||
-rw-r--r-- | src/include/optimizer/subselect.h | 8 | ||||
-rw-r--r-- | src/include/optimizer/tlist.h | 11 |
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 */ |