0001-Teach-CopyFrom-to-use-ModifyTableState-for-tuple-rou.patch
text/plain
Filename: 0001-Teach-CopyFrom-to-use-ModifyTableState-for-tuple-rou.patch
Type: text/plain
Part: 0
Message:
non-bulk inserts and tuple routing
Patch
Format: format-patch
Series: patch 0001
Subject: Teach CopyFrom to use ModifyTableState for tuple-routing
| File | + | − |
|---|---|---|
| src/backend/commands/copy.c | 42 | 37 |
From a87be8a84d467d65cc0b6cf02655fc3b2b9a458f Mon Sep 17 00:00:00 2001
From: amit <amitlangote09@gmail.com>
Date: Tue, 19 Dec 2017 10:43:45 +0900
Subject: [PATCH 1/4] Teach CopyFrom to use ModifyTableState for tuple-routing
This removes all fields of CopyStateData that were meant for
tuple routing and instead uses ModifyTableState that has all those
fields, including transition_tupconv_maps. In COPY's case,
transition_tupconv_maps is only required if tuple routing is being
used, so it's safe.
---
src/backend/commands/copy.c | 79 ++++++++++++++++++++++++---------------------
1 file changed, 42 insertions(+), 37 deletions(-)
diff --git a/src/backend/commands/copy.c b/src/backend/commands/copy.c
index 254be28ae4..c82103e1c5 100644
--- a/src/backend/commands/copy.c
+++ b/src/backend/commands/copy.c
@@ -166,14 +166,7 @@ typedef struct CopyStateData
bool volatile_defexprs; /* is any of defexprs volatile? */
List *range_table;
- PartitionDispatch *partition_dispatch_info;
- int num_dispatch; /* Number of entries in the above array */
- int num_partitions; /* Number of members in the following arrays */
- ResultRelInfo **partitions; /* Per partition result relation pointers */
- TupleConversionMap **partition_tupconv_maps;
- TupleTableSlot *partition_tuple_slot;
TransitionCaptureState *transition_capture;
- TupleConversionMap **transition_tupconv_maps;
/*
* These variables are used to reduce overhead in textual COPY FROM.
@@ -2289,6 +2282,7 @@ CopyFrom(CopyState cstate)
ResultRelInfo *resultRelInfo;
ResultRelInfo *saved_resultRelInfo = NULL;
EState *estate = CreateExecutorState(); /* for ExecConstraints() */
+ ModifyTableState *mtstate = makeNode(ModifyTableState);
ExprContext *econtext;
TupleTableSlot *myslot;
MemoryContext oldcontext = CurrentMemoryContext;
@@ -2478,22 +2472,28 @@ CopyFrom(CopyState cstate)
TupleTableSlot *partition_tuple_slot;
int num_parted,
num_partitions;
-
- ExecSetupPartitionTupleRouting(NULL,
+ ModifyTable *node = makeNode(ModifyTable);
+
+ /* Just need make this field appear valid. */
+ node->nominalRelation = 1;
+ mtstate->ps.plan = (Plan *) node;
+ mtstate->ps.state = estate;
+ mtstate->resultRelInfo = resultRelInfo;
+ ExecSetupPartitionTupleRouting(mtstate,
cstate->rel,
- 1,
+ node->nominalRelation,
estate,
&partition_dispatch_info,
&partitions,
&partition_tupconv_maps,
&partition_tuple_slot,
&num_parted, &num_partitions);
- cstate->partition_dispatch_info = partition_dispatch_info;
- cstate->num_dispatch = num_parted;
- cstate->partitions = partitions;
- cstate->num_partitions = num_partitions;
- cstate->partition_tupconv_maps = partition_tupconv_maps;
- cstate->partition_tuple_slot = partition_tuple_slot;
+ mtstate->mt_partition_dispatch_info = partition_dispatch_info;
+ mtstate->mt_num_dispatch = num_parted;
+ mtstate->mt_partitions = partitions;
+ mtstate->mt_num_partitions = num_partitions;
+ mtstate->mt_partition_tupconv_maps = partition_tupconv_maps;
+ mtstate->mt_partition_tuple_slot = partition_tuple_slot;
/*
* If we are capturing transition tuples, they may need to be
@@ -2505,12 +2505,13 @@ CopyFrom(CopyState cstate)
{
int i;
- cstate->transition_tupconv_maps = (TupleConversionMap **)
- palloc0(sizeof(TupleConversionMap *) * cstate->num_partitions);
- for (i = 0; i < cstate->num_partitions; ++i)
+ mtstate->mt_transition_tupconv_maps = (TupleConversionMap **)
+ palloc0(sizeof(TupleConversionMap *) *
+ mtstate->mt_num_partitions);
+ for (i = 0; i < mtstate->mt_num_partitions; ++i)
{
- cstate->transition_tupconv_maps[i] =
- convert_tuples_by_name(RelationGetDescr(cstate->partitions[i]->ri_RelationDesc),
+ mtstate->mt_transition_tupconv_maps[i] =
+ convert_tuples_by_name(RelationGetDescr(mtstate->mt_partitions[i]->ri_RelationDesc),
RelationGetDescr(cstate->rel),
gettext_noop("could not convert row type"));
}
@@ -2530,7 +2531,7 @@ CopyFrom(CopyState cstate)
if ((resultRelInfo->ri_TrigDesc != NULL &&
(resultRelInfo->ri_TrigDesc->trig_insert_before_row ||
resultRelInfo->ri_TrigDesc->trig_insert_instead_row)) ||
- cstate->partition_dispatch_info != NULL ||
+ mtstate->mt_partition_dispatch_info != NULL ||
cstate->volatile_defexprs)
{
useHeapMultiInsert = false;
@@ -2605,7 +2606,7 @@ CopyFrom(CopyState cstate)
ExecStoreTuple(tuple, slot, InvalidBuffer, false);
/* Determine the partition to heap_insert the tuple into */
- if (cstate->partition_dispatch_info)
+ if (cstate->rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
{
int leaf_part_index;
TupleConversionMap *map;
@@ -2619,11 +2620,11 @@ CopyFrom(CopyState cstate)
* partition, respectively.
*/
leaf_part_index = ExecFindPartition(resultRelInfo,
- cstate->partition_dispatch_info,
+ mtstate->mt_partition_dispatch_info,
slot,
estate);
Assert(leaf_part_index >= 0 &&
- leaf_part_index < cstate->num_partitions);
+ leaf_part_index < mtstate->mt_num_partitions);
/*
* If this tuple is mapped to a partition that is not same as the
@@ -2641,7 +2642,8 @@ CopyFrom(CopyState cstate)
* to the selected partition.
*/
saved_resultRelInfo = resultRelInfo;
- resultRelInfo = cstate->partitions[leaf_part_index];
+ resultRelInfo = mtstate->mt_partitions[leaf_part_index];
+ Assert(resultRelInfo != NULL);
/* We do not yet have a way to insert into a foreign partition */
if (resultRelInfo->ri_FdwRoutine)
@@ -2671,7 +2673,7 @@ CopyFrom(CopyState cstate)
*/
cstate->transition_capture->tcs_original_insert_tuple = NULL;
cstate->transition_capture->tcs_map =
- cstate->transition_tupconv_maps[leaf_part_index];
+ mtstate->mt_transition_tupconv_maps[leaf_part_index];
}
else
{
@@ -2688,7 +2690,7 @@ CopyFrom(CopyState cstate)
* We might need to convert from the parent rowtype to the
* partition rowtype.
*/
- map = cstate->partition_tupconv_maps[leaf_part_index];
+ map = mtstate->mt_partition_tupconv_maps[leaf_part_index];
if (map)
{
Relation partrel = resultRelInfo->ri_RelationDesc;
@@ -2700,7 +2702,7 @@ CopyFrom(CopyState cstate)
* point on. Use a dedicated slot from this point on until
* we're finished dealing with the partition.
*/
- slot = cstate->partition_tuple_slot;
+ slot = mtstate->mt_partition_tuple_slot;
Assert(slot != NULL);
ExecSetSlotDescriptor(slot, RelationGetDescr(partrel));
ExecStoreTuple(tuple, slot, InvalidBuffer, true);
@@ -2852,7 +2854,7 @@ CopyFrom(CopyState cstate)
ExecCloseIndices(resultRelInfo);
/* Close all the partitioned tables, leaf partitions, and their indices */
- if (cstate->partition_dispatch_info)
+ if (cstate->rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
{
int i;
@@ -2862,23 +2864,26 @@ CopyFrom(CopyState cstate)
* the main target table of COPY that will be closed eventually by
* DoCopy(). Also, tupslot is NULL for the root partitioned table.
*/
- for (i = 1; i < cstate->num_dispatch; i++)
+ for (i = 1; i < mtstate->mt_num_dispatch; i++)
{
- PartitionDispatch pd = cstate->partition_dispatch_info[i];
+ PartitionDispatch pd = mtstate->mt_partition_dispatch_info[i];
heap_close(pd->reldesc, NoLock);
ExecDropSingleTupleTableSlot(pd->tupslot);
}
- for (i = 0; i < cstate->num_partitions; i++)
+ for (i = 0; i < mtstate->mt_num_partitions; i++)
{
- ResultRelInfo *resultRelInfo = cstate->partitions[i];
+ ResultRelInfo *resultRelInfo = mtstate->mt_partitions[i];
- ExecCloseIndices(resultRelInfo);
- heap_close(resultRelInfo->ri_RelationDesc, NoLock);
+ if (resultRelInfo)
+ {
+ ExecCloseIndices(resultRelInfo);
+ heap_close(resultRelInfo->ri_RelationDesc, NoLock);
+ }
}
/* Release the standalone partition tuple descriptor */
- ExecDropSingleTupleTableSlot(cstate->partition_tuple_slot);
+ ExecDropSingleTupleTableSlot(mtstate->mt_partition_tuple_slot);
}
/* Close any trigger target relations */
--
2.11.0