summaryrefslogtreecommitdiff
path: root/src/include/executor/execPartition.h
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2018-08-01 19:42:46 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2018-08-01 19:42:52 -0400
commit1c2cb2744bf3d8ad751cd5cf3b347f10f48492b3 (patch)
tree78cbab7db4dacbac9f47b4c78974ba3c8f6c9184 /src/include/executor/execPartition.h
parentc40489e449ea08e154cd62fa055785873f7bdac8 (diff)
Fix run-time partition pruning for appends with multiple source rels.
The previous coding here supposed that if run-time partitioning applied to a particular Append/MergeAppend plan, then all child plans of that node must be members of a single partitioning hierarchy. This is totally wrong, since an Append could be formed from a UNION ALL: we could have multiple hierarchies sharing the same Append, or child plans that aren't part of any hierarchy. To fix, restructure the related plan-time and execution-time data structures so that we can have a separate list or array for each partitioning hierarchy. Also track subplans that are not part of any hierarchy, and make sure they don't get pruned. Per reports from Phil Florent and others. Back-patch to v11, since the bug originated there. David Rowley, with a lot of cosmetic adjustments by me; thanks also to Amit Langote for review. Discussion: https://postgr.es/m/HE1PR03MB17068BB27404C90B5B788BCABA7B0@HE1PR03MB1706.eurprd03.prod.outlook.com
Diffstat (limited to 'src/include/executor/execPartition.h')
-rw-r--r--src/include/executor/execPartition.h68
1 files changed, 41 insertions, 27 deletions
diff --git a/src/include/executor/execPartition.h b/src/include/executor/execPartition.h
index e9e6d380ec8..f6cd842cc9b 100644
--- a/src/include/executor/execPartition.h
+++ b/src/include/executor/execPartition.h
@@ -112,15 +112,14 @@ typedef struct PartitionTupleRouting
TupleTableSlot *root_tuple_slot;
} PartitionTupleRouting;
-/*-----------------------
- * PartitionPruningData - Per-partitioned-table data for run-time pruning
+/*
+ * PartitionedRelPruningData - Per-partitioned-table data for run-time pruning
* of partitions. For a multilevel partitioned table, we have one of these
- * for the topmost partition plus one for each non-leaf child partition,
- * ordered such that parents appear before their children.
+ * for the topmost partition plus one for each non-leaf child partition.
*
* subplan_map[] and subpart_map[] have the same definitions as in
- * PartitionPruneInfo (see plannodes.h); though note that here,
- * subpart_map contains indexes into PartitionPruneState.partprunedata[].
+ * PartitionedRelPruneInfo (see plannodes.h); though note that here,
+ * subpart_map contains indexes into PartitionPruningData.partrelprunedata[].
*
* subplan_map Subplan index by partition index, or -1.
* subpart_map Subpart index by partition index, or -1.
@@ -134,9 +133,8 @@ typedef struct PartitionTupleRouting
* executor startup (for this partitioning level).
* do_exec_prune true if pruning should be performed during
* executor run (for this partitioning level).
- *-----------------------
*/
-typedef struct PartitionPruningData
+typedef struct PartitionedRelPruningData
{
int *subplan_map;
int *subpart_map;
@@ -145,43 +143,59 @@ typedef struct PartitionPruningData
List *pruning_steps;
bool do_initial_prune;
bool do_exec_prune;
+} PartitionedRelPruningData;
+
+/*
+ * PartitionPruningData - Holds all the run-time pruning information for
+ * a single partitioning hierarchy containing one or more partitions.
+ * partrelprunedata[] is an array ordered such that parents appear before
+ * their children; in particular, the first entry is the topmost partition,
+ * which was actually named in the SQL query.
+ */
+typedef struct PartitionPruningData
+{
+ int num_partrelprunedata; /* number of array entries */
+ PartitionedRelPruningData partrelprunedata[FLEXIBLE_ARRAY_MEMBER];
} PartitionPruningData;
-/*-----------------------
+/*
* PartitionPruneState - State object required for plan nodes to perform
* run-time partition pruning.
*
* This struct can be attached to plan types which support arbitrary Lists of
- * subplans containing partitions to allow subplans to be eliminated due to
+ * subplans containing partitions, to allow subplans to be eliminated due to
* the clauses being unable to match to any tuple that the subplan could
- * possibly produce. Note that we currently support only one partitioned
- * table per parent plan node, hence partprunedata[] need describe only one
- * partitioning hierarchy.
+ * possibly produce.
*
- * partprunedata Array of PartitionPruningData for the plan's
- * partitioned relation, ordered such that parent tables
- * appear before children (hence, topmost table is first).
- * num_partprunedata Number of items in 'partprunedata' array.
- * do_initial_prune true if pruning should be performed during executor
- * startup (at any hierarchy level).
- * do_exec_prune true if pruning should be performed during
- * executor run (at any hierarchy level).
* execparamids Contains paramids of PARAM_EXEC Params found within
* any of the partprunedata structs. Pruning must be
* done again each time the value of one of these
* parameters changes.
+ * other_subplans Contains indexes of subplans that don't belong to any
+ * "partprunedata", e.g UNION ALL children that are not
+ * partitioned tables, or a partitioned table that the
+ * planner deemed run-time pruning to be useless for.
+ * These must not be pruned.
* prune_context A short-lived memory context in which to execute the
* partition pruning functions.
- *-----------------------
+ * do_initial_prune true if pruning should be performed during executor
+ * startup (at any hierarchy level).
+ * do_exec_prune true if pruning should be performed during
+ * executor run (at any hierarchy level).
+ * num_partprunedata Number of items in "partprunedata" array.
+ * partprunedata Array of PartitionPruningData pointers for the plan's
+ * partitioned relation(s), one for each partitioning
+ * hierarchy that requires run-time pruning.
*/
typedef struct PartitionPruneState
{
- PartitionPruningData *partprunedata;
- int num_partprunedata;
- bool do_initial_prune;
- bool do_exec_prune;
Bitmapset *execparamids;
+ Bitmapset *other_subplans;
MemoryContext prune_context;
+ bool do_initial_prune;
+ bool do_exec_prune;
+ int num_partprunedata;
+ PartitionPruningData *partprunedata[FLEXIBLE_ARRAY_MEMBER];
} PartitionPruneState;
extern PartitionTupleRouting *ExecSetupPartitionTupleRouting(ModifyTableState *mtstate,
@@ -210,7 +224,7 @@ extern HeapTuple ConvertPartitionTupleSlot(TupleConversionMap *map,
extern void ExecCleanupTupleRouting(ModifyTableState *mtstate,
PartitionTupleRouting *proute);
extern PartitionPruneState *ExecCreatePartitionPruneState(PlanState *planstate,
- List *partitionpruneinfo);
+ PartitionPruneInfo *partitionpruneinfo);
extern void ExecDestroyPartitionPruneState(PartitionPruneState *prunestate);
extern Bitmapset *ExecFindMatchingSubPlans(PartitionPruneState *prunestate);
extern Bitmapset *ExecFindInitialMatchingSubPlans(PartitionPruneState *prunestate,