mirror of
https://git.postgresql.org/git/postgresql.git
synced 2026-02-17 20:07:00 +08:00
Move PartitionPruneInfo out of plan nodes into PlannedStmt
This moves PartitionPruneInfo from plan nodes to PlannedStmt, simplifying traversal by centralizing all PartitionPruneInfo structures in a single list in it, which holds all instances for the main query and its subqueries. Instead of plan nodes (Append or MergeAppend) storing PartitionPruneInfo pointers, they now reference an index in this list. A bitmapset field is added to PartitionPruneInfo to store the RT indexes corresponding to the apprelids field in Append or MergeAppend. This allows execution pruning logic to verify that it operates on the correct plan node, mainly to facilitate debugging. Duplicated code in set_append_references() and set_mergeappend_references() is refactored into a new function, register_pruneinfo(). This updates RT indexes by applying rtoffet and adds PartitionPruneInfo to the global list in PlannerGlobal. By allowing pruning to be performed without traversing the plan tree, this change lays the groundwork for runtime initial pruning to occur independently of plan tree initialization. Reviewed-by: Alvaro Herrera <alvherre@alvh.no-ip.org> (earlier version) Reviewed-by: Robert Haas <robertmhaas@gmail.com> Reviewed-by: Tomas Vondra <tomas@vondra.me> Discussion: https://postgr.es/m/CA+HiwqFGkMSge6TgC9KQzde0ohpAycLQuV7ooitEEpbKB0O_mg@mail.gmail.com
This commit is contained in:
@ -123,7 +123,8 @@ typedef struct PartitionPruneState
|
||||
|
||||
extern PartitionPruneState *ExecInitPartitionPruning(PlanState *planstate,
|
||||
int n_total_subplans,
|
||||
PartitionPruneInfo *pruneinfo,
|
||||
int part_prune_index,
|
||||
Bitmapset *relids,
|
||||
Bitmapset **initially_valid_subplans);
|
||||
extern Bitmapset *ExecFindMatchingSubPlans(PartitionPruneState *prunestate,
|
||||
bool initial_prune);
|
||||
|
||||
@ -655,6 +655,7 @@ typedef struct EState
|
||||
* ExecRowMarks, or NULL if none */
|
||||
List *es_rteperminfos; /* List of RTEPermissionInfo */
|
||||
PlannedStmt *es_plannedstmt; /* link to top of plan tree */
|
||||
List *es_part_prune_infos; /* List of PartitionPruneInfo */
|
||||
const char *es_sourceText; /* Source text from QueryDesc */
|
||||
|
||||
JunkFilter *es_junkFilter; /* top-level junk filter, if any */
|
||||
|
||||
@ -128,6 +128,9 @@ typedef struct PlannerGlobal
|
||||
/* "flat" list of AppendRelInfos */
|
||||
List *appendRelations;
|
||||
|
||||
/* "flat" list of PartitionPruneInfos */
|
||||
List *partPruneInfos;
|
||||
|
||||
/* OIDs of relations the plan depends on */
|
||||
List *relationOids;
|
||||
|
||||
@ -559,6 +562,9 @@ struct PlannerInfo
|
||||
|
||||
/* Does this query modify any partition key columns? */
|
||||
bool partColsUpdated;
|
||||
|
||||
/* PartitionPruneInfos added in this query's plan. */
|
||||
List *partPruneInfos;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@ -69,6 +69,9 @@ typedef struct PlannedStmt
|
||||
|
||||
struct Plan *planTree; /* tree of Plan nodes */
|
||||
|
||||
List *partPruneInfos; /* List of PartitionPruneInfo contained in the
|
||||
* plan */
|
||||
|
||||
List *rtable; /* list of RangeTblEntry nodes */
|
||||
|
||||
List *permInfos; /* list of RTEPermissionInfo nodes for rtable
|
||||
@ -278,8 +281,8 @@ typedef struct Append
|
||||
*/
|
||||
int first_partial_plan;
|
||||
|
||||
/* Info for run-time subplan pruning; NULL if we're not doing that */
|
||||
struct PartitionPruneInfo *part_prune_info;
|
||||
/* Index to PlannerInfo.partPruneInfos or -1 if no run-time pruning */
|
||||
int part_prune_index;
|
||||
} Append;
|
||||
|
||||
/* ----------------
|
||||
@ -313,8 +316,8 @@ typedef struct MergeAppend
|
||||
/* NULLS FIRST/LAST directions */
|
||||
bool *nullsFirst pg_node_attr(array_size(numCols));
|
||||
|
||||
/* Info for run-time subplan pruning; NULL if we're not doing that */
|
||||
struct PartitionPruneInfo *part_prune_info;
|
||||
/* Index to PlannerInfo.partPruneInfos or -1 if no run-time pruning */
|
||||
int part_prune_index;
|
||||
} MergeAppend;
|
||||
|
||||
/* ----------------
|
||||
@ -1413,6 +1416,10 @@ typedef struct PlanRowMark
|
||||
* Then, since an Append-type node could have multiple partitioning
|
||||
* hierarchies among its children, we have an unordered List of those Lists.
|
||||
*
|
||||
* relids RelOptInfo.relids of the parent plan node (e.g. Append
|
||||
* or MergeAppend) to which this PartitionPruneInfo node
|
||||
* belongs. The pruning logic ensures that this matches
|
||||
* the parent plan node's apprelids.
|
||||
* prune_infos List of Lists containing PartitionedRelPruneInfo nodes,
|
||||
* one sublist per run-time-prunable partition hierarchy
|
||||
* appearing in the parent plan node's subplans.
|
||||
@ -1425,6 +1432,7 @@ typedef struct PartitionPruneInfo
|
||||
pg_node_attr(no_equal, no_query_jumble)
|
||||
|
||||
NodeTag type;
|
||||
Bitmapset *relids;
|
||||
List *prune_infos;
|
||||
Bitmapset *other_subplans;
|
||||
} PartitionPruneInfo;
|
||||
|
||||
@ -70,10 +70,10 @@ typedef struct PartitionPruneContext
|
||||
#define PruneCxtStateIdx(partnatts, step_id, keyno) \
|
||||
((partnatts) * (step_id) + (keyno))
|
||||
|
||||
extern PartitionPruneInfo *make_partition_pruneinfo(struct PlannerInfo *root,
|
||||
struct RelOptInfo *parentrel,
|
||||
List *subpaths,
|
||||
List *prunequal);
|
||||
extern int make_partition_pruneinfo(struct PlannerInfo *root,
|
||||
struct RelOptInfo *parentrel,
|
||||
List *subpaths,
|
||||
List *prunequal);
|
||||
extern Bitmapset *prune_append_rel_partitions(struct RelOptInfo *rel);
|
||||
extern Bitmapset *get_matching_partitions(PartitionPruneContext *context,
|
||||
List *pruning_steps);
|
||||
|
||||
Reference in New Issue
Block a user