aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/commands/copy.c4
-rw-r--r--src/backend/executor/execMain.c4
-rw-r--r--src/backend/executor/execPartition.c34
-rw-r--r--src/backend/executor/nodeModifyTable.c21
-rw-r--r--src/backend/replication/logical/worker.c11
-rw-r--r--src/include/executor/execPartition.h21
-rw-r--r--src/include/nodes/execnodes.h15
7 files changed, 45 insertions, 65 deletions
diff --git a/src/backend/commands/copy.c b/src/backend/commands/copy.c
index b4ccd35ec18..36ddcdccdb8 100644
--- a/src/backend/commands/copy.c
+++ b/src/backend/commands/copy.c
@@ -3119,7 +3119,7 @@ CopyFrom(CopyState cstate)
* We might need to convert from the root rowtype to the partition
* rowtype.
*/
- map = resultRelInfo->ri_PartitionInfo->pi_RootToPartitionMap;
+ map = resultRelInfo->ri_RootToPartitionMap;
if (insertMethod == CIM_SINGLE || !leafpart_use_multi_insert)
{
/* non batch insert */
@@ -3127,7 +3127,7 @@ CopyFrom(CopyState cstate)
{
TupleTableSlot *new_slot;
- new_slot = resultRelInfo->ri_PartitionInfo->pi_PartitionTupleSlot;
+ new_slot = resultRelInfo->ri_PartitionTupleSlot;
myslot = execute_attr_map_slot(map->attrMap, myslot, new_slot);
}
}
diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c
index fcdd4b35674..aea04794487 100644
--- a/src/backend/executor/execMain.c
+++ b/src/backend/executor/execMain.c
@@ -1243,7 +1243,9 @@ InitResultRelInfo(ResultRelInfo *resultRelInfo,
resultRelInfo->ri_TrigOldSlot = NULL;
resultRelInfo->ri_TrigNewSlot = NULL;
resultRelInfo->ri_PartitionRoot = partition_root;
- resultRelInfo->ri_PartitionInfo = NULL; /* may be set later */
+ resultRelInfo->ri_RootToPartitionMap = NULL; /* set by
+ * ExecInitRoutingInfo */
+ resultRelInfo->ri_PartitionTupleSlot = NULL; /* ditto */
resultRelInfo->ri_ChildToRootMap = NULL;
resultRelInfo->ri_CopyMultiInsertBuffer = NULL;
}
diff --git a/src/backend/executor/execPartition.c b/src/backend/executor/execPartition.c
index 08f91e59a7a..86594bd0565 100644
--- a/src/backend/executor/execPartition.c
+++ b/src/backend/executor/execPartition.c
@@ -261,7 +261,7 @@ ExecSetupPartitionTupleRouting(EState *estate, ModifyTableState *mtstate,
* If the partition's ResultRelInfo does not yet exist in 'proute' then we set
* one up or reuse one from mtstate's resultRelInfo array. When reusing a
* ResultRelInfo from the mtstate we verify that the relation is a valid
- * target for INSERTs and then set up a PartitionRoutingInfo for it.
+ * target for INSERTs and initialize tuple routing information.
*
* rootResultRelInfo is the relation named in the query.
*
@@ -307,6 +307,7 @@ ExecFindPartition(ModifyTableState *mtstate,
while (dispatch != NULL)
{
int partidx = -1;
+ bool is_leaf;
CHECK_FOR_INTERRUPTS();
@@ -346,8 +347,10 @@ ExecFindPartition(ModifyTableState *mtstate,
errtable(rel)));
}
- if (partdesc->is_leaf[partidx])
+ is_leaf = partdesc->is_leaf[partidx];
+ if (is_leaf)
{
+
/*
* We've reached the leaf -- hurray, we're done. Look to see if
* we've already got a ResultRelInfo for this partition.
@@ -382,7 +385,10 @@ ExecFindPartition(ModifyTableState *mtstate,
/* Verify this ResultRelInfo allows INSERTs */
CheckValidResultRel(rri, CMD_INSERT);
- /* Set up the PartitionRoutingInfo for it */
+ /*
+ * Initialize information needed to insert this and
+ * subsequent tuples routed to this partition.
+ */
ExecInitRoutingInfo(mtstate, estate, proute, dispatch,
rri, partidx);
}
@@ -464,8 +470,6 @@ ExecFindPartition(ModifyTableState *mtstate,
*/
if (partidx == partdesc->boundinfo->default_index)
{
- PartitionRoutingInfo *partrouteinfo = rri->ri_PartitionInfo;
-
/*
* The tuple must match the partition's layout for the constraint
* expression to be evaluated successfully. If the partition is
@@ -478,13 +482,13 @@ ExecFindPartition(ModifyTableState *mtstate,
* So if we have to convert, do it from the root slot; if not, use
* the root slot as-is.
*/
- if (partrouteinfo)
+ if (is_leaf)
{
- TupleConversionMap *map = partrouteinfo->pi_RootToPartitionMap;
+ TupleConversionMap *map = rri->ri_RootToPartitionMap;
if (map)
slot = execute_attr_map_slot(map->attrMap, rootslot,
- partrouteinfo->pi_PartitionTupleSlot);
+ rri->ri_PartitionTupleSlot);
else
slot = rootslot;
}
@@ -788,7 +792,7 @@ ExecInitPartitionInfo(ModifyTableState *mtstate, EState *estate,
{
TupleConversionMap *map;
- map = leaf_part_rri->ri_PartitionInfo->pi_RootToPartitionMap;
+ map = leaf_part_rri->ri_RootToPartitionMap;
Assert(node->onConflictSet != NIL);
Assert(rootResultRelInfo->ri_onConflict != NULL);
@@ -949,18 +953,15 @@ ExecInitRoutingInfo(ModifyTableState *mtstate,
int partidx)
{
MemoryContext oldcxt;
- PartitionRoutingInfo *partrouteinfo;
int rri_index;
oldcxt = MemoryContextSwitchTo(proute->memcxt);
- partrouteinfo = palloc(sizeof(PartitionRoutingInfo));
-
/*
* Set up a tuple conversion map to convert a tuple routed to the
* partition from the parent's type to the partition's.
*/
- partrouteinfo->pi_RootToPartitionMap =
+ partRelInfo->ri_RootToPartitionMap =
convert_tuples_by_name(RelationGetDescr(partRelInfo->ri_PartitionRoot),
RelationGetDescr(partRelInfo->ri_RelationDesc));
@@ -970,7 +971,7 @@ ExecInitRoutingInfo(ModifyTableState *mtstate,
* for various operations that are applied to tuples after routing, such
* as checking constraints.
*/
- if (partrouteinfo->pi_RootToPartitionMap != NULL)
+ if (partRelInfo->ri_RootToPartitionMap != NULL)
{
Relation partrel = partRelInfo->ri_RelationDesc;
@@ -979,11 +980,11 @@ ExecInitRoutingInfo(ModifyTableState *mtstate,
* partition's TupleDesc; TupleDesc reference will be released at the
* end of the command.
*/
- partrouteinfo->pi_PartitionTupleSlot =
+ partRelInfo->ri_PartitionTupleSlot =
table_slot_create(partrel, &estate->es_tupleTable);
}
else
- partrouteinfo->pi_PartitionTupleSlot = NULL;
+ partRelInfo->ri_PartitionTupleSlot = NULL;
/*
* If the partition is a foreign table, let the FDW init itself for
@@ -993,7 +994,6 @@ ExecInitRoutingInfo(ModifyTableState *mtstate,
partRelInfo->ri_FdwRoutine->BeginForeignInsert != NULL)
partRelInfo->ri_FdwRoutine->BeginForeignInsert(mtstate, partRelInfo);
- partRelInfo->ri_PartitionInfo = partrouteinfo;
partRelInfo->ri_CopyMultiInsertBuffer = NULL;
/*
diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c
index 5f85fd7cd88..a33423c896e 100644
--- a/src/backend/executor/nodeModifyTable.c
+++ b/src/backend/executor/nodeModifyTable.c
@@ -1172,8 +1172,8 @@ ExecCrossPartitionUpdate(ModifyTableState *mtstate,
planSlot, estate, canSetTag);
/*
- * Reset the transition state that may possibly have been written
- * by INSERT.
+ * Reset the transition state that may possibly have been written by
+ * INSERT.
*/
if (mtstate->mt_transition_capture)
mtstate->mt_transition_capture->tcs_original_insert_tuple = NULL;
@@ -1874,7 +1874,6 @@ ExecPrepareTupleRouting(ModifyTableState *mtstate,
ResultRelInfo **partRelInfo)
{
ResultRelInfo *partrel;
- PartitionRoutingInfo *partrouteinfo;
TupleConversionMap *map;
/*
@@ -1885,8 +1884,6 @@ ExecPrepareTupleRouting(ModifyTableState *mtstate,
* UPDATE to another partition becomes a DELETE+INSERT.
*/
partrel = ExecFindPartition(mtstate, targetRelInfo, proute, slot, estate);
- partrouteinfo = partrel->ri_PartitionInfo;
- Assert(partrouteinfo != NULL);
/*
* If we're capturing transition tuples, we might need to convert from the
@@ -1909,10 +1906,10 @@ ExecPrepareTupleRouting(ModifyTableState *mtstate,
/*
* Convert the tuple, if necessary.
*/
- map = partrouteinfo->pi_RootToPartitionMap;
+ map = partrel->ri_RootToPartitionMap;
if (map != NULL)
{
- TupleTableSlot *new_slot = partrouteinfo->pi_PartitionTupleSlot;
+ TupleTableSlot *new_slot = partrel->ri_PartitionTupleSlot;
slot = execute_attr_map_slot(map->attrMap, slot, new_slot);
}
@@ -2327,8 +2324,8 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags)
* to the format of the table mentioned in the query (root relation).
* It's needed for update tuple routing, because the routing starts
* from the root relation. It's also needed for capturing transition
- * tuples, because the transition tuple store can only store tuples
- * in the root table format.
+ * tuples, because the transition tuple store can only store tuples in
+ * the root table format.
*
* For INSERT, the map is only initialized for a given partition when
* the partition itself is first initialized by ExecFindPartition().
@@ -2363,9 +2360,9 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags)
ExecSetupPartitionTupleRouting(estate, mtstate, rel);
/*
- * For update row movement we'll need a dedicated slot to store the
- * tuples that have been converted from partition format to the root
- * table format.
+ * For update row movement we'll need a dedicated slot to store the tuples
+ * that have been converted from partition format to the root table
+ * format.
*/
if (update_tuple_routing_needed)
mtstate->mt_root_tuple_slot = table_slot_create(rel, NULL);
diff --git a/src/backend/replication/logical/worker.c b/src/backend/replication/logical/worker.c
index b8e297c5d34..3a5b733ee38 100644
--- a/src/backend/replication/logical/worker.c
+++ b/src/backend/replication/logical/worker.c
@@ -1572,7 +1572,6 @@ apply_handle_tuple_routing(ResultRelInfo *relinfo,
ResultRelInfo *partrelinfo;
Relation partrel;
TupleTableSlot *remoteslot_part;
- PartitionRoutingInfo *partinfo;
TupleConversionMap *map;
MemoryContext oldctx;
@@ -1599,11 +1598,10 @@ apply_handle_tuple_routing(ResultRelInfo *relinfo,
* partition's rowtype. Convert if needed or just copy, using a dedicated
* slot to store the tuple in any case.
*/
- partinfo = partrelinfo->ri_PartitionInfo;
- remoteslot_part = partinfo->pi_PartitionTupleSlot;
+ remoteslot_part = partrelinfo->ri_PartitionTupleSlot;
if (remoteslot_part == NULL)
remoteslot_part = table_slot_create(partrel, &estate->es_tupleTable);
- map = partinfo->pi_RootToPartitionMap;
+ map = partrelinfo->ri_RootToPartitionMap;
if (map != NULL)
remoteslot_part = execute_attr_map_slot(map->attrMap, remoteslot,
remoteslot_part);
@@ -1748,12 +1746,11 @@ apply_handle_tuple_routing(ResultRelInfo *relinfo,
*/
oldctx = MemoryContextSwitchTo(GetPerTupleMemoryContext(estate));
partrel = partrelinfo_new->ri_RelationDesc;
- partinfo = partrelinfo_new->ri_PartitionInfo;
- remoteslot_part = partinfo->pi_PartitionTupleSlot;
+ remoteslot_part = partrelinfo_new->ri_PartitionTupleSlot;
if (remoteslot_part == NULL)
remoteslot_part = table_slot_create(partrel,
&estate->es_tupleTable);
- map = partinfo->pi_RootToPartitionMap;
+ map = partrelinfo_new->ri_RootToPartitionMap;
if (map != NULL)
{
remoteslot_part = execute_attr_map_slot(map->attrMap,
diff --git a/src/include/executor/execPartition.h b/src/include/executor/execPartition.h
index 74c39911b2a..473c4cd84fc 100644
--- a/src/include/executor/execPartition.h
+++ b/src/include/executor/execPartition.h
@@ -23,27 +23,6 @@ typedef struct PartitionDispatchData *PartitionDispatch;
typedef struct PartitionTupleRouting PartitionTupleRouting;
/*
- * PartitionRoutingInfo
- *
- * Additional result relation information specific to routing tuples to a
- * table partition.
- */
-typedef struct PartitionRoutingInfo
-{
- /*
- * Map for converting tuples in root partitioned table format into
- * partition format, or NULL if no conversion is required.
- */
- TupleConversionMap *pi_RootToPartitionMap;
-
- /*
- * Slot to store tuples in partition format, or NULL when no translation
- * is required between root and partition.
- */
- TupleTableSlot *pi_PartitionTupleSlot;
-} PartitionRoutingInfo;
-
-/*
* 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.
diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h
index 46789cb0070..6c0a7d68d61 100644
--- a/src/include/nodes/execnodes.h
+++ b/src/include/nodes/execnodes.h
@@ -33,7 +33,6 @@
#include "utils/tuplestore.h"
struct PlanState; /* forward references in this file */
-struct PartitionRoutingInfo;
struct ParallelHashJoinState;
struct ExecRowMark;
struct ExprState;
@@ -480,11 +479,17 @@ typedef struct ResultRelInfo
/* partition check expression state (NULL if not set up yet) */
ExprState *ri_PartitionCheckExpr;
- /* relation descriptor for partitioned table's root, if any */
+ /*
+ * Information needed by tuple routing target relations
+ *
+ * PartitionRoot gives the target relation mentioned in the query.
+ * RootToPartitionMap and PartitionTupleSlot, initialized by
+ * ExecInitRoutingInfo, are non-NULL if partition has a different tuple
+ * format than the root table.
+ */
Relation ri_PartitionRoot;
-
- /* info for partition tuple routing (NULL if not set up yet) */
- struct PartitionRoutingInfo *ri_PartitionInfo;
+ TupleConversionMap *ri_RootToPartitionMap;
+ TupleTableSlot *ri_PartitionTupleSlot;
/*
* Map to convert child result relation tuples to the format of the table