v25-delta-pass-root-from-ExecUpdate.patch

text/plain

Filename: v25-delta-pass-root-from-ExecUpdate.patch
Type: text/plain
Part: 0
Message: Re: [HACKERS] UPDATE of partition key

Patch

Format: unified
Series: patch v25
File+
src/backend/executor/nodeModifyTable.c 25 32
diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c
index a0d8259663..09d16f4509 100644
--- a/src/backend/executor/nodeModifyTable.c
+++ b/src/backend/executor/nodeModifyTable.c
@@ -327,37 +327,6 @@ ExecInsert(ModifyTableState *mtstate,
 	if (mtstate->mt_partition_dispatch_info)
 	{
 		int			leaf_part_index;
-		ResultRelInfo *rootResultRelInfo;
-
-		/*
-		 * For UPDATE, the resultRelInfo is not the root partitioned table, so
-		 * we should convert the tuple into root's tuple descriptor, since
-		 * ExecFindPartition() starts the search from root.  The tuple
-		 * conversion map list is in the order of mtstate->resultRelInfo[], so
-		 * to retrieve the one for this resultRel, we need to know the position
-		 * of the resultRel in mtstate->resultRelInfo[].
-		 */
-		if (mtstate->operation == CMD_UPDATE)
-		{
-			int			map_index = resultRelInfo - mtstate->resultRelInfo;
-			TupleConversionMap *tupconv_map;
-
-			Assert(mtstate->rootResultRelInfo != NULL);
-			rootResultRelInfo = mtstate->rootResultRelInfo;
-
-			/* resultRelInfo must be one of the per-subplan result rels. */
-			Assert(resultRelInfo >= mtstate->resultRelInfo &&
-				   resultRelInfo <= mtstate->resultRelInfo + mtstate->mt_nplans - 1);
-
-			tupconv_map = tupconv_map_for_subplan(mtstate, map_index);
-			tuple = ConvertPartitionTupleSlot(mtstate,
-											  tupconv_map,
-											  tuple,
-											  mtstate->mt_root_tuple_slot,
-											  &slot);
-		}
-		else
-			rootResultRelInfo = resultRelInfo;
 
 		/*
 		 * Away we go ... If we end up not finding a partition after all,
@@ -367,7 +336,7 @@ ExecInsert(ModifyTableState *mtstate,
 		 * the ResultRelInfo and TupleConversionMap for the partition,
 		 * respectively.
 		 */
-		leaf_part_index = ExecFindPartition(rootResultRelInfo,
+		leaf_part_index = ExecFindPartition(resultRelInfo,
 											mtstate->mt_partition_dispatch_info,
 											slot,
 											estate);
@@ -1178,6 +1147,8 @@ lreplace:;
 		{
 			bool		tuple_deleted;
 			TupleTableSlot *ret_slot;
+			TupleConversionMap *tupconv_map;
+			int			subplan_off;
 
 			/*
 			 * When an UPDATE is run with a leaf partition, we would not have
@@ -1227,8 +1198,30 @@ lreplace:;
 			if (mtstate->mt_transition_capture)
 				saved_tcs_map = mtstate->mt_transition_capture->tcs_map;
 
+
+			/*
+			 * For UPDATE, the resultRelInfo is not the root partitioned
+			 * table, so we should convert the tuple into root's tuple
+			 * descriptor, since ExecInsert() starts the search from root.
+			 */
+			subplan_off = resultRelInfo - mtstate->resultRelInfo;
+			tupconv_map = tupconv_map_for_subplan(mtstate, subplan_off);
+			tuple = ConvertPartitionTupleSlot(mtstate,
+											  tupconv_map,
+											  tuple,
+											  mtstate->mt_root_tuple_slot,
+											  &slot);
+
+			/*
+			 * Make it look like to ExecInsert() that we are inserting the
+			 * tuple into the root table.
+			 */
+			Assert(mtstate->rootResultRelInfo != NULL);
+			estate->es_result_relation_info = mtstate->rootResultRelInfo;
 			ret_slot = ExecInsert(mtstate, slot, planSlot, NULL,
 								  ONCONFLICT_NONE, estate, canSetTag);
+			/* Restore for the next tuple. */
+			estate->es_result_relation_info = resultRelInfo;
 
 			if (mtstate->mt_transition_capture)
 			{