aboutsummaryrefslogtreecommitdiff
path: root/src/backend/commands/copy.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/commands/copy.c')
-rw-r--r--src/backend/commands/copy.c86
1 files changed, 24 insertions, 62 deletions
diff --git a/src/backend/commands/copy.c b/src/backend/commands/copy.c
index e62e3d8fba2..6588ebd6dc0 100644
--- a/src/backend/commands/copy.c
+++ b/src/backend/commands/copy.c
@@ -2316,6 +2316,7 @@ CopyFrom(CopyState cstate)
bool *nulls;
ResultRelInfo *resultRelInfo;
ResultRelInfo *target_resultRelInfo;
+ ResultRelInfo *prevResultRelInfo = NULL;
EState *estate = CreateExecutorState(); /* for ExecConstraints() */
ModifyTableState *mtstate;
ExprContext *econtext;
@@ -2331,7 +2332,6 @@ CopyFrom(CopyState cstate)
CopyInsertMethod insertMethod;
uint64 processed = 0;
int nBufferedTuples = 0;
- int prev_leaf_part_index = -1;
bool has_before_insert_row_trig;
bool has_instead_insert_row_trig;
bool leafpart_use_multi_insert = false;
@@ -2515,8 +2515,12 @@ CopyFrom(CopyState cstate)
/*
* If there are any triggers with transition tables on the named relation,
* we need to be prepared to capture transition tuples.
+ *
+ * Because partition tuple routing would like to know about whether
+ * transition capture is active, we also set it in mtstate, which is
+ * passed to ExecFindPartition() below.
*/
- cstate->transition_capture =
+ cstate->transition_capture = mtstate->mt_transition_capture =
MakeTransitionCaptureState(cstate->rel->trigdesc,
RelationGetRelid(cstate->rel),
CMD_INSERT);
@@ -2526,19 +2530,8 @@ CopyFrom(CopyState cstate)
* CopyFrom tuple routing.
*/
if (cstate->rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
- {
proute = ExecSetupPartitionTupleRouting(NULL, cstate->rel);
- /*
- * If we are capturing transition tuples, they may need to be
- * converted from partition format back to partitioned table format
- * (this is only ever necessary if a BEFORE trigger modifies the
- * tuple).
- */
- if (cstate->transition_capture != NULL)
- ExecSetupChildParentMapForLeaf(proute);
- }
-
/*
* It's more efficient to prepare a bunch of tuples for insertion, and
* insert them in one heap_multi_insert() call, than call heap_insert()
@@ -2694,25 +2687,17 @@ CopyFrom(CopyState cstate)
/* Determine the partition to heap_insert the tuple into */
if (proute)
{
- int leaf_part_index;
TupleConversionMap *map;
/*
- * Away we go ... If we end up not finding a partition after all,
- * ExecFindPartition() does not return and errors out instead.
- * Otherwise, the returned value is to be used as an index into
- * arrays mt_partitions[] and mt_partition_tupconv_maps[] that
- * will get us the ResultRelInfo and TupleConversionMap for the
- * partition, respectively.
+ * Attempt to find a partition suitable for this tuple.
+ * ExecFindPartition() will raise an error if none can be found or
+ * if the found partition is not suitable for INSERTs.
*/
- leaf_part_index = ExecFindPartition(target_resultRelInfo,
- proute->partition_dispatch_info,
- slot,
- estate);
- Assert(leaf_part_index >= 0 &&
- leaf_part_index < proute->num_partitions);
-
- if (prev_leaf_part_index != leaf_part_index)
+ resultRelInfo = ExecFindPartition(mtstate, target_resultRelInfo,
+ proute, slot, estate);
+
+ if (prevResultRelInfo != resultRelInfo)
{
/* Check if we can multi-insert into this partition */
if (insertMethod == CIM_MULTI_CONDITIONAL)
@@ -2725,12 +2710,9 @@ CopyFrom(CopyState cstate)
if (nBufferedTuples > 0)
{
ExprContext *swapcontext;
- ResultRelInfo *presultRelInfo;
-
- presultRelInfo = proute->partitions[prev_leaf_part_index];
CopyFromInsertBatch(cstate, estate, mycid, hi_options,
- presultRelInfo, myslot, bistate,
+ prevResultRelInfo, myslot, bistate,
nBufferedTuples, bufferedTuples,
firstBufferedLineNo);
nBufferedTuples = 0;
@@ -2787,21 +2769,6 @@ CopyFrom(CopyState cstate)
}
}
- /*
- * Overwrite resultRelInfo with the corresponding partition's
- * one.
- */
- resultRelInfo = proute->partitions[leaf_part_index];
- if (unlikely(resultRelInfo == NULL))
- {
- resultRelInfo = ExecInitPartitionInfo(mtstate,
- target_resultRelInfo,
- proute, estate,
- leaf_part_index);
- proute->partitions[leaf_part_index] = resultRelInfo;
- Assert(resultRelInfo != NULL);
- }
-
/* Determine which triggers exist on this partition */
has_before_insert_row_trig = (resultRelInfo->ri_TrigDesc &&
resultRelInfo->ri_TrigDesc->trig_insert_before_row);
@@ -2827,7 +2794,7 @@ CopyFrom(CopyState cstate)
* buffer when the partition being inserted into changes.
*/
ReleaseBulkInsertStatePin(bistate);
- prev_leaf_part_index = leaf_part_index;
+ prevResultRelInfo = resultRelInfo;
}
/*
@@ -2837,7 +2804,7 @@ CopyFrom(CopyState cstate)
/*
* If we're capturing transition tuples, we might need to convert
- * from the partition rowtype to parent rowtype.
+ * from the partition rowtype to root rowtype.
*/
if (cstate->transition_capture != NULL)
{
@@ -2850,8 +2817,7 @@ CopyFrom(CopyState cstate)
*/
cstate->transition_capture->tcs_original_insert_tuple = NULL;
cstate->transition_capture->tcs_map =
- TupConvMapForLeaf(proute, target_resultRelInfo,
- leaf_part_index);
+ resultRelInfo->ri_PartitionInfo->pi_PartitionToRootMap;
}
else
{
@@ -2865,18 +2831,18 @@ CopyFrom(CopyState cstate)
}
/*
- * We might need to convert from the parent rowtype to the
- * partition rowtype.
+ * We might need to convert from the root rowtype to the partition
+ * rowtype.
*/
- map = proute->parent_child_tupconv_maps[leaf_part_index];
+ map = resultRelInfo->ri_PartitionInfo->pi_RootToPartitionMap;
if (map != NULL)
{
TupleTableSlot *new_slot;
MemoryContext oldcontext;
- Assert(proute->partition_tuple_slots != NULL &&
- proute->partition_tuple_slots[leaf_part_index] != NULL);
- new_slot = proute->partition_tuple_slots[leaf_part_index];
+ new_slot = resultRelInfo->ri_PartitionInfo->pi_PartitionTupleSlot;
+ Assert(new_slot != NULL);
+
slot = execute_attr_map_slot(map->attrMap, slot, new_slot);
/*
@@ -3021,12 +2987,8 @@ CopyFrom(CopyState cstate)
{
if (insertMethod == CIM_MULTI_CONDITIONAL)
{
- ResultRelInfo *presultRelInfo;
-
- presultRelInfo = proute->partitions[prev_leaf_part_index];
-
CopyFromInsertBatch(cstate, estate, mycid, hi_options,
- presultRelInfo, myslot, bistate,
+ prevResultRelInfo, myslot, bistate,
nBufferedTuples, bufferedTuples,
firstBufferedLineNo);
}