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