From 7d321c1627b9ce16357a35704fee030b3ecbdedd Mon Sep 17 00:00:00 2001
From: amitlan <amitlangote09@gmail.com>
Date: Mon, 19 Oct 2020 12:32:09 +0900
Subject: [PATCH v19 2/2] Remove PartitionRoutingInfo struct

The extra indirection neeeded to access its members via its enclosing
ResultRelInfo seems pointless.
---
 src/backend/commands/copy.c              |  4 ++--
 src/backend/executor/execMain.c          |  3 ++-
 src/backend/executor/execPartition.c     | 32 ++++++++++++++++----------------
 src/backend/executor/nodeModifyTable.c   |  7 ++-----
 src/backend/replication/logical/worker.c | 11 ++++-------
 src/include/executor/execPartition.h     | 21 ---------------------
 src/include/nodes/execnodes.h            | 15 ++++++++++-----
 7 files changed, 36 insertions(+), 57 deletions(-)

diff --git a/src/backend/commands/copy.c b/src/backend/commands/copy.c
index eb326de..0c3672e 100644
--- a/src/backend/commands/copy.c
+++ b/src/backend/commands/copy.c
@@ -3118,7 +3118,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 */
@@ -3126,7 +3126,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 293f53d..eef3516 100644
--- a/src/backend/executor/execMain.c
+++ b/src/backend/executor/execMain.c
@@ -1243,7 +1243,8 @@ 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 ExecInitPartitionInfo */
+	resultRelInfo->ri_PartitionTupleSlot = NULL; /* ditto */
 	resultRelInfo->ri_CopyMultiInsertBuffer = NULL;
 }
 
diff --git a/src/backend/executor/execPartition.c b/src/backend/executor/execPartition.c
index 08f91e5..e72487f 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 = false;
 
 		CHECK_FOR_INTERRUPTS();
 
@@ -348,6 +349,8 @@ ExecFindPartition(ModifyTableState *mtstate,
 
 		if (partdesc->is_leaf[partidx])
 		{
+			is_leaf = true;
+
 			/*
 			 * 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 5efbfb6..4a26a07 100644
--- a/src/backend/executor/nodeModifyTable.c
+++ b/src/backend/executor/nodeModifyTable.c
@@ -1906,7 +1906,6 @@ ExecPrepareTupleRouting(ModifyTableState *mtstate,
 						ResultRelInfo **partRelInfo)
 {
 	ResultRelInfo *partrel;
-	PartitionRoutingInfo *partrouteinfo;
 	TupleConversionMap *map;
 	bool		has_before_insert_row_trig;
 
@@ -1918,8 +1917,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 and there are no BEFORE triggers
@@ -1935,10 +1932,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);
 	}
diff --git a/src/backend/replication/logical/worker.c b/src/backend/replication/logical/worker.c
index b8e297c..3a5b733 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 74c3991..473c4cd 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 ce83b81..1d9265c 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;
 
 	/* for use by copy.c when performing multi-inserts */
 	struct CopyMultiInsertBuffer *ri_CopyMultiInsertBuffer;
-- 
1.8.3.1

