From 672d4191115e07cdfb7db751f99abdfc04a9e662 Mon Sep 17 00:00:00 2001
From: amitlan <amitlangote09@gmail.com>
Date: Mon, 28 Nov 2022 16:12:15 +0900
Subject: [PATCH v29 1/5] Add ri_RootToChildMap and ExecGetRootToChildMap()

It's a AttrMap provided for converting "root" table column bitmapsets
into their child relation counterpart, as a more generalized
alternative to using ri_RootToPartitionMap.attrMap to do the same.
More generalized in the sense that it can also be requested for
regular inheritance child relations, whereas ri_RootToPartitionMap
is currently only initialized in tuple-routing "partition" result
relations.

One of the differences between the two cases is that the regular
inheritance child relations can have their own columns that are not
present in the "root" table, so the map must be created in a way that
ignores such columns.  To that end, ExecGetRootToChildMap() passes
true for the missing_ok argument of build_attrmap_by_name(), so that
it puts 0 (InvalidAttr) in the map for the columns of a child table
that are not present in the root table.

root-table-to-child-table bitmapset conversions that would need
ri_RootToChildMap (cannot be done with ri_RootToPartitionMap) are
as of this commit unnecessary, but will become necessary in a
subsequent commit that will remove the insertedCols et al bitmapset
fields from RangeTblEntry node in favor of a new type of node that
will only be created and added to the plan for root tables
in a query and never for children.  The child table bitmapsets will
be created on-the-fly during execution if needed, by copying the
root table bitmapset and converting with the aforementioned map as
required.
---
 src/backend/executor/execUtils.c | 39 ++++++++++++++++++++++++++++++++
 src/include/executor/executor.h  |  2 ++
 src/include/nodes/execnodes.h    |  8 +++++++
 3 files changed, 49 insertions(+)

diff --git a/src/backend/executor/execUtils.c b/src/backend/executor/execUtils.c
index 0e595ffa6e..e2b4272d90 100644
--- a/src/backend/executor/execUtils.c
+++ b/src/backend/executor/execUtils.c
@@ -1252,6 +1252,45 @@ ExecGetChildToRootMap(ResultRelInfo *resultRelInfo)
 	return resultRelInfo->ri_ChildToRootMap;
 }
 
+/*
+ * Return the map needed to convert "root" table column bitmapsets to the
+ * rowtype of an individual child table.  A NULL result is valid and means
+ * that no conversion is needed.
+ */
+AttrMap *
+ExecGetRootToChildMap(ResultRelInfo *resultRelInfo,
+					  EState *estate)
+{
+	/* If we didn't already do so, compute the map for this child. */
+	if (!resultRelInfo->ri_RootToChildMapValid)
+	{
+		ResultRelInfo *rootRelInfo = resultRelInfo->ri_RootResultRelInfo;
+		MemoryContext oldcontext = MemoryContextSwitchTo(estate->es_query_cxt);
+
+		if (rootRelInfo)
+		{
+			/*
+			 * Passing 'true' below means any columns present in the child
+			 * table but not in the root parent are to be ignored; note that
+			 * such a case is possible with traditional inheritance but never
+			 * with partitioning.
+			 */
+			resultRelInfo->ri_RootToChildMap =
+				build_attrmap_by_name_if_req(RelationGetDescr(rootRelInfo->ri_RelationDesc),
+											 RelationGetDescr(resultRelInfo->ri_RelationDesc),
+											 true);
+		}
+		else					/* this isn't a child result rel */
+			resultRelInfo->ri_RootToChildMap = NULL;
+
+		resultRelInfo->ri_RootToChildMapValid = true;
+
+		MemoryContextSwitchTo(oldcontext);
+	}
+
+	return resultRelInfo->ri_RootToChildMap;
+}
+
 /* Return a bitmap representing columns being inserted */
 Bitmapset *
 ExecGetInsertedCols(ResultRelInfo *relinfo, EState *estate)
diff --git a/src/include/executor/executor.h b/src/include/executor/executor.h
index ed95ed1176..5c02a1521f 100644
--- a/src/include/executor/executor.h
+++ b/src/include/executor/executor.h
@@ -600,6 +600,8 @@ extern TupleTableSlot *ExecGetTriggerOldSlot(EState *estate, ResultRelInfo *relI
 extern TupleTableSlot *ExecGetTriggerNewSlot(EState *estate, ResultRelInfo *relInfo);
 extern TupleTableSlot *ExecGetReturningSlot(EState *estate, ResultRelInfo *relInfo);
 extern TupleConversionMap *ExecGetChildToRootMap(ResultRelInfo *resultRelInfo);
+extern AttrMap *ExecGetRootToChildMap(ResultRelInfo *resultRelInfo,
+					  EState *estate);
 
 extern Bitmapset *ExecGetInsertedCols(ResultRelInfo *relinfo, EState *estate);
 extern Bitmapset *ExecGetUpdatedCols(ResultRelInfo *relinfo, EState *estate);
diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h
index 18e572f171..313840fe32 100644
--- a/src/include/nodes/execnodes.h
+++ b/src/include/nodes/execnodes.h
@@ -563,6 +563,14 @@ typedef struct ResultRelInfo
 	TupleConversionMap *ri_ChildToRootMap;
 	bool		ri_ChildToRootMapValid;
 
+	/*
+	 * Map used to convert "root" table column bitmapsets into the ones that
+	 * describe a given child table's columns; see ExecGetInsertedCols() et
+	 * al.  Like ri_ChildToRootMap, computed only if needed.
+	 */
+	AttrMap	   *ri_RootToChildMap;
+	bool		ri_RootToChildMapValid;
+
 	/* for use by copyfrom.c when performing multi-inserts */
 	struct CopyMultiInsertBuffer *ri_CopyMultiInsertBuffer;
 
-- 
2.35.3

