You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudberry.apache.org by ma...@apache.org on 2024/12/24 08:13:31 UTC

(cloudberry) 06/11: Assorted changes and cleanup for Dynamic Scan support

This is an automated email from the ASF dual-hosted git repository.

maxyang pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/cloudberry.git

commit 10bc16c245295e86cc1a26f28c1c45952ccc196a
Author: Chris Hajas <ch...@vmware.com>
AuthorDate: Mon May 23 14:59:48 2022 -0700

    Assorted changes and cleanup for Dynamic Scan support
    
    This includes changes that touched multiple scans and fixed up some of
    the explain output. Also some code cleanup.
---
 src/backend/commands/explain.c                     |  48 +++----
 src/backend/commands/explain_gp.c                  |  39 +-----
 src/backend/executor/Makefile                      |  12 +-
 src/backend/executor/execAmi.c                     |  13 +-
 src/backend/executor/execExprInterp.c              |   9 ++
 src/backend/executor/execProcnode.c                |  23 +---
 src/backend/executor/execUtils.c                   |  67 +++++++++-
 src/backend/executor/nodeBitmapHeapscan.c          |   1 -
 src/backend/executor/nodeDynamicBitmapHeapscan.c   |  10 +-
 src/backend/executor/nodeDynamicBitmapIndexscan.c  |   6 +-
 src/backend/executor/nodeDynamicIndexscan.c        |  20 +--
 src/backend/executor/nodeDynamicSeqscan.c          |  10 +-
 src/backend/gpopt/gpdbwrappers.cpp                 |  31 -----
 .../gpopt/translate/CTranslatorDXLToPlStmt.cpp     |   4 +-
 .../src/translate/CTranslatorExprToDXL.cpp         |  28 ++--
 .../include/naucrates/dxl/operators/dxlops.h       | 145 ---------------------
 src/backend/nodes/copyfuncs.c                      |  33 +----
 src/backend/nodes/outfuncs.c                       |  22 +---
 src/backend/nodes/readfast.c                       |   2 +
 src/backend/nodes/readfuncs.c                      |  33 ++---
 src/include/executor/nodeDynamicIndexscan.h        |   2 +-
 src/include/gpopt/gpdbwrappers.h                   |   9 --
 .../gpopt/translate/CTranslatorRelcacheToDXL.h     |   1 -
 src/include/nodes/execnodes.h                      |  93 +++++--------
 src/include/nodes/plannodes.h                      |  71 +++++-----
 25 files changed, 237 insertions(+), 495 deletions(-)

diff --git a/src/backend/commands/explain.c b/src/backend/commands/explain.c
index b68c81c062..33bc59ad91 100644
--- a/src/backend/commands/explain.c
+++ b/src/backend/commands/explain.c
@@ -50,7 +50,6 @@
 #include "utils/xml.h"
 
 #include "cdb/cdbgang.h"
-#include "executor/execDynamicScan.h"
 #include "optimizer/tlist.h"
 #include "optimizer/optimizer.h"
 
@@ -1920,7 +1919,6 @@ ExplainNode(PlanState *planstate, List *ancestors,
 	{
 		case T_SeqScan:
 		case T_DynamicSeqScan:
-		case T_DynamicIndexScan:
 		case T_SampleScan:
 		case T_BitmapHeapScan:
 		case T_DynamicBitmapHeapScan:
@@ -1973,19 +1971,25 @@ ExplainNode(PlanState *planstate, List *ancestors,
 					ExplainPropertyText("Index Name", indexname, es);
 			}
 			break;
+		case T_DynamicIndexScan:
+			{
+				DynamicIndexScan *dynamicIndexScan = (DynamicIndexScan *) plan;
+				Oid indexoid = dynamicIndexScan->indexscan.indexid;
+				const char *indexname =
+						explain_get_index_name(indexoid);
+
+				if (es->format == EXPLAIN_FORMAT_TEXT)
+					appendStringInfo(es->str, " on %s", indexname);
+				else
+					ExplainPropertyText("Index Name", indexname, es);
+
+				ExplainScanTarget((Scan *) plan, es);
+			}
+			break;
 		case T_DynamicBitmapIndexScan:
 			{
-			/* GPDB_12_MERGE_FIXME */
-#if 0
 				BitmapIndexScan *bitmapindexscan = (BitmapIndexScan *) plan;
 				Oid indexoid = bitmapindexscan->indexid;
-				Oid parentOid = rel_partition_get_root(indexoid);
-				while (parentOid != InvalidOid)
-				{
-					indexoid = parentOid;
-					parentOid = rel_partition_get_root(indexoid);
-				}
-
 				const char *indexname =
 				explain_get_index_name(indexoid);
 
@@ -1993,7 +1997,6 @@ ExplainNode(PlanState *planstate, List *ancestors,
 					appendStringInfo(es->str, " on %s", indexname);
 				else
 					ExplainPropertyText("Index Name", indexname, es);
-#endif
 			}
 			break;
 		case T_ModifyTable:
@@ -2293,7 +2296,12 @@ ExplainNode(PlanState *planstate, List *ancestors,
 			show_scan_qual(plan->qual, "Filter", planstate, ancestors, es);
 			if (plan->qual)
 				show_instrumentation_count("Rows Removed by Filter", 1,
+
 										   planstate, es);
+			if (IsA(plan, DynamicIndexScan))
+				ExplainPropertyInteger(
+									   "Number of partitions to scan", "",
+									   list_length(((DynamicIndexScan *) plan)->partOids), es);
 			break;
 		case T_IndexOnlyScan:
 			show_scan_qual(((IndexOnlyScan *) plan)->indexqual,
@@ -2321,6 +2329,11 @@ ExplainNode(PlanState *planstate, List *ancestors,
 		{
 			List		*bitmapqualorig;
 
+			if (IsA(plan, DynamicBitmapHeapScan))
+				ExplainPropertyInteger(
+						"Number of partitions to scan", "",
+						list_length(((DynamicBitmapHeapScan *) plan)->partOids), es);
+
 			bitmapqualorig = ((BitmapHeapScan *) plan)->bitmapqualorig;
 
 			show_scan_qual(bitmapqualorig,
@@ -2362,7 +2375,6 @@ ExplainNode(PlanState *planstate, List *ancestors,
 				ExplainPropertyInteger(
 					"Number of partitions to scan", "",
 					list_length(((DynamicSeqScan *) plan)->partOids), es);
-
 			show_scan_qual(plan->qual, "Filter", planstate, ancestors, es);
 			if (plan->qual)
 				show_instrumentation_count("Rows Removed by Filter", 1,
@@ -4570,16 +4582,6 @@ ExplainTargetRel(Plan *plan, Index rti, ExplainState *es)
 			if (es->verbose)
 				namespace = get_namespace_name(get_rel_namespace(rte->relid));
 			objecttag = "Relation Name";
-
-			/* Print dynamic scan id for dynamic scan operators */
-/* GPDB_12_MERGE_FIXME */
-#if 0
-			if (isDynamicScan(plan))
-			{
-				dynamicScanId = DynamicScan_GetDynamicScanIdPrintable(plan);
-			}
-#endif
-
 			break;
 		case T_FunctionScan:
 			{
diff --git a/src/backend/commands/explain_gp.c b/src/backend/commands/explain_gp.c
index 559ec16c93..5411b5c720 100644
--- a/src/backend/commands/explain_gp.c
+++ b/src/backend/commands/explain_gp.c
@@ -286,7 +286,6 @@ static void cdbexplain_depositStatsToNode(PlanState *planstate,
 										  CdbExplain_RecvStatCtx *ctx);
 static int cdbexplain_collectExtraText(PlanState *planstate,
 									   StringInfo notebuf);
-static int cdbexplain_countLeafPartTables(PlanState *planstate);
 
 static void show_motion_keys(PlanState *planstate, List *hashExpr, int nkeys,
 							 AttrNumber *keycols, const char *qlabel,
@@ -1657,7 +1656,8 @@ cdbexplain_showExecStats(struct PlanState *planstate, ExplainState *es)
 	 * Print number of partitioned tables scanned for dynamic scans.
 	 */
 	if (0 <= ns->totalPartTableScanned.vcnt && (T_DynamicSeqScanState == planstate->type
-												|| T_DynamicIndexScanState == planstate->type))
+												|| T_DynamicIndexScanState == planstate->type
+												|| T_DynamicBitmapHeapScanState == planstate->type))
 	{
 		/*
 		 * FIXME: Only displayed in TEXT format
@@ -1671,18 +1671,14 @@ cdbexplain_showExecStats(struct PlanState *planstate, ExplainState *es)
 			{
 				if (T_DynamicBitmapHeapScanState == planstate->type)
 				{
-					int			numTotalLeafParts = cdbexplain_countLeafPartTables(planstate);
-
 					appendStringInfoSpaces(es->str, es->indent * 2);
 					appendStringInfo(es->str,
-									 "Partitions scanned:  0 (out of %d).\n",
-									 numTotalLeafParts);
+									 "Partitions scanned:  0 .\n");
 				}
 			}
 			else
 			{
 				cdbexplain_formatSeg(segbuf, sizeof(segbuf), ns->totalPartTableScanned.imax, ns->ninst);
-				int			numTotalLeafParts = cdbexplain_countLeafPartTables(planstate);
 
 				appendStringInfoSpaces(es->str, es->indent * 2);
 
@@ -1695,18 +1691,16 @@ cdbexplain_showExecStats(struct PlanState *planstate, ExplainState *es)
 						double		totalPartTableScannedPerRescan = ns->totalPartTableScanned.vmax / instr->nloops;
 
 						appendStringInfo(es->str,
-										 "Partitions scanned:  %.0f (out of %d) %s of %ld scans.\n",
+										 "Partitions scanned:  %.0f %s of %ld scans.\n",
 										 totalPartTableScannedPerRescan,
-										 numTotalLeafParts,
 										 segbuf,
 										 instr->nloops);
 					}
 					else
 					{
 						appendStringInfo(es->str,
-										 "Partitions scanned:  %.0f (out of %d) %s.\n",
+										 "Partitions scanned:  %.0f %s.\n",
 										 ns->totalPartTableScanned.vmax,
-										 numTotalLeafParts,
 										 segbuf);
 					}
 				}
@@ -1719,10 +1713,9 @@ cdbexplain_showExecStats(struct PlanState *planstate, ExplainState *es)
 						double		maxPartTableScannedPerRescan = ns->totalPartTableScanned.vmax / instr->nloops;
 
 						appendStringInfo(es->str,
-										 "Partitions scanned:  Avg %.1f (out of %d) x %d workers of %ld scans."
+										 "Partitions scanned:  Avg %.1f x %d workers of %ld scans."
 										 "  Max %.0f parts%s.\n",
 										 totalPartTableScannedPerRescan,
-										 numTotalLeafParts,
 										 ns->totalPartTableScanned.vcnt,
 										 instr->nloops,
 										 maxPartTableScannedPerRescan,
@@ -1732,10 +1725,9 @@ cdbexplain_showExecStats(struct PlanState *planstate, ExplainState *es)
 					else
 					{
 						appendStringInfo(es->str,
-										 "Partitions scanned:  Avg %.1f (out of %d) x %d workers."
+										 "Partitions scanned:  Avg %.1f x %d workers."
 										 "  Max %.0f parts%s.\n",
 										 nPartTableScanned_avg,
-										 numTotalLeafParts,
 										 ns->totalPartTableScanned.vcnt,
 										 ns->totalPartTableScanned.vmax,
 										 segbuf);
@@ -2226,23 +2218,6 @@ gpexplain_formatSlicesOutput(struct CdbExplain_ShowStatCtx *showstatctx,
     }
 }
 
-static int
-cdbexplain_countLeafPartTables(PlanState *planstate)
-{
-	Assert(IsA(planstate, DynamicSeqScanState) ||
-		   IsA(planstate, DynamicIndexScanState));
-
-	return -1;
-	/* GPDB_12_MERGE_FIXME */
-#if 0
-	Scan	   *scan = (Scan *) planstate->plan;
-
-	Oid			root_oid = getrelid(scan->scanrelid, planstate->state->es_range_table);
-
-	return countLeafPartTables(root_oid);
-#endif
-}
-
 /*
  * Show the hash and merge keys for a Motion node.
  */
diff --git a/src/backend/executor/Makefile b/src/backend/executor/Makefile
index 9403563c96..8a02584f0d 100644
--- a/src/backend/executor/Makefile
+++ b/src/backend/executor/Makefile
@@ -91,13 +91,9 @@ OBJS += nodeMotion.o \
        nodeTupleSplit.o \
        nodePartitionSelector.o
 
-OBJS += nodeDynamicSeqscan.o
-
-# GPDB_12_MERGE_FIXME: Are any of these still needed?
-#OBJS += nodeDynamicIndexscan.o \
-#       nodeDynamicBitmapHeapscan.o \
-#       nodeDynamicBitmapIndexscan.o \
-#       nodeDynamicSeqscan.o
-#       execDynamicScan.o
+OBJS += nodeDynamicSeqscan.o \
+        nodeDynamicIndexscan.o \
+        nodeDynamicBitmapHeapscan.o \
+        nodeDynamicBitmapIndexscan.o
 
 include $(top_srcdir)/src/backend/common.mk
diff --git a/src/backend/executor/execAmi.c b/src/backend/executor/execAmi.c
index e74b10446d..55d1ff0deb 100644
--- a/src/backend/executor/execAmi.c
+++ b/src/backend/executor/execAmi.c
@@ -219,8 +219,6 @@ ExecReScan(PlanState *node)
 			ExecReScanIndexScan((IndexScanState *) node);
 			break;
 
-/* GPDB_12_MERGE_FIXME */
-#if 0
 		case T_DynamicSeqScanState:
 			ExecReScanDynamicSeqScan((DynamicSeqScanState *) node);
 			break;
@@ -228,7 +226,6 @@ ExecReScan(PlanState *node)
 		case T_DynamicIndexScanState:
 			ExecReScanDynamicIndex((DynamicIndexScanState *) node);
 			break;
-#endif
 			
 		case T_IndexOnlyScanState:
 			ExecReScanIndexOnlyScan((IndexOnlyScanState *) node);
@@ -238,24 +235,18 @@ ExecReScan(PlanState *node)
 			ExecReScanBitmapIndexScan((BitmapIndexScanState *) node);
 			break;
 
-/* GPDB_12_MERGE_FIXME */
-#if 0
 		case T_DynamicBitmapIndexScanState:
 			ExecReScanDynamicBitmapIndex((DynamicBitmapIndexScanState *) node);
 			break;
-#endif
-			
+
 		case T_BitmapHeapScanState:
 			ExecReScanBitmapHeapScan((BitmapHeapScanState *) node);
 			break;
 
-/* GPDB_12_MERGE_FIXME */
-#if 0
 		case T_DynamicBitmapHeapScanState:
 			ExecReScanDynamicBitmapHeapScan((DynamicBitmapHeapScanState *) node);
 			break;
-#endif
-			
+
 		case T_TidScanState:
 			ExecReScanTidScan((TidScanState *) node);
 			break;
diff --git a/src/backend/executor/execExprInterp.c b/src/backend/executor/execExprInterp.c
index 2e8a979a36..7729117381 100644
--- a/src/backend/executor/execExprInterp.c
+++ b/src/backend/executor/execExprInterp.c
@@ -2029,6 +2029,15 @@ CheckOpSlotCompatibility(ExprEvalStep *op, TupleTableSlot *slot)
 	if (slot->tts_ops == &TTSOpsVirtual)
 		return;
 
+	/*
+	 * We think it is OK if op's fetch kind is virtual.
+	 */
+	if (op->d.fetch.kind == &TTSOpsVirtual)
+		return;
+
+	// FIXME: A simple  explain  select * from foo join bar on foo.a=bar.b; where
+	// bar is a PT on the outer side of a HJ triggers this assert without the above
+	// if statement
 	Assert(op->d.fetch.kind == slot->tts_ops);
 #endif
 }
diff --git a/src/backend/executor/execProcnode.c b/src/backend/executor/execProcnode.c
index 015de0d73f..d18a2d2364 100644
--- a/src/backend/executor/execProcnode.c
+++ b/src/backend/executor/execProcnode.c
@@ -298,14 +298,11 @@ ExecInitNode(Plan *node, EState *estate, int eflags)
 													 estate, eflags);
 			break;
 
-/* GPDB_12_MERGE_FIXME */
-#if 0
 		case T_DynamicIndexScan:
 			result = (PlanState *) ExecInitDynamicIndexScan((DynamicIndexScan *) node,
 													estate, eflags);
 			break;
-#endif
-			
+
 		case T_IndexOnlyScan:
 			result = (PlanState *) ExecInitIndexOnlyScan((IndexOnlyScan *) node,
 														 estate, eflags);
@@ -316,26 +313,20 @@ ExecInitNode(Plan *node, EState *estate, int eflags)
 														   estate, eflags);
 			break;
 
-/* GPDB_12_MERGE_FIXME */
-#if 0
 		case T_DynamicBitmapIndexScan:
 			result = (PlanState *) ExecInitDynamicBitmapIndexScan((DynamicBitmapIndexScan *) node,
 																  estate, eflags);
 			break;
-#endif
 
 		case T_BitmapHeapScan:
 			result = (PlanState *) ExecInitBitmapHeapScan((BitmapHeapScan *) node,
 														  estate, eflags);
 			break;
 
-/* GPDB_12_MERGE_FIXME */
-#if 0
 		case T_DynamicBitmapHeapScan:
 			result = (PlanState *) ExecInitDynamicBitmapHeapScan((DynamicBitmapHeapScan *) node,
 																 estate, eflags);
 			break;
-#endif
 
 		case T_TidScan:
 			result = (PlanState *) ExecInitTidScan((TidScan *) node,
@@ -750,12 +741,9 @@ MultiExecProcNode(PlanState *node)
 			result = MultiExecBitmapIndexScan((BitmapIndexScanState *) node);
 			break;
 
-/* GPDB_12_MERGE_FIXME */
-#if 0
 		case T_DynamicBitmapIndexScanState:
 			result = MultiExecDynamicBitmapIndexScan((DynamicBitmapIndexScanState *) node);
 			break;
-#endif
 
 		case T_BitmapAndState:
 			result = MultiExecBitmapAnd((BitmapAndState *) node);
@@ -887,12 +875,9 @@ ExecEndNode(PlanState *node)
 			ExecEndIndexScan((IndexScanState *) node);
 			break;
 
-/* GPDB_12_MERGE_FIXME */
-#if 0
 		case T_DynamicIndexScanState:
 			ExecEndDynamicIndexScan((DynamicIndexScanState *) node);
 			break;
-#endif
 
 		case T_IndexOnlyScanState:
 			ExecEndIndexOnlyScan((IndexOnlyScanState *) node);
@@ -902,23 +887,17 @@ ExecEndNode(PlanState *node)
 			ExecEndBitmapIndexScan((BitmapIndexScanState *) node);
 			break;
 
-/* GPDB_12_MERGE_FIXME */
-#if 0
 		case T_DynamicBitmapIndexScanState:
 			ExecEndDynamicBitmapIndexScan((DynamicBitmapIndexScanState *) node);
 			break;
-#endif
 
 		case T_BitmapHeapScanState:
 			ExecEndBitmapHeapScan((BitmapHeapScanState *) node);
 			break;
 
-/* GPDB_12_MERGE_FIXME */
-#if 0
 		case T_DynamicBitmapHeapScanState:
 			ExecEndDynamicBitmapHeapScan((DynamicBitmapHeapScanState *) node);
 			break;
-#endif
 
 		case T_TidScanState:
 			ExecEndTidScan((TidScanState *) node);
diff --git a/src/backend/executor/execUtils.c b/src/backend/executor/execUtils.c
index 82dcdb1dff..d6fc4aab56 100644
--- a/src/backend/executor/execUtils.c
+++ b/src/backend/executor/execUtils.c
@@ -144,11 +144,6 @@ CreateExecutorState(void)
 
 	estate = makeNode(EState);
 
-	/*
-	 * Initialize dynamicTableScanInfo.
-	 */
-	estate->dynamicTableScanInfo = palloc0(sizeof(DynamicTableScanInfo));
-
 	/*
 	 * Initialize all fields of the Executor State structure
 	 */
@@ -264,7 +259,6 @@ FreeExecutorState(EState *estate)
 	}
 
 	estate->dispatcherState = NULL;
-	estate->dynamicTableScanInfo = NULL;
 
 	/* release JIT context, if allocated */
 	if (estate->es_jit)
@@ -2571,3 +2565,64 @@ void AssertSliceTableIsValid(SliceTable *st)
 	}
 }
 #endif
+
+/*
+ * During attribute re-mapping for heterogeneous partitions, we use
+ * this struct to identify which varno's attributes will be re-mapped.
+ * Using this struct as a *context* during expression tree walking, we
+ * can skip varattnos that do not belong to a given varno.
+ */
+typedef struct AttrMapContext
+{
+	const AttrNumber *newattno; /* The mapping table to remap the varattno */
+	Index		varno;			/* Which rte's varattno to re-map */
+} AttrMapContext;
+
+/*
+ * Remaps the varattno of a varattno in a Var node using an attribute map.
+ */
+static bool
+change_varattnos_varno_walker(Node *node, const AttrMapContext *attrMapCxt)
+{
+	if (node == NULL)
+		return false;
+	if (IsA(node, Var))
+	{
+		Var		   *var = (Var *) node;
+
+		if (var->varlevelsup == 0 && (var->varno == attrMapCxt->varno) &&
+			var->varattno > 0)
+		{
+			/*
+			 * ??? the following may be a problem when the node is multiply
+			 * referenced though stringToNode() doesn't create such a node
+			 * currently.
+			 */
+			Assert(attrMapCxt->newattno[var->varattno - 1] > 0);
+			var->varattno = var->varattnosyn = attrMapCxt->newattno[var->varattno - 1];
+		}
+		return false;
+	}
+	return expression_tree_walker(node, change_varattnos_varno_walker,
+								  (void *) attrMapCxt);
+}
+
+/*
+ * Replace varattno values for a given varno RTE index in an expression
+ * tree according to the given map array, that is, varattno N is replaced
+ * by newattno[N-1].  It is caller's responsibility to ensure that the array
+ * is long enough to define values for all user varattnos present in the tree.
+ * System column attnos remain unchanged.
+ *
+ * Note that the passed node tree is modified in-place!
+ */
+void
+change_varattnos_of_a_varno(Node *node, const AttrNumber *newattno, Index varno)
+{
+	AttrMapContext attrMapCxt;
+
+	attrMapCxt.newattno = newattno;
+	attrMapCxt.varno = varno;
+
+	(void) change_varattnos_varno_walker(node, &attrMapCxt);
+}
diff --git a/src/backend/executor/nodeBitmapHeapscan.c b/src/backend/executor/nodeBitmapHeapscan.c
index 5a5e8c5e43..2993b2580e 100644
--- a/src/backend/executor/nodeBitmapHeapscan.c
+++ b/src/backend/executor/nodeBitmapHeapscan.c
@@ -793,7 +793,6 @@ ExecInitBitmapHeapScanForPartition(BitmapHeapScan *node, EState *estate, int efl
 								   Relation currentRelation)
 {
 	BitmapHeapScanState *scanstate;
-	int			io_concurrency;
 
 	/* check for unsupported flags */
 	Assert(!(eflags & (EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK)));
diff --git a/src/backend/executor/nodeDynamicBitmapHeapscan.c b/src/backend/executor/nodeDynamicBitmapHeapscan.c
index 1b5e268422..2d731223eb 100644
--- a/src/backend/executor/nodeDynamicBitmapHeapscan.c
+++ b/src/backend/executor/nodeDynamicBitmapHeapscan.c
@@ -125,7 +125,7 @@ initNextTableToScan(DynamicBitmapHeapScanState *node)
 	Relation	lastScannedRel;
 	TupleDesc	partTupDesc;
 	TupleDesc	lastTupDesc;
-	AttrNumber *attMap;
+	AttrMap    *attMap;
 	Oid		   pid;
 	Relation	currentRelation;
 
@@ -158,14 +158,14 @@ initNextTableToScan(DynamicBitmapHeapScanState *node)
 	 * FIXME: should we use execute_attr_map_tuple instead? Seems like a
 	 * higher level abstraction that fits the bill
 	 */
-	attMap = convert_tuples_by_name_map_if_req(partTupDesc, lastTupDesc, "unused msg");
+	attMap = build_attrmap_by_name_if_req(partTupDesc, lastTupDesc);
 	table_close(lastScannedRel, AccessShareLock);
 
 	/* If attribute remapping is not necessary, then do not change the varattno */
 	if (attMap)
 	{
-		change_varattnos_of_a_varno((Node*)scanState->ps.plan->qual, attMap, node->scanrelid);
-		change_varattnos_of_a_varno((Node*)scanState->ps.plan->targetlist, attMap, node->scanrelid);
+		change_varattnos_of_a_varno((Node*)scanState->ps.plan->qual, attMap->attnums, node->scanrelid);
+		change_varattnos_of_a_varno((Node*)scanState->ps.plan->targetlist, attMap->attnums, node->scanrelid);
 
 		/*
 		 * Now that the varattno mapping has been changed, change the relation that
@@ -193,7 +193,7 @@ initNextTableToScan(DynamicBitmapHeapScanState *node)
 	}
 
 	if (attMap)
-		pfree(attMap);
+		free_attrmap(attMap);
 
 	node->bhsState = ExecInitBitmapHeapScanForPartition(&plan->bitmapheapscan, estate, node->eflags,
 													 currentRelation);
diff --git a/src/backend/executor/nodeDynamicBitmapIndexscan.c b/src/backend/executor/nodeDynamicBitmapIndexscan.c
index d38b8f4a61..7d1494b0cd 100644
--- a/src/backend/executor/nodeDynamicBitmapIndexscan.c
+++ b/src/backend/executor/nodeDynamicBitmapIndexscan.c
@@ -98,7 +98,7 @@ ExecInitDynamicBitmapIndexScan(DynamicBitmapIndexScan *node, EState *estate, int
 static void
 BitmapIndexScan_ReMapColumns(DynamicBitmapIndexScan *dbiScan, Oid oldOid, Oid newOid)
 {
-	AttrNumber *attMap;
+	AttrMap *attMap;
 
 	Assert(OidIsValid(newOid));
 
@@ -118,7 +118,7 @@ BitmapIndexScan_ReMapColumns(DynamicBitmapIndexScan *dbiScan, Oid oldOid, Oid ne
 		/* A bitmap index scan has no target list or quals */
 		// FIXME: no quals remapping?
 
-		pfree(attMap);
+		free_attrmap(attMap);
 	}
 }
 
@@ -156,7 +156,7 @@ beginCurrentBitmapIndexScan(DynamicBitmapIndexScanState *node, EState *estate,
 	if (!OidIsValid(node->columnLayoutOid))
 	{
 		/* Very first partition */
-		node->columnLayoutOid = get_partition_parent(tableOid);
+		node->columnLayoutOid = get_partition_parent(tableOid, true /* even_if_detached */);
 	}
 	BitmapIndexScan_ReMapColumns(dbiScan, node->columnLayoutOid, tableOid);
 	node->columnLayoutOid = tableOid;
diff --git a/src/backend/executor/nodeDynamicIndexscan.c b/src/backend/executor/nodeDynamicIndexscan.c
index 5115fa9d9c..d341404b50 100644
--- a/src/backend/executor/nodeDynamicIndexscan.c
+++ b/src/backend/executor/nodeDynamicIndexscan.c
@@ -96,7 +96,7 @@ static void
 DynamicIndexScan_ReMapColumns(DynamicIndexScan *dIndexScan, Oid oldOid, Oid newOid)
 {
 	IndexScan *indexScan = &dIndexScan->indexscan;
-	AttrNumber *attMap;
+	AttrMap *attMap;
 
 	Assert(OidIsValid(newOid));
 
@@ -115,15 +115,15 @@ DynamicIndexScan_ReMapColumns(DynamicIndexScan *dIndexScan, Oid oldOid, Oid newO
 	{
 		/* Also map attrnos in targetlist and quals */
 		change_varattnos_of_a_varno((Node *) indexScan->scan.plan.targetlist,
-									attMap, indexScan->scan.scanrelid);
+									attMap->attnums, indexScan->scan.scanrelid);
 		change_varattnos_of_a_varno((Node *) indexScan->scan.plan.qual,
-									attMap, indexScan->scan.scanrelid);
+									attMap->attnums, indexScan->scan.scanrelid);
 		change_varattnos_of_a_varno((Node *) indexScan->indexqual,
-									attMap, indexScan->scan.scanrelid);
+									attMap->attnums, indexScan->scan.scanrelid);
 		change_varattnos_of_a_varno((Node *) indexScan->indexqualorig,
-									attMap, indexScan->scan.scanrelid);
+									attMap->attnums, indexScan->scan.scanrelid);
 
-		pfree(attMap);
+		free_attrmap(attMap);
 	}
 }
 
@@ -159,7 +159,7 @@ beginCurrentIndexScan(DynamicIndexScanState *node, EState *estate,
 	{
 		/* Very first partition */
 		// Just get the direct parent, we don't support multi-level partitioning
-		node->columnLayoutOid = get_partition_parent(tableOid);
+		node->columnLayoutOid = get_partition_parent(tableOid, true /* even_if_detached */);
 	}
 	DynamicIndexScan_ReMapColumns(dynamicIndexScan,
 								  tableOid, node->columnLayoutOid);
@@ -320,13 +320,13 @@ ExecReScanDynamicIndex(DynamicIndexScanState *node)
  *
  *             Returns NULL for identical mapping.
  */
-AttrNumber*
+AttrMap*
 IndexScan_GetColumnMapping(Oid oldOid, Oid newOid)
 {
 	if (oldOid == newOid)
 		return NULL;
 
-	AttrNumber	  *attMap;
+	AttrMap	  *attMap;
 
 	Relation oldRel = heap_open(oldOid, AccessShareLock);
 	Relation newRel = heap_open(newOid, AccessShareLock);
@@ -334,7 +334,7 @@ IndexScan_GetColumnMapping(Oid oldOid, Oid newOid)
 	TupleDesc oldTupDesc = oldRel->rd_att;
 	TupleDesc newTupDesc = newRel->rd_att;
 
-	attMap = convert_tuples_by_name_map_if_req(oldTupDesc, newTupDesc, "unused msg");
+	attMap = build_attrmap_by_name_if_req(oldTupDesc, newTupDesc);
 
 	heap_close(oldRel, AccessShareLock);
 	heap_close(newRel, AccessShareLock);
diff --git a/src/backend/executor/nodeDynamicSeqscan.c b/src/backend/executor/nodeDynamicSeqscan.c
index 717a1849a4..3e1b367172 100644
--- a/src/backend/executor/nodeDynamicSeqscan.c
+++ b/src/backend/executor/nodeDynamicSeqscan.c
@@ -115,7 +115,7 @@ initNextTableToScan(DynamicSeqScanState *node)
 	Relation	lastScannedRel;
 	TupleDesc	partTupDesc;
 	TupleDesc	lastTupDesc;
-	AttrNumber *attMap;
+	AttrMap *attMap;
 	Oid		   *pid;
 	Relation	currentRelation;
 
@@ -146,14 +146,14 @@ initNextTableToScan(DynamicSeqScanState *node)
 	 * FIXME: should we use execute_attr_map_tuple instead? Seems like a
 	 * higher level abstraction that fits the bill
 	 */
-	attMap = convert_tuples_by_name_map_if_req(partTupDesc, lastTupDesc, "unused msg");
+	attMap = build_attrmap_by_name_if_req(partTupDesc, lastTupDesc);
 	table_close(lastScannedRel, AccessShareLock);
 
 	/* If attribute remapping is not necessary, then do not change the varattno */
 	if (attMap)
 	{
-		change_varattnos_of_a_varno((Node*)scanState->ps.plan->qual, attMap, node->scanrelid);
-		change_varattnos_of_a_varno((Node*)scanState->ps.plan->targetlist, attMap, node->scanrelid);
+		change_varattnos_of_a_varno((Node*)scanState->ps.plan->qual, attMap->attnums, node->scanrelid);
+		change_varattnos_of_a_varno((Node*)scanState->ps.plan->targetlist, attMap->attnums, node->scanrelid);
 
 		/*
 		 * Now that the varattno mapping has been changed, change the relation that
@@ -181,7 +181,7 @@ initNextTableToScan(DynamicSeqScanState *node)
 	}
 
 	if (attMap)
-		pfree(attMap);
+		free_attrmap(attMap);
 
 	node->seqScanState = ExecInitSeqScanForPartition(&plan->seqscan, estate,
 													 currentRelation);
diff --git a/src/backend/gpopt/gpdbwrappers.cpp b/src/backend/gpopt/gpdbwrappers.cpp
index af87a1b7aa..8fdaf94d96 100644
--- a/src/backend/gpopt/gpdbwrappers.cpp
+++ b/src/backend/gpopt/gpdbwrappers.cpp
@@ -2052,37 +2052,6 @@ gpdb::GetRelationIndexes(Relation relation)
 	GP_WRAP_END;
 	return NIL;
 }
-#if 0
-LogicalIndexes *
-gpdb::GetLogicalPartIndexes
-	(
-	Oid oid
-	)
-{
-	GP_WRAP_START;
-	{
-		/* catalog tables: pg_partition, pg_partition_rule, pg_index */
-		return BuildLogicalIndexInfo(oid);
-	}
-	GP_WRAP_END;
-	return NULL;
-}
-LogicalIndexInfo *
-gpdb::GetLogicalIndexInfo
-	(
-	Oid root_oid,
-	Oid index_oid
-	)
-{
-	GP_WRAP_START;
-	{
-		/* catalog tables: pg_index */
-		return logicalIndexInfoForIndexOid(root_oid, index_oid);
-	}
-	GP_WRAP_END;
-	return NULL;
-}
-#endif
 
 gpdb::RelationWrapper
 gpdb::GetRelation(Oid rel_oid)
diff --git a/src/backend/gpopt/translate/CTranslatorDXLToPlStmt.cpp b/src/backend/gpopt/translate/CTranslatorDXLToPlStmt.cpp
index 1e9779dc29..eeb8cb41fc 100644
--- a/src/backend/gpopt/translate/CTranslatorDXLToPlStmt.cpp
+++ b/src/backend/gpopt/translate/CTranslatorDXLToPlStmt.cpp
@@ -4142,7 +4142,7 @@ CTranslatorDXLToPlStmt::TranslateDXLDynIdxScan(
 		dyn_index_scan_dxlop->GetDXLTableDescr()->MDId());
 	RangeTblEntry *rte = TranslateDXLTblDescrToRangeTblEntry(
 		dyn_index_scan_dxlop->GetDXLTableDescr(), index, &base_table_context);
-	GPOS_ASSERT(NULL != rte);
+	GPOS_ASSERT(nullptr != rte);
 	rte->requiredPerms |= ACL_SELECT;
 	m_dxl_to_plstmt_context->AddRTE(rte);
 
@@ -4206,7 +4206,7 @@ CTranslatorDXLToPlStmt::TranslateDXLDynIdxScan(
 	// translate proj list
 	plan->targetlist =
 		TranslateDXLProjList(project_list_dxlnode, &base_table_context,
-							 NULL /*child_contexts*/, output_context);
+							 nullptr /*child_contexts*/, output_context);
 
 	// translate index filter
 	plan->qual = TranslateDXLIndexFilter(filter_dxlnode, output_context,
diff --git a/src/backend/gporca/libgpopt/src/translate/CTranslatorExprToDXL.cpp b/src/backend/gporca/libgpopt/src/translate/CTranslatorExprToDXL.cpp
index a942c22a15..cbd6804b9e 100644
--- a/src/backend/gporca/libgpopt/src/translate/CTranslatorExprToDXL.cpp
+++ b/src/backend/gporca/libgpopt/src/translate/CTranslatorExprToDXL.cpp
@@ -1330,8 +1330,8 @@ CTranslatorExprToDXL::PdxlnDynamicTableScan(
 	CDistributionSpecArray *pdrgpdsBaseTables, CExpression *pexprScalarCond,
 	CDXLPhysicalProperties *dxl_properties)
 {
-	GPOS_ASSERT(NULL != pexprDTS);
-	GPOS_ASSERT_IFF(NULL != pexprScalarCond, NULL != dxl_properties);
+	GPOS_ASSERT(nullptr != pexprDTS);
+	GPOS_ASSERT_IFF(nullptr != pexprScalarCond, nullptr != dxl_properties);
 
 	CPhysicalDynamicTableScan *popDTS =
 		CPhysicalDynamicTableScan::PopConvert(pexprDTS->Pop());
@@ -1344,7 +1344,7 @@ CTranslatorExprToDXL::PdxlnDynamicTableScan(
 	// construct plan costs
 	CDXLPhysicalProperties *pdxlpropDTS = GetProperties(pexprDTS);
 
-	if (NULL != dxl_properties)
+	if (nullptr != dxl_properties)
 	{
 		CWStringDynamic *rows_out_str = GPOS_NEW(m_mp) CWStringDynamic(
 			m_mp,
@@ -1384,9 +1384,9 @@ CTranslatorExprToDXL::PdxlnDynamicTableScan(
 	CDXLNode *pdxlnDTS = GPOS_NEW(m_mp) CDXLNode(m_mp, pdxlopDTS);
 	pdxlnDTS->SetProperties(pdxlpropDTS);
 
-	CDXLNode *pdxlnCond = NULL;
+	CDXLNode *pdxlnCond = nullptr;
 
-	if (NULL != pexprScalarCond)
+	if (nullptr != pexprScalarCond)
 	{
 		pdxlnCond = PdxlnScalar(pexprScalarCond);
 	}
@@ -1394,7 +1394,7 @@ CTranslatorExprToDXL::PdxlnDynamicTableScan(
 	CDXLNode *filter_dxlnode = PdxlnFilter(pdxlnCond);
 
 	// construct projection list
-	GPOS_ASSERT(NULL != pexprDTS->Prpp());
+	GPOS_ASSERT(nullptr != pexprDTS->Prpp());
 
 	CColRefSet *pcrsOutput = pexprDTS->Prpp()->PcrsRequired();
 	pdxlnDTS->AddChild(PdxlnProjList(pcrsOutput, colref_array));
@@ -1450,7 +1450,7 @@ CTranslatorExprToDXL::PdxlnDynamicBitmapTableScan(
 	CDistributionSpecArray *pdrgpdsBaseTables, CExpression *pexprScalar,
 	CDXLPhysicalProperties *dxl_properties)
 {
-	GPOS_ASSERT(NULL != pexprScan);
+	GPOS_ASSERT(nullptr != pexprScan);
 
 	CPhysicalDynamicBitmapTableScan *pop =
 		CPhysicalDynamicBitmapTableScan::PopConvert(pexprScan->Pop());
@@ -1483,15 +1483,15 @@ CTranslatorExprToDXL::PdxlnDynamicBitmapTableScan(
 	CDXLNode *pdxlnScan = GPOS_NEW(m_mp) CDXLNode(m_mp, pdxlopScan);
 
 	// construct plan costs
-	if (NULL == dxl_properties)
+	if (nullptr == dxl_properties)
 	{
 		dxl_properties = GetProperties(pexprScan);
 	}
 	pdxlnScan->SetProperties(dxl_properties);
 
 	// translate predicates into DXL filter
-	CDXLNode *pdxlnCond = NULL;
-	if (NULL != pexprScalar)
+	CDXLNode *pdxlnCond = nullptr;
+	if (nullptr != pexprScalar)
 	{
 		pdxlnCond = PdxlnScalar(pexprScalar);
 	}
@@ -1541,9 +1541,9 @@ CTranslatorExprToDXL::PdxlnDynamicIndexScan(
 	CExpression *pexprDIS, CColRefArray *colref_array,
 	CDXLPhysicalProperties *dxl_properties, CReqdPropPlan *prpp)
 {
-	GPOS_ASSERT(NULL != pexprDIS);
-	GPOS_ASSERT(NULL != dxl_properties);
-	GPOS_ASSERT(NULL != prpp);
+	GPOS_ASSERT(nullptr != pexprDIS);
+	GPOS_ASSERT(nullptr != dxl_properties);
+	GPOS_ASSERT(nullptr != prpp);
 
 	CPhysicalDynamicIndexScan *popDIS =
 		CPhysicalDynamicIndexScan::PopConvert(pexprDIS->Pop());
@@ -1609,7 +1609,7 @@ CTranslatorExprToDXL::PdxlnDynamicIndexScan(
 	}
 	pdrgpexprConds->Release();
 
-	CDXLNode *pdxlnResidualCond = NULL;
+	CDXLNode *pdxlnResidualCond = nullptr;
 	if (2 == pexprDIS->Arity())
 	{
 		// translate residual predicates into the filter node
diff --git a/src/backend/gporca/libnaucrates/include/naucrates/dxl/operators/dxlops.h b/src/backend/gporca/libnaucrates/include/naucrates/dxl/operators/dxlops.h
deleted file mode 100644
index 1aa920d05e..0000000000
--- a/src/backend/gporca/libnaucrates/include/naucrates/dxl/operators/dxlops.h
+++ /dev/null
@@ -1,145 +0,0 @@
-//---------------------------------------------------------------------------
-//	Greenplum Database
-//	Copyright (C) 2010 EMC Corp.
-//
-//	@filename:
-//		dxlops.h
-//
-//	@doc:
-//		collective include file for all dxl operators
-//---------------------------------------------------------------------------
-
-
-
-#ifndef GPDXL_dxlops_H
-#define GPDXL_dxlops_H
-
-#include "naucrates/dxl/operators/CDXLColDescr.h"
-#include "naucrates/dxl/operators/CDXLColRef.h"
-#include "naucrates/dxl/operators/CDXLCtasStorageOptions.h"
-#include "naucrates/dxl/operators/CDXLIndexDescr.h"
-#include "naucrates/dxl/operators/CDXLLogicalCTAS.h"
-#include "naucrates/dxl/operators/CDXLLogicalCTEAnchor.h"
-#include "naucrates/dxl/operators/CDXLLogicalCTEConsumer.h"
-#include "naucrates/dxl/operators/CDXLLogicalCTEProducer.h"
-#include "naucrates/dxl/operators/CDXLLogicalConstTable.h"
-#include "naucrates/dxl/operators/CDXLLogicalDelete.h"
-#include "naucrates/dxl/operators/CDXLLogicalExternalGet.h"
-#include "naucrates/dxl/operators/CDXLLogicalGet.h"
-#include "naucrates/dxl/operators/CDXLLogicalGroupBy.h"
-#include "naucrates/dxl/operators/CDXLLogicalInsert.h"
-#include "naucrates/dxl/operators/CDXLLogicalJoin.h"
-#include "naucrates/dxl/operators/CDXLLogicalLimit.h"
-#include "naucrates/dxl/operators/CDXLLogicalProject.h"
-#include "naucrates/dxl/operators/CDXLLogicalSelect.h"
-#include "naucrates/dxl/operators/CDXLLogicalSetOp.h"
-#include "naucrates/dxl/operators/CDXLLogicalTVF.h"
-#include "naucrates/dxl/operators/CDXLLogicalUpdate.h"
-#include "naucrates/dxl/operators/CDXLLogicalWindow.h"
-#include "naucrates/dxl/operators/CDXLPhysicalAgg.h"
-#include "naucrates/dxl/operators/CDXLPhysicalAppend.h"
-#include "naucrates/dxl/operators/CDXLPhysicalAssert.h"
-#include "naucrates/dxl/operators/CDXLPhysicalBitmapTableScan.h"
-#include "naucrates/dxl/operators/CDXLPhysicalBroadcastMotion.h"
-#include "naucrates/dxl/operators/CDXLPhysicalCTAS.h"
-#include "naucrates/dxl/operators/CDXLPhysicalCTEConsumer.h"
-#include "naucrates/dxl/operators/CDXLPhysicalCTEProducer.h"
-#include "naucrates/dxl/operators/CDXLPhysicalDML.h"
-#include "naucrates/dxl/operators/CDXLPhysicalDynamicBitmapTableScan.h"
-#include "naucrates/dxl/operators/CDXLPhysicalDynamicIndexScan.h"
-#include "naucrates/dxl/operators/CDXLPhysicalDynamicTableScan.h"
-#include "naucrates/dxl/operators/CDXLPhysicalExternalScan.h"
-#include "naucrates/dxl/operators/CDXLPhysicalGatherMotion.h"
-#include "naucrates/dxl/operators/CDXLPhysicalHashJoin.h"
-#include "naucrates/dxl/operators/CDXLPhysicalIndexOnlyScan.h"
-#include "naucrates/dxl/operators/CDXLPhysicalIndexScan.h"
-#include "naucrates/dxl/operators/CDXLPhysicalLimit.h"
-#include "naucrates/dxl/operators/CDXLPhysicalMaterialize.h"
-#include "naucrates/dxl/operators/CDXLPhysicalMergeJoin.h"
-#include "naucrates/dxl/operators/CDXLPhysicalNLJoin.h"
-#include "naucrates/dxl/operators/CDXLPhysicalPartitionSelector.h"
-#include "naucrates/dxl/operators/CDXLPhysicalRandomMotion.h"
-#include "naucrates/dxl/operators/CDXLPhysicalRedistributeMotion.h"
-#include "naucrates/dxl/operators/CDXLPhysicalResult.h"
-#include "naucrates/dxl/operators/CDXLPhysicalRoutedDistributeMotion.h"
-#include "naucrates/dxl/operators/CDXLPhysicalRowTrigger.h"
-#include "naucrates/dxl/operators/CDXLPhysicalSequence.h"
-#include "naucrates/dxl/operators/CDXLPhysicalSort.h"
-#include "naucrates/dxl/operators/CDXLPhysicalSplit.h"
-#include "naucrates/dxl/operators/CDXLPhysicalSubqueryScan.h"
-#include "naucrates/dxl/operators/CDXLPhysicalTVF.h"
-#include "naucrates/dxl/operators/CDXLPhysicalTableScan.h"
-#include "naucrates/dxl/operators/CDXLPhysicalValuesScan.h"
-#include "naucrates/dxl/operators/CDXLPhysicalWindow.h"
-#include "naucrates/dxl/operators/CDXLScalarAggref.h"
-#include "naucrates/dxl/operators/CDXLScalarArray.h"
-#include "naucrates/dxl/operators/CDXLScalarArrayCoerceExpr.h"
-#include "naucrates/dxl/operators/CDXLScalarArrayComp.h"
-#include "naucrates/dxl/operators/CDXLScalarArrayRef.h"
-#include "naucrates/dxl/operators/CDXLScalarArrayRefIndexList.h"
-#include "naucrates/dxl/operators/CDXLScalarAssertConstraint.h"
-#include "naucrates/dxl/operators/CDXLScalarAssertConstraintList.h"
-#include "naucrates/dxl/operators/CDXLScalarBitmapBoolOp.h"
-#include "naucrates/dxl/operators/CDXLScalarBitmapIndexProbe.h"
-#include "naucrates/dxl/operators/CDXLScalarBoolExpr.h"
-#include "naucrates/dxl/operators/CDXLScalarBooleanTest.h"
-#include "naucrates/dxl/operators/CDXLScalarCaseTest.h"
-#include "naucrates/dxl/operators/CDXLScalarCast.h"
-#include "naucrates/dxl/operators/CDXLScalarCoalesce.h"
-#include "naucrates/dxl/operators/CDXLScalarCoerceToDomain.h"
-#include "naucrates/dxl/operators/CDXLScalarCoerceViaIO.h"
-#include "naucrates/dxl/operators/CDXLScalarComp.h"
-#include "naucrates/dxl/operators/CDXLScalarConstValue.h"
-#include "naucrates/dxl/operators/CDXLScalarDMLAction.h"
-#include "naucrates/dxl/operators/CDXLScalarDistinctComp.h"
-#include "naucrates/dxl/operators/CDXLScalarFilter.h"
-#include "naucrates/dxl/operators/CDXLScalarFuncExpr.h"
-#include "naucrates/dxl/operators/CDXLScalarHashCondList.h"
-#include "naucrates/dxl/operators/CDXLScalarHashExpr.h"
-#include "naucrates/dxl/operators/CDXLScalarHashExprList.h"
-#include "naucrates/dxl/operators/CDXLScalarIdent.h"
-#include "naucrates/dxl/operators/CDXLScalarIfStmt.h"
-#include "naucrates/dxl/operators/CDXLScalarIndexCondList.h"
-#include "naucrates/dxl/operators/CDXLScalarJoinFilter.h"
-#include "naucrates/dxl/operators/CDXLScalarLimitCount.h"
-#include "naucrates/dxl/operators/CDXLScalarLimitOffset.h"
-#include "naucrates/dxl/operators/CDXLScalarMergeCondList.h"
-#include "naucrates/dxl/operators/CDXLScalarMinMax.h"
-#include "naucrates/dxl/operators/CDXLScalarNullIf.h"
-#include "naucrates/dxl/operators/CDXLScalarNullTest.h"
-#include "naucrates/dxl/operators/CDXLScalarOneTimeFilter.h"
-#include "naucrates/dxl/operators/CDXLScalarOpExpr.h"
-#include "naucrates/dxl/operators/CDXLScalarOpList.h"
-#include "naucrates/dxl/operators/CDXLScalarPartBound.h"
-#include "naucrates/dxl/operators/CDXLScalarPartBoundInclusion.h"
-#include "naucrates/dxl/operators/CDXLScalarPartBoundOpen.h"
-#include "naucrates/dxl/operators/CDXLScalarPartDefault.h"
-#include "naucrates/dxl/operators/CDXLScalarPartListNullTest.h"
-#include "naucrates/dxl/operators/CDXLScalarPartListValues.h"
-#include "naucrates/dxl/operators/CDXLScalarPartOid.h"
-#include "naucrates/dxl/operators/CDXLScalarProjElem.h"
-#include "naucrates/dxl/operators/CDXLScalarProjList.h"
-#include "naucrates/dxl/operators/CDXLScalarRecheckCondFilter.h"
-#include "naucrates/dxl/operators/CDXLScalarSortCol.h"
-#include "naucrates/dxl/operators/CDXLScalarSortColList.h"
-#include "naucrates/dxl/operators/CDXLScalarSubPlan.h"
-#include "naucrates/dxl/operators/CDXLScalarSubquery.h"
-#include "naucrates/dxl/operators/CDXLScalarSubqueryAll.h"
-#include "naucrates/dxl/operators/CDXLScalarSubqueryAny.h"
-#include "naucrates/dxl/operators/CDXLScalarSubqueryExists.h"
-#include "naucrates/dxl/operators/CDXLScalarSubqueryNotExists.h"
-#include "naucrates/dxl/operators/CDXLScalarSwitch.h"
-#include "naucrates/dxl/operators/CDXLScalarSwitchCase.h"
-#include "naucrates/dxl/operators/CDXLScalarValuesList.h"
-#include "naucrates/dxl/operators/CDXLScalarWindowFrameEdge.h"
-#include "naucrates/dxl/operators/CDXLScalarWindowRef.h"
-#include "naucrates/dxl/operators/CDXLSpoolInfo.h"
-#include "naucrates/dxl/operators/CDXLTableDescr.h"
-#include "naucrates/dxl/operators/CDXLWindowFrame.h"
-#include "naucrates/dxl/operators/CDXLWindowKey.h"
-#include "naucrates/dxl/operators/CDXLWindowSpec.h"
-#include "naucrates/exception.h"
-
-#endif	// !GPDXL_dxlops_H
-
-// EOF
diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c
index 3166706987..636553dbd2 100644
--- a/src/backend/nodes/copyfuncs.c
+++ b/src/backend/nodes/copyfuncs.c
@@ -264,30 +264,6 @@ CopyPlanFields(const Plan *from, Plan *newnode)
 	COPY_SCALAR_FIELD(operatorMemKB);
 }
 
-/*
- * CopyLogicalIndexInfo
- *
- *		This function copies the LogicalIndexInfo, which is part of
- *		DynamicIndexScan node.
- */
-static LogicalIndexInfo *
-CopyLogicalIndexInfo(const LogicalIndexInfo *from)
-{
-	LogicalIndexInfo *newnode = palloc(sizeof(LogicalIndexInfo));
-
-	COPY_SCALAR_FIELD(logicalIndexOid);
-	COPY_SCALAR_FIELD(nColumns);
-	COPY_POINTER_FIELD(indexKeys, from->nColumns * sizeof(AttrNumber));
-	COPY_NODE_FIELD(indPred);
-	COPY_NODE_FIELD(indExprs);
-	COPY_SCALAR_FIELD(indIsUnique);
-	COPY_SCALAR_FIELD(indType);
-	COPY_NODE_FIELD(partCons);
-	COPY_NODE_FIELD(defaultLevels);
-
-	return newnode;
-}
-
 /*
  * _copyPlan
  */
@@ -630,6 +606,8 @@ _copyDynamicSeqScan(const DynamicSeqScan *from)
 
 	CopyScanFields((Scan *) from, (Scan *) newnode);
 	COPY_NODE_FIELD(partOids);
+	COPY_NODE_FIELD(part_prune_info);
+	COPY_NODE_FIELD(join_prune_paramids);
 
 	return newnode;
 }
@@ -717,7 +695,8 @@ _copyDynamicIndexScan(const DynamicIndexScan *from)
 	/* DynamicIndexScan has some content from IndexScan */
 	CopyIndexScanFields(&from->indexscan, &newnode->indexscan);
 	COPY_NODE_FIELD(partOids);
-	newnode->logicalIndexInfo = CopyLogicalIndexInfo(from->logicalIndexInfo);
+	COPY_NODE_FIELD(part_prune_info);
+	COPY_NODE_FIELD(join_prune_paramids);
 
 	return newnode;
 }
@@ -782,8 +761,6 @@ _copyDynamicBitmapIndexScan(const DynamicBitmapIndexScan *from)
 	DynamicBitmapIndexScan *newnode = makeNode(DynamicBitmapIndexScan);
 
 	CopyBitmapIndexScanFields(&from->biscan, &newnode->biscan);
-	COPY_NODE_FIELD(partOids);
-	newnode->logicalIndexInfo = CopyLogicalIndexInfo(from->logicalIndexInfo);
 
 	return newnode;
 }
@@ -825,6 +802,8 @@ _copyDynamicBitmapHeapScan(const DynamicBitmapHeapScan *from)
 
 	CopyBitmapHeapScanFields(&from->bitmapheapscan, &newnode->bitmapheapscan);
 	COPY_NODE_FIELD(partOids);
+	COPY_NODE_FIELD(part_prune_info);
+	COPY_NODE_FIELD(join_prune_paramids);
 
 	return newnode;
 }
diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c
index faa089586c..025aeebceb 100644
--- a/src/backend/nodes/outfuncs.c
+++ b/src/backend/nodes/outfuncs.c
@@ -318,8 +318,6 @@ outDatum(StringInfo str, Datum value, int typlen, bool typbyval)
 
 #endif /* COMPILING_BINARY_FUNCS */
 
-static void outLogicalIndexInfo(StringInfo str, const LogicalIndexInfo *node);
-
 /*
  *	Stuff from plannodes.h
  */
@@ -632,6 +630,8 @@ _outDynamicSeqScan(StringInfo str, const DynamicSeqScan *node)
 
 	_outScanInfo(str, (Scan *)node);
 	WRITE_NODE_FIELD(partOids);
+	WRITE_NODE_FIELD(part_prune_info);
+	WRITE_NODE_FIELD(join_prune_paramids);
 }
 
 static void
@@ -644,20 +644,6 @@ _outSampleScan(StringInfo str, const SampleScan *node)
 	WRITE_NODE_FIELD(tablesample);
 }
 
-static void
-outLogicalIndexInfo(StringInfo str, const LogicalIndexInfo *node)
-{
-	WRITE_OID_FIELD(logicalIndexOid);
-	WRITE_INT_FIELD(nColumns);
-	WRITE_ATTRNUMBER_ARRAY(indexKeys, node->nColumns);
-	WRITE_NODE_FIELD(indPred);
-	WRITE_NODE_FIELD(indExprs);
-	WRITE_BOOL_FIELD(indIsUnique);
-	WRITE_ENUM_FIELD(indType, LogicalIndexType);
-	WRITE_NODE_FIELD(partCons);
-	WRITE_NODE_FIELD(defaultLevels);
-}
-
 static void
 outIndexScanFields(StringInfo str, const IndexScan *node)
 {
@@ -731,8 +717,6 @@ _outDynamicBitmapIndexScan(StringInfo str, const DynamicBitmapIndexScan *node)
 	WRITE_NODE_TYPE("DYNAMICBITMAPINDEXSCAN");
 
 	_outBitmapIndexScanFields(str, &node->biscan);
-	WRITE_NODE_FIELD(partOids);
-	outLogicalIndexInfo(str, node->logicalIndexInfo);
 }
 
 static void
@@ -758,6 +742,8 @@ _outDynamicBitmapHeapScan(StringInfo str, const DynamicBitmapHeapScan *node)
 
 	outBitmapHeapScanFields(str, &node->bitmapheapscan);
 	WRITE_NODE_FIELD(partOids);
+	WRITE_NODE_FIELD(part_prune_info);
+	WRITE_NODE_FIELD(join_prune_paramids);
 }
 
 static void
diff --git a/src/backend/nodes/readfast.c b/src/backend/nodes/readfast.c
index a33404cd2a..1efa5cb33a 100644
--- a/src/backend/nodes/readfast.c
+++ b/src/backend/nodes/readfast.c
@@ -936,6 +936,8 @@ _readDynamicSeqScan(void)
 
 	ReadCommonScan(&local_node->seqscan);
 	READ_NODE_FIELD(partOids);
+	READ_NODE_FIELD(part_prune_info);
+	READ_NODE_FIELD(join_prune_paramids);
 
 	READ_DONE();
 }
diff --git a/src/backend/nodes/readfuncs.c b/src/backend/nodes/readfuncs.c
index a50bf90e15..ffbf769314 100644
--- a/src/backend/nodes/readfuncs.c
+++ b/src/backend/nodes/readfuncs.c
@@ -1936,7 +1936,6 @@ _readSampleScan(void)
  */
 
 static void readIndexScanFields(IndexScan *local_node);
-static LogicalIndexInfo *readLogicalIndexInfo(void);
 
 static IndexScan *
 _readIndexScan(void)
@@ -1955,7 +1954,8 @@ _readDynamicIndexScan(void)
 	/* DynamicIndexScan has some content from IndexScan. */
 	readIndexScanFields(&local_node->indexscan);
 	READ_NODE_FIELD(partOids);
-	local_node->logicalIndexInfo = readLogicalIndexInfo();
+	READ_NODE_FIELD(part_prune_info);
+	READ_NODE_FIELD(join_prune_paramids);
 	READ_DONE();
 }
 static void
@@ -1974,24 +1974,6 @@ readIndexScanFields(IndexScan *local_node)
 	READ_ENUM_FIELD(indexorderdir, ScanDirection);
 }
 
-static LogicalIndexInfo *
-readLogicalIndexInfo(void)
-{
-	READ_TEMP_LOCALS();
-	LogicalIndexInfo *local_node = palloc(sizeof(LogicalIndexInfo));
-	READ_OID_FIELD(logicalIndexOid);
-	READ_INT_FIELD(nColumns);
-	READ_ATTRNUMBER_ARRAY(indexKeys, local_node->nColumns);
-	READ_NODE_FIELD(indPred);
-	READ_NODE_FIELD(indExprs);
-	READ_BOOL_FIELD(indIsUnique);
-	READ_ENUM_FIELD(indType, LogicalIndexType);
-	READ_NODE_FIELD(partCons);
-	READ_NODE_FIELD(defaultLevels);
-	/* No READ_DONE, this is "embedded" in other structs */
-	return local_node;
-}
-
 /*
  * _readIndexOnlyScan
  */
@@ -2041,11 +2023,11 @@ _readBitmapIndexScan(void)
 static DynamicBitmapIndexScan *
 _readDynamicBitmapIndexScan(void)
 {
-	READ_LOCALS(DynamicBitmapIndexScan);
+	READ_LOCALS_NO_FIELDS(DynamicBitmapIndexScan);
+
 	/* DynamicBitmapIndexScan has some content from BitmapIndexScan. */
 	readBitmapIndexScanFields(&local_node->biscan);
-	READ_NODE_FIELD(partOids);
-	local_node->logicalIndexInfo = readLogicalIndexInfo();
+
 	READ_DONE();
 }
 
@@ -2077,9 +2059,14 @@ static DynamicBitmapHeapScan *
 _readDynamicBitmapHeapScan(void)
 {
 	READ_LOCALS(DynamicBitmapHeapScan);
+
 	/* DynamicBitmapHeapScan has some content from BitmapHeapScan. */
 	readBitmapHeapScanFields(&local_node->bitmapheapscan);
+
 	READ_NODE_FIELD(partOids);
+	READ_NODE_FIELD(part_prune_info);
+	READ_NODE_FIELD(join_prune_paramids);
+
 	READ_DONE();
 }
 
diff --git a/src/include/executor/nodeDynamicIndexscan.h b/src/include/executor/nodeDynamicIndexscan.h
index 64e9045423..d5495539b2 100644
--- a/src/include/executor/nodeDynamicIndexscan.h
+++ b/src/include/executor/nodeDynamicIndexscan.h
@@ -21,6 +21,6 @@ extern TupleTableSlot *ExecDynamicIndexScan(PlanState *node);
 extern void ExecEndDynamicIndexScan(DynamicIndexScanState *node);
 extern void ExecReScanDynamicIndex(DynamicIndexScanState *node);
 
-extern AttrNumber *IndexScan_GetColumnMapping(Oid oldOid, Oid newOid);
+extern AttrMap *IndexScan_GetColumnMapping(Oid oldOid, Oid newOid);
 
 #endif
diff --git a/src/include/gpopt/gpdbwrappers.h b/src/include/gpopt/gpdbwrappers.h
index 9ddaad768e..ea5b9fd3cc 100644
--- a/src/include/gpopt/gpdbwrappers.h
+++ b/src/include/gpopt/gpdbwrappers.h
@@ -50,7 +50,6 @@ struct CdbComponentDatabases;
 struct StringInfoData;
 using StringInfo = StringInfoData *;
 struct LogicalIndexes;
-struct LogicalIndexInfo;
 struct ParseState;
 struct DefElem;
 struct GpPolicy;
@@ -587,14 +586,6 @@ double CdbEstimatePartitionedNumTuples(Relation rel);
 // close the given relation
 void CloseRelation(Relation rel);
 
-#if 0
-	// return the logical indexes for a partitioned table
-	LogicalIndexes *GetLogicalPartIndexes(Oid oid);
-	
-	// return the logical info structure for a given logical index oid
-	LogicalIndexInfo *GetLogicalIndexInfo(Oid root_oid, Oid index_oid);
-#endif
-
 // return a list of index oids for a given relation
 List *GetRelationIndexes(Relation relation);
 
diff --git a/src/include/gpopt/translate/CTranslatorRelcacheToDXL.h b/src/include/gpopt/translate/CTranslatorRelcacheToDXL.h
index 7b2771621a..f7e1069cae 100644
--- a/src/include/gpopt/translate/CTranslatorRelcacheToDXL.h
+++ b/src/include/gpopt/translate/CTranslatorRelcacheToDXL.h
@@ -48,7 +48,6 @@ extern "C" {
 struct RelationData;
 using Relation = struct RelationData *;
 struct LogicalIndexes;
-struct LogicalIndexInfo;
 
 namespace gpdxl
 {
diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h
index 1715204fc1..b7d1817b49 100644
--- a/src/include/nodes/execnodes.h
+++ b/src/include/nodes/execnodes.h
@@ -709,14 +709,6 @@ typedef struct EState
 	 */
 	bool		useMppParallelMode;
 
-	/*
-	 * Information relevant to dynamic table scans.
-	 */
-	/* GPDB_12_MERGE_FIXME: This is no longer used by PartitionSelectors.
-	 * But it's still referenced by DynamicHeapScan etc. nodes.
-	 */
-	DynamicTableScanInfo *dynamicTableScanInfo;
-
 	/* Should the executor skip past the alien plan nodes */
 	bool eliminateAliens;
 
@@ -727,6 +719,9 @@ typedef struct EState
 	 */
 	bool		gp_bypass_unique_check;
 
+	/* partition oid that is being scanned, used by DynamicBitmapHeapScan/IndexScan */
+	int			partitionOid;
+
 } EState;
 
 struct PlanState;
@@ -1666,30 +1661,20 @@ typedef struct DynamicIndexScanState
 	ExprContext *outer_exprContext;
 
 	/*
-	* Partition id index that mantains all unique partition ids for the
-	* DynamicIndexScan.
-	*/
-	HTAB *pidxIndex;
-
-	/*
-	* Status of the part to retrieve (result of the sequential search in a hash table).
-	*/
-	HASH_SEQ_STATUS pidxStatus;
-
-	/* Like DynamicTableScanState, this flag is required to handle error condition.
-	 * This flag prevent ExecEndDynamicIndexScan from calling hash_seq_term() or
-	 * a NULL hash table. */
-	bool shouldCallHashSeqTerm;
-
-	/*
-	 * We will create a new copy of logicalIndexInfo in this memory context for
-	 * each partition. This memory context will be reset per-partition to free
-	 * up previous partition's logicalIndexInfo memory
+	 * This memory context will be reset per-partition to free
+	 * up previous partition's memory
 	 */
 	MemoryContext partitionMemoryContext;
 
+	int			nOids; /* number of oids to scan in partitioned table */
+	Oid		   *partOids; /* list of oids to scan in partitioned table */
+	int			whichPart; /* index of current partition in partOids */
 	/* The partition oid for which the current varnos are mapped */
 	Oid columnLayoutOid;
+
+	struct PartitionPruneState *as_prune_state; /* partition dynamic pruning state */
+	Bitmapset  *as_valid_subplans; /* used to determine partitions during dynamic pruning*/
+	bool 		did_pruning; /* flag that is set when */
 } DynamicIndexScanState;
 
 /* ----------------
@@ -1769,19 +1754,22 @@ typedef struct DynamicBitmapIndexScanState
 {
 	ScanState	ss;
 
+	int			scan_state; /* the stage of scanning */
+
 	int			eflags;
 	BitmapIndexScanState *bitmapIndexScanState;
 	ExprContext *outer_exprContext;
 
 	/*
-	 * We will create a new copy of logicalIndexInfo in this memory context for
-	 * each partition. This memory context will be reset per-partition to free
-	 * up previous partition's logicalIndexInfo memory
+	 * This memory context will be reset per-partition to free
+	 * up previous partition's memory
 	 */
 	MemoryContext partitionMemoryContext;
 
 	/* The partition oid for which the current varnos are mapped */
-	Oid			columnLayoutOid;
+	Oid columnLayoutOid;
+
+	List	   *tuptable;
 } DynamicBitmapIndexScanState;
 
 /* ----------------
@@ -1886,30 +1874,9 @@ typedef struct DynamicBitmapHeapScanState
 	int			eflags;
 	BitmapHeapScanState *bhsState;
 
-
-	/*
-	 * Pid index that maintains all unique partition pids for this dynamic
-	 * table scan to scan.
-	 */
-	HTAB	   *pidIndex;
-
-	/*
-	 * The status of sequentially scan the pid index.
-	 */
-	HASH_SEQ_STATUS pidStatus;
-
-	/*
-	 * Should we call hash_seq_term()? This is required
-	 * to handle error condition, where we are required to explicitly
-	 * call hash_seq_term(). Also, if we don't have any partition, this
-	 * flag should prevent ExecEndDynamicSeqScan from calling
-	 * hash_seq_term() on a NULL hash table.
-	 */
-	bool		shouldCallHashSeqTerm;
-
 	/*
 	 * The first partition requires initialization of expression states,
-	 * such as qual and targetlist, regardless of whether we need to re-map varattno
+	 * such as qual, regardless of whether we need to re-map varattno
 	 */
 	bool		firstPartition;
 	/*
@@ -1931,7 +1898,15 @@ typedef struct DynamicBitmapHeapScanState
 	 * up previous partition's memory
 	 */
 	MemoryContext partitionMemoryContext;
-	
+
+
+	int			nOids; /* number of oids to scan in partitioned table */
+	Oid		   *partOids; /* list of oids to scan in partitioned table */
+	int			whichPart; /* index of current partition in partOids */
+
+	struct PartitionPruneState *as_prune_state; /* partition dynamic pruning state */
+	Bitmapset  *as_valid_subplans; /* used to determine partitions during dynamic pruning*/
+	bool 		did_pruning; /* flag that is set when */
 } DynamicBitmapHeapScanState;
 
 /* ----------------
@@ -2220,9 +2195,13 @@ typedef struct DynamicSeqScanState
 	 */
 	MemoryContext partitionMemoryContext;
 
-	int			nOids;
-	Oid		   *partOids;
-	int			whichPart;
+	int			nOids; /* number of oids to scan in partitioned table */
+	Oid		   *partOids; /* list of oids to scan in partitioned table */
+	int			whichPart; /* index of current partition in partOids */
+
+	struct PartitionPruneState *as_prune_state; /* partition dynamic pruning state */
+	Bitmapset  *as_valid_subplans; /* used to determine partitions during dynamic pruning*/
+	bool 		did_pruning; /* flag that is set when */
 } DynamicSeqScanState;
 
 /* ----------------
diff --git a/src/include/nodes/plannodes.h b/src/include/nodes/plannodes.h
index 0bf113a30c..bf2475033b 100644
--- a/src/include/nodes/plannodes.h
+++ b/src/include/nodes/plannodes.h
@@ -573,31 +573,6 @@ typedef struct SampleScan
 	struct TableSampleClause *tablesample;
 } SampleScan;
 
-/* ----------------
- *		index type information
- */
-typedef enum LogicalIndexType
-{
-	INDTYPE_BTREE = 0,
-	INDTYPE_BITMAP = 1,
-	INDTYPE_GIST = 2,
-	INDTYPE_GIN = 3
-} LogicalIndexType;
-
-typedef struct LogicalIndexInfo
-{
-	Oid	logicalIndexOid;	/* OID of the logical index */
-	int	nColumns;		/* Number of columns in the index */
-	AttrNumber	*indexKeys;	/* column numbers of index keys */
-	List	*indPred;		/* predicate if partial index, or NIL */
-	List	*indExprs;		/* index on expressions */
-	bool	indIsUnique;		/* unique index */
-	LogicalIndexType indType;  /* index type: btree or bitmap */
-	Node	*partCons;		/* concatenated list of check constraints
-					 * of each partition on which this index is defined */
-	List	*defaultLevels;		/* Used to identify a default partition */
-} LogicalIndexInfo;
-
 /* ----------------
  *		index scan node
  *
@@ -663,8 +638,15 @@ typedef struct DynamicIndexScan
 	 */
 	List	   *partOids;
 
-	/* logical index to use */
-	LogicalIndexInfo *logicalIndexInfo;
+	/* Info for run-time subplan pruning; NULL if we're not doing that */
+	struct PartitionPruneInfo *part_prune_info;
+
+	/*
+	 * Info for run-time join pruning, using Partition Selector nodes.
+	 * These param IDs contain additional Bitmapsets containing selected
+	 * partitions.
+	 */
+	List	   *join_prune_paramids;
 } DynamicIndexScan;
 
 /* ----------------
@@ -749,14 +731,6 @@ typedef struct DynamicBitmapIndexScan
 {
 	/* Fields shared with a normal BitmapIndexScan. Must be first! */
 	BitmapIndexScan biscan;
-
-	/*
-	 * List of partition OIDs to scan.
-	 */
-	List	   *partOids;
-
-	/* logical index to use */
-	LogicalIndexInfo *logicalIndexInfo;
 } DynamicBitmapIndexScan;
 
 /* ----------------
@@ -788,6 +762,16 @@ typedef struct DynamicBitmapHeapScan
 	 * List of partition OIDs to scan.
 	 */
 	List	   *partOids;
+
+	/* Info for run-time subplan pruning; NULL if we're not doing that */
+	struct PartitionPruneInfo *part_prune_info;
+
+	/*
+	 * Info for run-time join pruning, using Partition Selector nodes.
+	 * These param IDs contain additional Bitmapsets containing selected
+	 * partitions.
+	 */
+	List	   *join_prune_paramids;
 } DynamicBitmapHeapScan;
 
 /*
@@ -799,16 +783,21 @@ typedef struct DynamicSeqScan
 	/* Fields shared with a normal SeqScan. Must be first! */
 	SeqScan		seqscan;
 
-	/*
-	 * Index to arrays in EState->dynamicTableScanInfo, that contain information
-	 * about the partitiones that need to be scanned.
-	 */
-	int32 		partIndex;
-	int32 		partIndexPrintable;
 	/*
 	 * List of partition OIDs to scan.
 	 */
 	List	   *partOids;
+
+	/* Info for run-time subplan pruning; NULL if we're not doing that */
+	struct PartitionPruneInfo *part_prune_info;
+
+	/*
+	 * Info for run-time join pruning, using Partition Selector nodes.
+	 * These param IDs contain additional Bitmapsets containing selected
+	 * partitions.
+	 */
+	List	   *join_prune_paramids;
+
 } DynamicSeqScan;
 
 /* ----------------


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@cloudberry.apache.org
For additional commands, e-mail: commits-help@cloudberry.apache.org