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 5f5250e70bf0a3fccc9553106c380d4c6f5e3964
Author: Chris Hajas <[email protected]>
AuthorDate: Mon May 23 14:59:33 2022 -0700

    Adds Orca support for Dynamic Bitmap Heap/Index Scan
---
 src/backend/executor/nodeBitmapHeapscan.c          |  42 +++--
 src/backend/executor/nodeDynamicBitmapHeapscan.c   | 181 +++++++++++----------
 src/backend/executor/nodeDynamicBitmapIndexscan.c  |  77 +++++++--
 .../gpopt/translate/CTranslatorDXLToPlStmt.cpp     |  68 ++++----
 .../src/translate/CTranslatorExprToDXL.cpp         | 140 ++++++----------
 .../operators/CDXLPhysicalDynamicBitmapTableScan.h |  30 ++--
 .../CParseHandlerPhysicalAbstractBitmapScan.h      |   4 +-
 .../CParseHandlerPhysicalDynamicBitmapTableScan.h  |  10 +-
 .../CDXLPhysicalDynamicBitmapTableScan.cpp         |  30 +++-
 .../CParseHandlerPhysicalAbstractBitmapScan.cpp    |  41 ++++-
 .../CParseHandlerPhysicalBitmapTableScan.cpp       |   3 +-
 ...CParseHandlerPhysicalDynamicBitmapTableScan.cpp |  16 +-
 src/include/executor/nodeDynamicBitmapHeapscan.h   |   5 +-
 src/include/executor/nodeDynamicBitmapIndexscan.h  |   3 -
 14 files changed, 355 insertions(+), 295 deletions(-)

diff --git a/src/backend/executor/nodeBitmapHeapscan.c 
b/src/backend/executor/nodeBitmapHeapscan.c
index d4caa77e77..5a5e8c5e43 100644
--- a/src/backend/executor/nodeBitmapHeapscan.c
+++ b/src/backend/executor/nodeBitmapHeapscan.c
@@ -762,8 +762,38 @@ ExecEndBitmapHeapScan(BitmapHeapScanState *node)
 BitmapHeapScanState *
 ExecInitBitmapHeapScan(BitmapHeapScan *node, EState *estate, int eflags)
 {
-       BitmapHeapScanState *scanstate;
        Relation        currentRelation;
+       BitmapHeapScanState *bhsState;
+
+       /* check for unsupported flags */
+       Assert(!(eflags & (EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK)));
+
+       /*
+        * open the scan relation
+        */
+       currentRelation = ExecOpenScanRelation(estate, node->scan.scanrelid, 
eflags);
+
+       bhsState =  ExecInitBitmapHeapScanForPartition(node, estate, eflags,
+                                                                               
                   currentRelation);
+
+       /*
+        * initialize child nodes
+        *
+        * We do this last because the child nodes will open indexscans on our
+        * relation's indexes, and we want to be sure we have acquired a lock on
+        * the relation first.
+        */
+       outerPlanState(bhsState) = ExecInitNode(outerPlan(node), estate, 
eflags);
+
+       return bhsState;
+}
+
+BitmapHeapScanState *
+ExecInitBitmapHeapScanForPartition(BitmapHeapScan *node, EState *estate, int 
eflags,
+                                                                  Relation 
currentRelation)
+{
+       BitmapHeapScanState *scanstate;
+       int                     io_concurrency;
 
        /* check for unsupported flags */
        Assert(!(eflags & (EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK)));
@@ -819,16 +849,6 @@ ExecInitBitmapHeapScan(BitmapHeapScan *node, EState 
*estate, int eflags)
         */
        ExecAssignExprContext(estate, &scanstate->ss.ps);
 
-       /*
-        * open the scan relation
-        */
-       currentRelation = ExecOpenScanRelation(estate, node->scan.scanrelid, 
eflags);
-
-       /*
-        * initialize child nodes
-        */
-       outerPlanState(scanstate) = ExecInitNode(outerPlan(node), estate, 
eflags);
-
        /*
         * get the scan type from the relation descriptor.
         */
diff --git a/src/backend/executor/nodeDynamicBitmapHeapscan.c 
b/src/backend/executor/nodeDynamicBitmapHeapscan.c
index c39a27d611..1b5e268422 100644
--- a/src/backend/executor/nodeDynamicBitmapHeapscan.c
+++ b/src/backend/executor/nodeDynamicBitmapHeapscan.c
@@ -26,15 +26,15 @@
 
 #include "executor/executor.h"
 #include "executor/instrument.h"
-#include "executor/execDynamicScan.h"
 #include "executor/nodeBitmapHeapscan.h"
+#include "executor/nodeDynamicIndexscan.h"
 #include "executor/nodeDynamicBitmapHeapscan.h"
+#include "executor/execPartition.h"
 #include "nodes/execnodes.h"
-#include "utils/hsearch.h"
-#include "parser/parsetree.h"
+#include "utils/rel.h"
 #include "utils/memutils.h"
-#include "cdb/cdbvars.h"
-#include "cdb/partitionselection.h"
+#include "access/table.h"
+#include "access/tableam.h"
 
 static void CleanupOnePartition(DynamicBitmapHeapScanState *node);
 
@@ -43,6 +43,8 @@ ExecInitDynamicBitmapHeapScan(DynamicBitmapHeapScan *node, 
EState *estate, int e
 {
        DynamicBitmapHeapScanState *state;
        Oid                     reloid;
+       int                     i;
+       ListCell *lc;
 
        Assert((eflags & (EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK)) == 0);
 
@@ -50,14 +52,28 @@ ExecInitDynamicBitmapHeapScan(DynamicBitmapHeapScan *node, 
EState *estate, int e
        state->eflags = eflags;
        state->ss.ps.plan = (Plan *) node;
        state->ss.ps.state = estate;
-
+       state->ss.ps.ExecProcNode = ExecDynamicBitmapHeapScan;
+       state->did_pruning = false;
        state->scan_state = SCAN_INIT;
 
-       /* Initialize result tuple type. */
-       ExecInitResultTupleSlot(estate, &state->ss.ps);
-       ExecAssignResultTypeFromTL(&state->ss.ps);
+       state->whichPart = -1;
+       state->nOids = list_length(node->partOids);
+       state->partOids = palloc(sizeof(Oid) * state->nOids);
+       foreach_with_count(lc, node->partOids, i)
+               state->partOids[i] = lfirst_oid(lc);
+
+       /*
+        * tuple table initialization
+        */
+       Relation scanRel = ExecOpenScanRelation(estate, 
node->bitmapheapscan.scan.scanrelid, eflags);
+       ExecInitScanTupleSlot(estate, &state->ss, RelationGetDescr(scanRel), 
table_slot_callbacks(scanRel));
 
-       reloid = getrelid(node->bitmapheapscan.scan.scanrelid, 
estate->es_range_table);
+       /*
+        * Initialize result tuple type and projection info.
+        */
+       ExecInitResultTypeTL(&state->ss.ps);
+
+       reloid = exec_rt_fetch(node->bitmapheapscan.scan.scanrelid, 
estate)->relid;
        Assert(OidIsValid(reloid));
 
        state->firstPartition = true;
@@ -77,6 +93,8 @@ ExecInitDynamicBitmapHeapScan(DynamicBitmapHeapScan *node, 
EState *estate, int e
                                                                         
ALLOCSET_DEFAULT_INITSIZE,
                                                                         
ALLOCSET_DEFAULT_MAXSIZE);
 
+       state->as_prune_state = NULL;
+
        /*
         * initialize child nodes.
         *
@@ -108,17 +126,15 @@ initNextTableToScan(DynamicBitmapHeapScanState *node)
        TupleDesc       partTupDesc;
        TupleDesc       lastTupDesc;
        AttrNumber *attMap;
-       Oid                     currentPartitionOid;
-       Oid                *pid;
+       Oid                pid;
        Relation        currentRelation;
 
-       pid = hash_seq_search(&node->pidStatus);
-       if (pid == NULL)
-       {
-               node->shouldCallHashSeqTerm = false;
+       if (++node->whichPart < node->nOids)
+               pid = node->partOids[node->whichPart];
+       else
                return false;
-       }
-       currentPartitionOid = *pid;
+
+       estate->partitionOid = pid;
 
        /* Collect number of partitions scanned in EXPLAIN ANALYZE */
        if (NULL != scanState->ps.instrument)
@@ -127,14 +143,23 @@ initNextTableToScan(DynamicBitmapHeapScanState *node)
                instr->numPartScanned++;
        }
 
-       CleanupOnePartition(node);
+       currentRelation = scanState->ss_currentRelation =
+                       table_open(node->partOids[node->whichPart], 
AccessShareLock);
 
-       currentRelation = scanState->ss_currentRelation = 
heap_open(currentPartitionOid, AccessShareLock);
-       lastScannedRel = heap_open(node->lastRelOid, AccessShareLock);
+       if (currentRelation->rd_rel->relkind != RELKIND_RELATION)
+       {
+               /* shouldn't happen */
+               elog(ERROR, "unexpected relkind in Dynamic Scan: %c", 
currentRelation->rd_rel->relkind);
+       }
+       lastScannedRel = table_open(node->lastRelOid, AccessShareLock);
        lastTupDesc = RelationGetDescr(lastScannedRel);
        partTupDesc = RelationGetDescr(scanState->ss_currentRelation);
-       attMap = varattnos_map(lastTupDesc, partTupDesc);
-       heap_close(lastScannedRel, AccessShareLock);
+       /*
+        * 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");
+       table_close(lastScannedRel, AccessShareLock);
 
        /* If attribute remapping is not necessary, then do not change the 
varattno */
        if (attMap)
@@ -146,13 +171,13 @@ initNextTableToScan(DynamicBitmapHeapScanState *node)
                 * Now that the varattno mapping has been changed, change the 
relation that
                 * the new varnos correspond to
                 */
-               node->lastRelOid = currentPartitionOid;
+               node->lastRelOid = pid;
        }
 
        /*
-        * For the very first partition, the targetlist of planstate is set to 
null. So, we must
-        * initialize quals and targetlist, regardless of remapping 
requirements. For later
-        * partitions, we only initialize quals and targetlist if a column 
re-mapping is necessary.
+        * For the very first partition, the qual of planstate is set to null. 
So, we must
+        * initialize quals, regardless of remapping requirements. For later
+        * partitions, we only initialize quals if a column re-mapping is 
necessary.
         */
        if (attMap || node->firstPartition)
        {
@@ -161,10 +186,8 @@ initNextTableToScan(DynamicBitmapHeapScanState *node)
                MemoryContext oldCxt = 
MemoryContextSwitchTo(node->partitionMemoryContext);
 
                /* Initialize child expressions */
-               scanState->ps.qual = (List *) ExecInitExpr((Expr *) 
scanState->ps.plan->qual,
-                                                                               
                   (PlanState *) scanState);
-               scanState->ps.targetlist = (List *) ExecInitExpr((Expr *) 
scanState->ps.plan->targetlist,
-                                                                               
                                 (PlanState *) scanState);
+               scanState->ps.qual =
+                               ExecInitQual(scanState->ps.plan->qual, 
(PlanState *) scanState);
 
                MemoryContextSwitchTo(oldCxt);
        }
@@ -172,7 +195,6 @@ initNextTableToScan(DynamicBitmapHeapScanState *node)
        if (attMap)
                pfree(attMap);
 
-       DynamicScan_SetTableOid(&node->ss, currentPartitionOid);
        node->bhsState = 
ExecInitBitmapHeapScanForPartition(&plan->bitmapheapscan, estate, node->eflags,
                                                                                
                         currentRelation);
 
@@ -185,50 +207,37 @@ initNextTableToScan(DynamicBitmapHeapScanState *node)
        return true;
 }
 
-/*
- * setPidIndex
- *   Set the pid index for the given dynamic table.
- */
-static void
-setPidIndex(DynamicBitmapHeapScanState *node)
-{
-       Assert(node->pidIndex == NULL);
-
-       ScanState *scanState = (ScanState *)node;
-       EState *estate = scanState->ps.state;
-       DynamicBitmapHeapScan *plan = (DynamicBitmapHeapScan *) 
scanState->ps.plan;
-
-       Assert(estate->dynamicTableScanInfo != NULL);
-
-       /*
-        * Ensure that the dynahash exists even if the partition selector
-        * didn't choose any partition for current scan node [MPP-24169].
-        */
-       InsertPidIntoDynamicTableScanInfo(estate, plan->partIndex,
-                                                                         
InvalidOid, InvalidPartitionSelectorId);
-
-       Assert(NULL != estate->dynamicTableScanInfo->pidIndexes);
-       Assert(estate->dynamicTableScanInfo->numScans >= plan->partIndex);
-       node->pidIndex = 
estate->dynamicTableScanInfo->pidIndexes[plan->partIndex - 1];
-       Assert(node->pidIndex != NULL);
-}
-
 TupleTableSlot *
-ExecDynamicBitmapHeapScan(DynamicBitmapHeapScanState *node)
+ExecDynamicBitmapHeapScan(PlanState *pstate)
 {
+       DynamicBitmapHeapScanState *node = castNode(DynamicBitmapHeapScanState, 
pstate);
        TupleTableSlot *slot = NULL;
 
-       /*
-        * If this is called the first time, find the pid index that contains 
all unique
-        * partition pids for this node to scan.
-        */
-       if (node->pidIndex == NULL)
+       DynamicBitmapHeapScan      *plan = (DynamicBitmapHeapScan *) 
node->ss.ps.plan;
+       node->as_valid_subplans = NULL;
+       if (NULL != plan->join_prune_paramids && !node->did_pruning)
        {
-               setPidIndex(node);
-               Assert(node->pidIndex != NULL);
+               node->did_pruning = true;
+               node->as_valid_subplans =
+                               ExecFindMatchingSubPlans(node->as_prune_state,
+                                                                               
 node->ss.ps.state,
+                                                                               
 list_length(plan->partOids),
+                                                                               
 plan->join_prune_paramids);
+
+               int i = 0;
+               int partOidIdx = -1;
+               List *newPartOids = NIL;
+               ListCell *lc;
+               for(i = 0; i < bms_num_members(node->as_valid_subplans); i++)
+               {
+                       partOidIdx = bms_next_member(node->as_valid_subplans, 
partOidIdx);
+                       newPartOids = lappend_oid(newPartOids, 
node->partOids[partOidIdx]);
+               }
 
-               hash_seq_init(&node->pidStatus, node->pidIndex);
-               node->shouldCallHashSeqTerm = true;
+               node->partOids = palloc(sizeof(Oid) * list_length(newPartOids));
+               foreach_with_count(lc, newPartOids, i)
+                       node->partOids[i] = lfirst_oid(lc);
+               node->nOids = list_length(newPartOids);
        }
 
        /*
@@ -244,7 +253,7 @@ ExecDynamicBitmapHeapScan(DynamicBitmapHeapScanState *node)
                                break;
                }
 
-               slot = ExecBitmapHeapScan(node->bhsState);
+               slot = ExecProcNode(&node->bhsState->ss.ps);
 
                if (!TupIsNull(slot))
                        break;
@@ -274,11 +283,8 @@ CleanupOnePartition(DynamicBitmapHeapScanState *scanState)
                outerPlanState(scanState->bhsState) = NULL;
                ExecEndBitmapHeapScan(scanState->bhsState);
                scanState->bhsState = NULL;
-       }
-       if ((scanState->scan_state & SCAN_SCAN) != 0)
-       {
                Assert(scanState->ss.ss_currentRelation != NULL);
-               ExecCloseScanRelation(scanState->ss.ss_currentRelation);
+               table_close(scanState->ss.ss_currentRelation, NoLock);
                scanState->ss.ss_currentRelation = NULL;
        }
 }
@@ -291,12 +297,6 @@ static void
 DynamicBitmapHeapScanEndCurrentScan(DynamicBitmapHeapScanState *node)
 {
        CleanupOnePartition(node);
-
-       if (node->shouldCallHashSeqTerm)
-       {
-               hash_seq_term(&node->pidStatus);
-               node->shouldCallHashSeqTerm = false;
-       }
 }
 
 /*
@@ -309,7 +309,8 @@ ExecEndDynamicBitmapHeapScan(DynamicBitmapHeapScanState 
*node)
 {
        DynamicBitmapHeapScanEndCurrentScan(node);
 
-       ExecClearTuple(node->ss.ps.ps_ResultTupleSlot);
+       if (node->ss.ps.ps_ResultTupleSlot)
+               ExecClearTuple(node->ss.ps.ps_ResultTupleSlot);
 
        /*
         * close down subplans
@@ -326,6 +327,18 @@ ExecReScanDynamicBitmapHeapScan(DynamicBitmapHeapScanState 
*node)
 {
        DynamicBitmapHeapScanEndCurrentScan(node);
 
-       /* Force reloading the partition hash table */
-       node->pidIndex = NULL;
+       // reset partition internal state
+       /*
+        * If any PARAM_EXEC Params used in pruning expressions have changed, 
then
+        * we'd better unset the valid subplans so that they are reselected for
+        * the new parameter values.
+        */
+       if (node->as_prune_state &&
+               bms_overlap(node->ss.ps.chgParam,
+                                       node->as_prune_state->execparamids))
+       {
+               bms_free(node->as_valid_subplans);
+               node->as_valid_subplans = NULL;
+       }
+       node->whichPart = -1;
 }
diff --git a/src/backend/executor/nodeDynamicBitmapIndexscan.c 
b/src/backend/executor/nodeDynamicBitmapIndexscan.c
index 5dd5372bd2..d38b8f4a61 100644
--- a/src/backend/executor/nodeDynamicBitmapIndexscan.c
+++ b/src/backend/executor/nodeDynamicBitmapIndexscan.c
@@ -29,18 +29,17 @@
 
 #include "postgres.h"
 
-#include "cdb/cdbvars.h"
-#include "cdb/partitionselection.h"
+#include "catalog/partition.h"
 #include "executor/executor.h"
 #include "executor/instrument.h"
 #include "nodes/execnodes.h"
 #include "executor/nodeBitmapIndexscan.h"
-#include "executor/execDynamicScan.h"
 #include "executor/nodeDynamicIndexscan.h"
 #include "executor/nodeDynamicBitmapIndexscan.h"
-#include "access/genam.h"
-#include "nodes/nodeFuncs.h"
+#include "access/table.h"
+#include "access/tableam.h"
 #include "utils/memutils.h"
+#include "utils/rel.h"
 
 /*
  * Initialize ScanState in DynamicBitmapIndexScan.
@@ -56,8 +55,33 @@ ExecInitDynamicBitmapIndexScan(DynamicBitmapIndexScan *node, 
EState *estate, int
        dynamicBitmapIndexScanState = makeNode(DynamicBitmapIndexScanState);
        dynamicBitmapIndexScanState->ss.ps.plan = (Plan *) node;
        dynamicBitmapIndexScanState->ss.ps.state = estate;
+       dynamicBitmapIndexScanState->ss.ps.ExecProcNode = ExecDynamicIndexScan;
        dynamicBitmapIndexScanState->eflags = eflags;
 
+       dynamicBitmapIndexScanState->scan_state = SCAN_INIT;
+
+       /*
+        * Initialize child expressions
+        *
+        * These are not used for anything, we rely on the child IndexScan node
+        * to do all evaluation for us. But I think this is still needed to
+        * find and process any SubPlans. See comment in ExecInitIndexScan.
+        */
+       dynamicBitmapIndexScanState->ss.ps.qual =
+                       ExecInitQual(node->biscan.scan.plan.qual,
+                                                (PlanState *) 
dynamicBitmapIndexScanState);
+
+       /*
+        * tuple table initialization
+        */
+       Relation scanRel = ExecOpenScanRelation(estate, 
node->biscan.scan.scanrelid, eflags);
+       ExecInitScanTupleSlot(estate, &dynamicBitmapIndexScanState->ss, 
RelationGetDescr(scanRel), table_slot_callbacks(scanRel));
+
+       /*
+        * Initialize result tuple type and projection info.
+        */
+       ExecInitResultTypeTL(&dynamicBitmapIndexScanState->ss.ps);
+
        /*
         * This context will be reset per-partition to free up per-partition
         * copy of LogicalIndexInfo
@@ -91,11 +115,8 @@ BitmapIndexScan_ReMapColumns(DynamicBitmapIndexScan 
*dbiScan, Oid oldOid, Oid ne
 
        if (attMap)
        {
-               IndexScan_MapLogicalIndexInfo(dbiScan->logicalIndexInfo,
-                                                                         
attMap,
-                                                                         
dbiScan->biscan.scan.scanrelid);
-
                /* A bitmap index scan has no target list or quals */
+               // FIXME: no quals remapping?
 
                pfree(attMap);
        }
@@ -114,7 +135,18 @@ beginCurrentBitmapIndexScan(DynamicBitmapIndexScanState 
*node, EState *estate,
        Relation        currentRelation;
        Oid                     indexOid;
        MemoryContext oldCxt;
+       List       *save_tupletable;
+
 
+       /*
+        * open the base relation and acquire appropriate lock on it.
+        */
+       currentRelation = table_open(tableOid, AccessShareLock);
+       node->ss.ss_currentRelation = currentRelation;
+
+       save_tupletable = estate->es_tupleTable;
+
+       estate->es_tupleTable = NIL;
        oldCxt = MemoryContextSwitchTo(node->partitionMemoryContext);
 
        /*
@@ -124,7 +156,7 @@ beginCurrentBitmapIndexScan(DynamicBitmapIndexScanState 
*node, EState *estate,
        if (!OidIsValid(node->columnLayoutOid))
        {
                /* Very first partition */
-               node->columnLayoutOid = rel_partition_get_root(tableOid);
+               node->columnLayoutOid = get_partition_parent(tableOid);
        }
        BitmapIndexScan_ReMapColumns(dbiScan, node->columnLayoutOid, tableOid);
        node->columnLayoutOid = tableOid;
@@ -136,13 +168,13 @@ beginCurrentBitmapIndexScan(DynamicBitmapIndexScanState 
*node, EState *estate,
         * We started at table level, and now we are fetching the oid of an 
index
         * partition.
         */
-       currentRelation = heap_open(tableOid, AccessShareLock);
-       indexOid = getPhysicalIndexRelid(currentRelation, 
dbiScan->logicalIndexInfo);
+       Oid indexOidOld = dbiScan->biscan.indexid;
+       indexOid = index_get_partition(currentRelation, 
dbiScan->biscan.indexid);
        if (!OidIsValid(indexOid))
-               elog(ERROR, "failed to find index for partition \"%s\" in 
dynamic index scan",
-                        RelationGetRelationName(currentRelation));
-       ExecCloseScanRelation(currentRelation);
+               elog(ERROR, "failed to find index for partition \"%s\" for 
\"%d\"in dynamic index scan",
+                        RelationGetRelationName(currentRelation), 
dbiScan->biscan.indexid);
 
+       table_close(currentRelation, NoLock);
        /* Modify the plan node with the index ID */
        dbiScan->biscan.indexid = indexOid;
 
@@ -150,12 +182,15 @@ beginCurrentBitmapIndexScan(DynamicBitmapIndexScanState 
*node, EState *estate,
                                                                                
                                 estate,
                                                                                
                                 node->eflags);
 
+       dbiScan->biscan.indexid = indexOidOld;
        if (node->ss.ps.instrument)
        {
                /* Let the BitmapIndexScan share our Instrument node */
                node->bitmapIndexScanState->ss.ps.instrument = 
node->ss.ps.instrument;
        }
 
+       node->tuptable = estate->es_tupleTable;
+       estate->es_tupleTable = save_tupletable;
        MemoryContextSwitchTo(oldCxt);
 
        if (node->outer_exprContext)
@@ -173,6 +208,9 @@ endCurrentBitmapIndexScan(DynamicBitmapIndexScanState *node)
                ExecEndBitmapIndexScan(node->bitmapIndexScanState);
                node->bitmapIndexScanState = NULL;
        }
+       ExecResetTupleTable(node->tuptable, true);
+       node->tuptable = NIL;
+       MemoryContextReset(node->partitionMemoryContext);
 }
 
 /*
@@ -191,7 +229,11 @@ 
MultiExecDynamicBitmapIndexScan(DynamicBitmapIndexScanState *node)
         * Fetch the OID of the current partition, and of the index on
         * that partition to scan.
         */
-       tableOid = DynamicScan_GetTableOid(&node->ss);
+       if (estate->partitionOid > 0) {
+               tableOid = estate->partitionOid;
+       } else {
+               return NULL;
+       }
 
        /*
         * Create the underlying regular BitmapIndexScan executor node,
@@ -214,7 +256,7 @@ void
 ExecEndDynamicBitmapIndexScan(DynamicBitmapIndexScanState *node)
 {
        endCurrentBitmapIndexScan(node);
-
+       node->scan_state = SCAN_END;
        MemoryContextDelete(node->partitionMemoryContext);
 }
 
@@ -231,4 +273,5 @@ ExecReScanDynamicBitmapIndex(DynamicBitmapIndexScanState 
*node)
                ExecEndBitmapIndexScan(node->bitmapIndexScanState);
                node->bitmapIndexScanState = NULL;
        }
+       node->scan_state = SCAN_INIT;
 }
diff --git a/src/backend/gpopt/translate/CTranslatorDXLToPlStmt.cpp 
b/src/backend/gpopt/translate/CTranslatorDXLToPlStmt.cpp
index 425e05f55e..1e9779dc29 100644
--- a/src/backend/gpopt/translate/CTranslatorDXLToPlStmt.cpp
+++ b/src/backend/gpopt/translate/CTranslatorDXLToPlStmt.cpp
@@ -5762,8 +5762,6 @@ CTranslatorDXLToPlStmt::TranslateDXLBitmapTblScan(
        const CDXLNode *bitmapscan_dxlnode, CDXLTranslateContext 
*output_context,
        CDXLTranslationContextArray *ctxt_translation_prev_siblings)
 {
-       ULONG part_index_id = 0;
-       ULONG part_idx_printable_id = 0;
        BOOL is_dynamic = false;
        const CDXLTableDescr *table_descr = nullptr;
 
@@ -5781,9 +5779,6 @@ CTranslatorDXLToPlStmt::TranslateDXLBitmapTblScan(
                        CDXLPhysicalDynamicBitmapTableScan::Cast(dxl_operator);
                table_descr = phy_dyn_bitmap_tblscan_dxlop->GetDXLTableDescr();
 
-               part_index_id = phy_dyn_bitmap_tblscan_dxlop->GetPartIndexId();
-               part_idx_printable_id =
-                       phy_dyn_bitmap_tblscan_dxlop->GetPartIndexIdPrintable();
                is_dynamic = true;
        }
 
@@ -5809,19 +5804,46 @@ CTranslatorDXLToPlStmt::TranslateDXLBitmapTblScan(
 
        m_dxl_to_plstmt_context->AddRTE(rte);
 
+       DynamicBitmapHeapScan *dscan;
        BitmapHeapScan *bitmap_tbl_scan;
 
        if (is_dynamic)
        {
-               DynamicBitmapHeapScan *dscan = MakeNode(DynamicBitmapHeapScan);
+               dscan = MakeNode(DynamicBitmapHeapScan);
+               bitmap_tbl_scan = &dscan->bitmapheapscan;
 
-               // GPDB_12_MERGE_FIXME: broken with the Partition Selector 
refactoring
-#if 0
-               dscan->partIndex = part_index_id;
-               dscan->partIndexPrintable = part_idx_printable_id;
-#endif
+               CDXLPhysicalDynamicBitmapTableScan 
*phy_dyn_bitmap_tblscan_dxlop =
+                       CDXLPhysicalDynamicBitmapTableScan::Cast(dxl_operator);
 
-               bitmap_tbl_scan = &dscan->bitmapheapscan;
+               IMdIdArray *parts = phy_dyn_bitmap_tblscan_dxlop->GetParts();
+
+               List *oids_list = NIL;
+
+               for (ULONG ul = 0; ul < parts->Size(); ul++)
+               {
+                       Oid part = CMDIdGPDB::CastMdid((*parts)[ul])->Oid();
+                       oids_list = gpdb::LAppendOid(oids_list, part);
+               }
+
+               dscan->partOids = oids_list;
+
+               dscan->join_prune_paramids = NIL;
+
+               OID oid_type =
+                       
CMDIdGPDB::CastMdid(m_md_accessor->PtMDType<IMDTypeInt4>()->MDId())
+                               ->Oid();
+
+               const ULongPtrArray *selector_ids =
+                       phy_dyn_bitmap_tblscan_dxlop->GetSelectorIds();
+
+               for (ULONG ul = 0; ul < selector_ids->Size(); ++ul)
+               {
+                       ULONG selector_id = *(*selector_ids)[ul];
+                       ULONG param_id = 
m_dxl_to_plstmt_context->GetParamIdForSelector(
+                               oid_type, selector_id);
+                       dscan->join_prune_paramids =
+                               gpdb::LAppendInt(dscan->join_prune_paramids, 
param_id);
+               }
        }
        else
        {
@@ -5860,6 +5882,10 @@ CTranslatorDXLToPlStmt::TranslateDXLBitmapTblScan(
                &base_table_context, ctxt_translation_prev_siblings, 
bitmap_tbl_scan);
        SetParamIds(plan);
 
+       if (is_dynamic)
+       {
+               return (Plan *) dscan;
+       }
        return (Plan *) bitmap_tbl_scan;
 }
 
@@ -5984,16 +6010,9 @@ CTranslatorDXLToPlStmt::TranslateDXLBitmapIndexProbe(
 
        if (IsA(bitmap_tbl_scan, DynamicBitmapHeapScan))
        {
-               GPOS_RAISE(gpdxl::ExmaDXL, gpdxl::ExmiDXL2PlStmtConversion,
-                                  GPOS_WSZ_LIT("FIXME: dynamic bitmap index 
scan"));
-#if 0
                /* It's a Dynamic Bitmap Index Scan */
                dyn_bitmap_idx_scan = MakeNode(DynamicBitmapIndexScan);
-               dyn_bitmap_idx_scan->partIndex = ((DynamicBitmapHeapScan *) 
bitmap_tbl_scan)->partIndex;
-               dyn_bitmap_idx_scan->partIndexPrintable = 
((DynamicBitmapHeapScan *) bitmap_tbl_scan)->partIndexPrintable;
-
                bitmap_idx_scan = &(dyn_bitmap_idx_scan->biscan);
-#endif
        }
        else
        {
@@ -6036,17 +6055,6 @@ CTranslatorDXLToPlStmt::TranslateDXLBitmapIndexProbe(
         */
        SetParamIds(plan);
 
-#if 0
-       /*
-        * If it's a Dynamic Bitmap Index Scan, also fill in the information
-        * about the indexes on the partitions.
-        */
-       if (dyn_bitmap_idx_scan)
-       {
-               dyn_bitmap_idx_scan->logicalIndexInfo = 
gpdb::GetLogicalIndexInfo(oidRel, index_oid);
-       }
-#endif
-
        return plan;
 }
 
diff --git a/src/backend/gporca/libgpopt/src/translate/CTranslatorExprToDXL.cpp 
b/src/backend/gporca/libgpopt/src/translate/CTranslatorExprToDXL.cpp
index efc6c873a4..a942c22a15 100644
--- a/src/backend/gporca/libgpopt/src/translate/CTranslatorExprToDXL.cpp
+++ b/src/backend/gporca/libgpopt/src/translate/CTranslatorExprToDXL.cpp
@@ -1450,119 +1450,81 @@ CTranslatorExprToDXL::PdxlnDynamicBitmapTableScan(
        CDistributionSpecArray *pdrgpdsBaseTables, CExpression *pexprScalar,
        CDXLPhysicalProperties *dxl_properties)
 {
-       GPOS_ASSERT(nullptr != pexprScan);
+       GPOS_ASSERT(NULL != pexprScan);
+
        CPhysicalDynamicBitmapTableScan *pop =
                CPhysicalDynamicBitmapTableScan::PopConvert(pexprScan->Pop());
+       CColRefArray *pdrgpcrOutput = pop->PdrgpcrOutput();
 
-       // construct projection list
-       CColRefSet *pcrsOutput = pexprScan->Prpp()->PcrsRequired();
-       CDXLNode *pdxlnPrLAppend = PdxlnProjList(pcrsOutput, colref_array);
-
-       CDXLNode *pdxlnResult = GPOS_NEW(m_mp)
-               CDXLNode(m_mp, GPOS_NEW(m_mp) CDXLPhysicalAppend(m_mp, false, 
false));
-       // GPDB_12_MERGE_FIXME: set plan costs
-       pdxlnResult->SetProperties(dxl_properties);
-       pdxlnResult->AddChild(pdxlnPrLAppend);
-       pdxlnResult->AddChild(PdxlnFilter(nullptr));
+       CDXLTableDescr *table_descr =
+               MakeDXLTableDescr(pop->Ptabdesc(), pdrgpcrOutput, 
pexprScan->Prpp());
 
+       // construct dynamic table scan operator
        IMdIdArray *part_mdids = pop->GetPartitionMdids();
+       part_mdids->AddRef();
 
-       
COptCtxt::PoctxtFromTLS()->AddDirectDispatchableFilterCandidate(pexprScan);
-
-       for (ULONG ul = 0; ul < part_mdids->Size(); ++ul)
+       ULongPtrArray *selector_ids = GPOS_NEW(m_mp) ULongPtrArray(m_mp);
+       CPartitionPropagationSpec *pps_reqd =
+               pexprScan->Prpp()->Pepp()->PppsRequired();
+       if (pps_reqd->Contains(pop->ScanId()))
        {
-               IMDId *part_mdid = (*part_mdids)[ul];
-               const IMDRelation *part = m_pmda->RetrieveRel(part_mdid);
-
-               // translate table descriptor
-               CTableDescriptor *part_tabdesc =
-                       MakeTableDescForPart(part, 
pexprScan->DeriveTableDescriptor());
-
-               // Create new colrefs for the child partition. The ColRefs from 
root
-               // DTS, which may be used in any parent node, can no longer be 
exported
-               // by a child of the Append node. Thus it is exported by the 
Append
-               // node itself, and new colrefs are created here.
-               CColRefArray *part_colrefs = GPOS_NEW(m_mp) CColRefArray(m_mp);
-               for (ULONG ul = 0; ul < part_tabdesc->ColumnCount(); ++ul)
-               {
-                       const CColumnDescriptor *cd = 
part_tabdesc->Pcoldesc(ul);
-                       CColRef *cr = m_pcf->PcrCreate(cd->RetrieveType(),
-                                                                               
   cd->TypeModifier(), cd->Name());
-                       part_colrefs->Append(cr);
-               }
-
-               CDXLTableDescr *dxl_table_descr =
-                       MakeDXLTableDescr(part_tabdesc, part_colrefs, 
pexprScan->Prpp());
-               part_tabdesc->Release();
-
-               CDXLNode *pdxlnBitmapTableScan = GPOS_NEW(m_mp) CDXLNode(
-                       m_mp,
-                       GPOS_NEW(m_mp) CDXLPhysicalBitmapTableScan(m_mp, 
dxl_table_descr));
-
-               // set properties
-               // construct plan costs, if there are not passed as a parameter
-               if (nullptr == dxl_properties)
+               const CBitSet *bs = pps_reqd->SelectorIds(pop->ScanId());
+               CBitSetIter bsi(*bs);
+               for (ULONG ul = 0; bsi.Advance(); ul++)
                {
-                       dxl_properties = GetProperties(pexprScan);
+                       selector_ids->Append(GPOS_NEW(m_mp) ULONG(bsi.Bit()));
                }
-               dxl_properties->AddRef();
-               pdxlnBitmapTableScan->SetProperties(dxl_properties);
+       }
 
-               // build projection list
-               auto *root_col_mapping = (*pop->GetRootColMappingPerPart())[ul];
+       CDXLPhysicalDynamicBitmapTableScan *pdxlopScan =
+               GPOS_NEW(m_mp) CDXLPhysicalDynamicBitmapTableScan(
+                       m_mp, table_descr, part_mdids, selector_ids);
 
-               // translate scalar predicate into DXL filter only if it is not 
redundant
-               CExpression *pexprRecheckCond = (*pexprScan)[0];
-               CDXLNode *pdxlnCond = nullptr;
-               if (nullptr != pexprScalar && 
!CUtils::FScalarConstTrue(pexprScalar) &&
-                       !pexprScalar->Matches(pexprRecheckCond))
-               {
-                       pdxlnCond =
-                               PdxlnCondForChildPart(root_col_mapping, 
part_colrefs,
-                                                                         
pop->PdrgpcrOutput(), pexprScalar);
-               }
+       CDXLNode *pdxlnScan = GPOS_NEW(m_mp) CDXLNode(m_mp, pdxlopScan);
 
-               CDXLNode *filter_dxlnode = PdxlnFilter(pdxlnCond);
+       // construct plan costs
+       if (NULL == dxl_properties)
+       {
+               dxl_properties = GetProperties(pexprScan);
+       }
+       pdxlnScan->SetProperties(dxl_properties);
 
-               CDXLNode *pdxlnRecheckCond =
-                       PdxlnCondForChildPart(root_col_mapping, part_colrefs,
-                                                                 
pop->PdrgpcrOutput(), pexprRecheckCond);
-               CDXLNode *pdxlnRecheckCondFilter = GPOS_NEW(m_mp)
-                       CDXLNode(m_mp, GPOS_NEW(m_mp) 
CDXLScalarRecheckCondFilter(m_mp),
-                                        pdxlnRecheckCond);
+       // translate predicates into DXL filter
+       CDXLNode *pdxlnCond = NULL;
+       if (NULL != pexprScalar)
+       {
+               pdxlnCond = PdxlnScalar(pexprScalar);
+       }
+       CDXLNode *filter_dxlnode = PdxlnFilter(pdxlnCond);
 
-               AddBitmapFilterColumns(m_mp, pop, pexprRecheckCond, pexprScalar,
-                                                          pcrsOutput);
+       CExpression *pexprRecheckCond = (*pexprScan)[0];
+       CDXLNode *pdxlnRecheckCond = PdxlnScalar(pexprRecheckCond);
+       CDXLNode *pdxlnRecheckCondFilter = GPOS_NEW(m_mp)
+               CDXLNode(m_mp, GPOS_NEW(m_mp) 
CDXLScalarRecheckCondFilter(m_mp));
+       pdxlnRecheckCondFilter->AddChild(pdxlnRecheckCond);
 
-               CDXLNode *proj_list_dxlnode = PdxlnProjListForChildPart(
-                       root_col_mapping, part_colrefs, pcrsOutput, 
colref_array);
+       // translate bitmap access path
+       CDXLNode *pdxlnBitmapAccessPath = PdxlnScalar((*pexprScan)[1]);
 
-               // translate bitmap access path
-               CExpression *pexprBitmapIndexPath = (*pexprScan)[1];
+       // build projection list
+       CColRefSet *pcrsOutput = pexprScan->Prpp()->PcrsRequired();
+       CDXLNode *proj_list_dxlnode = PdxlnProjList(pcrsOutput, colref_array);
 
-               CDXLNode *pdxlnBitmapIndexPath = 
PdxlnBitmapIndexPathForChildPart(
-                       root_col_mapping, part_colrefs, pop->PdrgpcrOutput(), 
part,
-                       pexprBitmapIndexPath);
+       pdxlnScan->AddChild(proj_list_dxlnode);
+       pdxlnScan->AddChild(filter_dxlnode);
+       pdxlnScan->AddChild(pdxlnRecheckCondFilter);
+       pdxlnScan->AddChild(pdxlnBitmapAccessPath);
 
-               pdxlnBitmapTableScan->AddChild(proj_list_dxlnode);
-               pdxlnBitmapTableScan->AddChild(filter_dxlnode);
-               pdxlnBitmapTableScan->AddChild(pdxlnRecheckCondFilter);
-               pdxlnBitmapTableScan->AddChild(pdxlnBitmapIndexPath);
 #ifdef GPOS_DEBUG
-               pdxlnBitmapTableScan->GetOperator()->AssertValid(
-                       pdxlnBitmapTableScan, false /*validate_children*/);
+       pdxlnScan->GetOperator()->AssertValid(pdxlnScan,
+                                                                               
  false /* validate_children */);
 #endif
 
-               pdxlnResult->AddChild(pdxlnBitmapTableScan);
-
-               // cleanup
-               part_colrefs->Release();
-       }
-
        CDistributionSpec *pds = pexprScan->GetDrvdPropPlan()->Pds();
        pds->AddRef();
        pdrgpdsBaseTables->Append(pds);
-       return pdxlnResult;
+
+       return pdxlnScan;
 }
 
 //---------------------------------------------------------------------------
diff --git 
a/src/backend/gporca/libnaucrates/include/naucrates/dxl/operators/CDXLPhysicalDynamicBitmapTableScan.h
 
b/src/backend/gporca/libnaucrates/include/naucrates/dxl/operators/CDXLPhysicalDynamicBitmapTableScan.h
index 6f8498c3b3..b615071d99 100644
--- 
a/src/backend/gporca/libnaucrates/include/naucrates/dxl/operators/CDXLPhysicalDynamicBitmapTableScan.h
+++ 
b/src/backend/gporca/libnaucrates/include/naucrates/dxl/operators/CDXLPhysicalDynamicBitmapTableScan.h
@@ -35,11 +35,9 @@ class CXMLSerializer;
 class CDXLPhysicalDynamicBitmapTableScan : public 
CDXLPhysicalAbstractBitmapScan
 {
 private:
-       // id of partition index structure
-       ULONG m_part_index_id;
+       IMdIdArray *m_part_mdids;
 
-       // printable partition index id
-       ULONG m_part_index_id_printable;
+       ULongPtrArray *m_selector_ids = nullptr;
 
 public:
        CDXLPhysicalDynamicBitmapTableScan(
@@ -48,17 +46,17 @@ public:
        // ctor
        CDXLPhysicalDynamicBitmapTableScan(CMemoryPool *mp,
                                                                           
CDXLTableDescr *table_descr,
-                                                                          
ULONG part_idx_id,
-                                                                          
ULONG part_idx_id_printable)
+                                                                          
IMdIdArray *part_mdids,
+                                                                          
ULongPtrArray *selector_ids)
                : CDXLPhysicalAbstractBitmapScan(mp, table_descr),
-                 m_part_index_id(part_idx_id),
-                 m_part_index_id_printable(part_idx_id_printable)
+                 m_part_mdids(part_mdids),
+                 m_selector_ids(selector_ids)
        {
                GPOS_ASSERT(nullptr != table_descr);
        }
 
        // dtor
-       ~CDXLPhysicalDynamicBitmapTableScan() override = default;
+       ~CDXLPhysicalDynamicBitmapTableScan() override;
 
        // operator type
        Edxlopid
@@ -70,18 +68,12 @@ public:
        // operator name
        const CWStringConst *GetOpNameStr() const override;
 
-       // partition index id
-       ULONG
-       GetPartIndexId() const
-       {
-               return m_part_index_id;
-       }
+       IMdIdArray *GetParts() const;
 
-       // printable partition index id
-       ULONG
-       GetPartIndexIdPrintable() const
+       const ULongPtrArray *
+       GetSelectorIds() const
        {
-               return m_part_index_id_printable;
+               return m_selector_ids;
        }
 
        // serialize operator in DXL format
diff --git 
a/src/backend/gporca/libnaucrates/include/naucrates/dxl/parser/CParseHandlerPhysicalAbstractBitmapScan.h
 
b/src/backend/gporca/libnaucrates/include/naucrates/dxl/parser/CParseHandlerPhysicalAbstractBitmapScan.h
index 4b8b4c2399..83787b2041 100644
--- 
a/src/backend/gporca/libnaucrates/include/naucrates/dxl/parser/CParseHandlerPhysicalAbstractBitmapScan.h
+++ 
b/src/backend/gporca/libnaucrates/include/naucrates/dxl/parser/CParseHandlerPhysicalAbstractBitmapScan.h
@@ -41,8 +41,8 @@ protected:
 
        // common EndElement functionality for child classes
        void EndElementHelper(const XMLCh *const element_local_name,
-                                                 Edxltoken token_type, ULONG 
part_idx_id = 0,
-                                                 ULONG part_idx_id_printable = 
0);
+                                                 Edxltoken token_type,
+                                                 ULongPtrArray *selector_ids = 
nullptr);
 
 public:
        CParseHandlerPhysicalAbstractBitmapScan(
diff --git 
a/src/backend/gporca/libnaucrates/include/naucrates/dxl/parser/CParseHandlerPhysicalDynamicBitmapTableScan.h
 
b/src/backend/gporca/libnaucrates/include/naucrates/dxl/parser/CParseHandlerPhysicalDynamicBitmapTableScan.h
index 43ea094a75..25c547b058 100644
--- 
a/src/backend/gporca/libnaucrates/include/naucrates/dxl/parser/CParseHandlerPhysicalDynamicBitmapTableScan.h
+++ 
b/src/backend/gporca/libnaucrates/include/naucrates/dxl/parser/CParseHandlerPhysicalDynamicBitmapTableScan.h
@@ -35,11 +35,7 @@ class CParseHandlerPhysicalDynamicBitmapTableScan
        : public CParseHandlerPhysicalAbstractBitmapScan
 {
 private:
-       // part index id
-       ULONG m_part_index_id;
-
-       // printable partition index id
-       ULONG m_part_index_id_printable;
+       ULongPtrArray *m_selector_ids;
 
        // process the start of an element
        void StartElement(
@@ -65,9 +61,7 @@ public:
                CMemoryPool *mp, CParseHandlerManager *parse_handler_mgr,
                CParseHandlerBase *parse_handler_root)
                : CParseHandlerPhysicalAbstractBitmapScan(mp, parse_handler_mgr,
-                                                                               
                  parse_handler_root),
-                 m_part_index_id(0),
-                 m_part_index_id_printable(0)
+                                                                               
                  parse_handler_root)
        {
        }
 };
diff --git 
a/src/backend/gporca/libnaucrates/src/operators/CDXLPhysicalDynamicBitmapTableScan.cpp
 
b/src/backend/gporca/libnaucrates/src/operators/CDXLPhysicalDynamicBitmapTableScan.cpp
index d0dd3c5313..1a0e01caee 100644
--- 
a/src/backend/gporca/libnaucrates/src/operators/CDXLPhysicalDynamicBitmapTableScan.cpp
+++ 
b/src/backend/gporca/libnaucrates/src/operators/CDXLPhysicalDynamicBitmapTableScan.cpp
@@ -11,10 +11,12 @@
 
 #include "naucrates/dxl/operators/CDXLPhysicalDynamicBitmapTableScan.h"
 
+#include "naucrates/dxl/CDXLUtils.h"
 #include "naucrates/dxl/operators/CDXLNode.h"
 #include "naucrates/dxl/operators/CDXLTableDescr.h"
 #include "naucrates/dxl/xml/CXMLSerializer.h"
 #include "naucrates/dxl/xml/dxltokens.h"
+#include "naucrates/md/IMDCacheObject.h"
 
 using namespace gpdxl;
 using namespace gpos;
@@ -33,6 +35,18 @@ CDXLPhysicalDynamicBitmapTableScan::GetOpNameStr() const
        return 
CDXLTokens::GetDXLTokenStr(EdxltokenPhysicalDynamicBitmapTableScan);
 }
 
+IMdIdArray *
+CDXLPhysicalDynamicBitmapTableScan::GetParts() const
+{
+       return m_part_mdids;
+}
+
+CDXLPhysicalDynamicBitmapTableScan::~CDXLPhysicalDynamicBitmapTableScan()
+{
+       m_part_mdids->Release();
+       CRefCount::SafeRelease(m_selector_ids);
+}
+
 //---------------------------------------------------------------------------
 //     @function:
 //             CDXLPhysicalDynamicBitmapTableScan::SerializeToDXL
@@ -49,16 +63,18 @@ CDXLPhysicalDynamicBitmapTableScan::SerializeToDXL(
        xml_serializer->OpenElement(
                CDXLTokens::GetDXLTokenStr(EdxltokenNamespacePrefix), 
element_name);
 
+       CWStringDynamic *serialized_selector_ids =
+               CDXLUtils::Serialize(m_mp, m_selector_ids);
        xml_serializer->AddAttribute(
-               CDXLTokens::GetDXLTokenStr(EdxltokenPartIndexId), 
m_part_index_id);
-       if (m_part_index_id_printable != m_part_index_id)
-       {
-               xml_serializer->AddAttribute(
-                       
CDXLTokens::GetDXLTokenStr(EdxltokenPartIndexIdPrintable),
-                       m_part_index_id_printable);
-       }
+               CDXLTokens::GetDXLTokenStr(EdxltokenSelectorIds),
+               serialized_selector_ids);
+       GPOS_DELETE(serialized_selector_ids);
        node->SerializePropertiesToDXL(xml_serializer);
        node->SerializeChildrenToDXL(xml_serializer);
+       IMDCacheObject::SerializeMDIdList(
+               xml_serializer, m_part_mdids,
+               CDXLTokens::GetDXLTokenStr(EdxltokenPartitions),
+               CDXLTokens::GetDXLTokenStr(EdxltokenPartition));
        m_dxl_table_descr->SerializeToDXL(xml_serializer);
 
        xml_serializer->CloseElement(
diff --git 
a/src/backend/gporca/libnaucrates/src/parser/CParseHandlerPhysicalAbstractBitmapScan.cpp
 
b/src/backend/gporca/libnaucrates/src/parser/CParseHandlerPhysicalAbstractBitmapScan.cpp
index 3b18e63e44..85f681c7e5 100644
--- 
a/src/backend/gporca/libnaucrates/src/parser/CParseHandlerPhysicalAbstractBitmapScan.cpp
+++ 
b/src/backend/gporca/libnaucrates/src/parser/CParseHandlerPhysicalAbstractBitmapScan.cpp
@@ -16,6 +16,7 @@
 #include "naucrates/dxl/operators/CDXLPhysicalDynamicBitmapTableScan.h"
 #include "naucrates/dxl/parser/CParseHandlerFactory.h"
 #include "naucrates/dxl/parser/CParseHandlerFilter.h"
+#include "naucrates/dxl/parser/CParseHandlerMetadataIdList.h"
 #include "naucrates/dxl/parser/CParseHandlerPhysicalBitmapTableScan.h"
 #include "naucrates/dxl/parser/CParseHandlerPhysicalDynamicBitmapTableScan.h"
 #include "naucrates/dxl/parser/CParseHandlerProjList.h"
@@ -56,6 +57,16 @@ CParseHandlerPhysicalAbstractBitmapScan::StartElementHelper(
                        m_parse_handler_mgr, this);
        m_parse_handler_mgr->ActivateParseHandler(table_descr_parse_handler);
 
+       CParseHandlerBase *partition_mdids_parse_handler = nullptr;
+       if (EdxltokenPhysicalDynamicBitmapTableScan == token_type)
+       {
+               partition_mdids_parse_handler = 
CParseHandlerFactory::GetParseHandler(
+                       m_mp, CDXLTokens::XmlstrToken(EdxltokenMetadataIdList),
+                       m_parse_handler_mgr, this);
+               m_parse_handler_mgr->ActivateParseHandler(
+                       partition_mdids_parse_handler);
+       }
+
        // parse handler for the bitmap access path
        CParseHandlerBase *bitmap_parse_handler =
                CParseHandlerFactory::GetParseHandler(
@@ -97,6 +108,10 @@ CParseHandlerPhysicalAbstractBitmapScan::StartElementHelper(
        this->Append(filter_parse_handler);
        this->Append(recheck_cond_parse_handler);
        this->Append(bitmap_parse_handler);
+       if (EdxltokenPhysicalDynamicBitmapTableScan == token_type)
+       {
+               this->Append(partition_mdids_parse_handler);
+       }
        this->Append(table_descr_parse_handler);
 }
 
@@ -111,7 +126,7 @@ CParseHandlerPhysicalAbstractBitmapScan::StartElementHelper(
 void
 CParseHandlerPhysicalAbstractBitmapScan::EndElementHelper(
        const XMLCh *const element_local_name, Edxltoken token_type,
-       ULONG part_idx_id, ULONG part_idx_id_printable)
+       ULongPtrArray *selector_ids)
 {
        if (0 != XMLString::compareString(CDXLTokens::XmlstrToken(token_type),
                                                                          
element_local_name))
@@ -122,19 +137,26 @@ CParseHandlerPhysicalAbstractBitmapScan::EndElementHelper(
                                   str->GetBuffer());
        }
 
+       int i = 0;
        // construct nodes from the created child nodes
        CParseHandlerProperties *prop_parse_handler =
-               dynamic_cast<CParseHandlerProperties *>((*this)[0]);
+               dynamic_cast<CParseHandlerProperties *>((*this)[i++]);
        CParseHandlerProjList *proj_list_parse_handler =
-               dynamic_cast<CParseHandlerProjList *>((*this)[1]);
+               dynamic_cast<CParseHandlerProjList *>((*this)[i++]);
        CParseHandlerFilter *filter_parse_handler =
-               dynamic_cast<CParseHandlerFilter *>((*this)[2]);
+               dynamic_cast<CParseHandlerFilter *>((*this)[i++]);
        CParseHandlerFilter *recheck_cond_parse_handler =
-               dynamic_cast<CParseHandlerFilter *>((*this)[3]);
+               dynamic_cast<CParseHandlerFilter *>((*this)[i++]);
        CParseHandlerScalarOp *bitmap_parse_handler =
-               dynamic_cast<CParseHandlerScalarOp *>((*this)[4]);
+               dynamic_cast<CParseHandlerScalarOp *>((*this)[i++]);
+       CParseHandlerMetadataIdList *partition_mdids_parse_handler = nullptr;
+       if (EdxltokenPhysicalDynamicBitmapTableScan == token_type)
+       {
+               partition_mdids_parse_handler =
+                       dynamic_cast<CParseHandlerMetadataIdList 
*>((*this)[i++]);
+       }
        CParseHandlerTableDescr *table_descr_parse_handler =
-               dynamic_cast<CParseHandlerTableDescr *>((*this)[5]);
+               dynamic_cast<CParseHandlerTableDescr *>((*this)[i++]);
 
        GPOS_ASSERT(nullptr != table_descr_parse_handler->GetDXLTableDescr());
 
@@ -150,8 +172,11 @@ CParseHandlerPhysicalAbstractBitmapScan::EndElementHelper(
        else
        {
                GPOS_ASSERT(EdxltokenPhysicalDynamicBitmapTableScan == 
token_type);
+               IMdIdArray *mdid_partitions_array =
+                       partition_mdids_parse_handler->GetMdIdArray();
+               mdid_partitions_array->AddRef();
                dxl_op = GPOS_NEW(m_mp) CDXLPhysicalDynamicBitmapTableScan(
-                       m_mp, table_descr, part_idx_id, part_idx_id_printable);
+                       m_mp, table_descr, mdid_partitions_array, selector_ids);
        }
        m_dxl_node = GPOS_NEW(m_mp) CDXLNode(m_mp, dxl_op);
 
diff --git 
a/src/backend/gporca/libnaucrates/src/parser/CParseHandlerPhysicalBitmapTableScan.cpp
 
b/src/backend/gporca/libnaucrates/src/parser/CParseHandlerPhysicalBitmapTableScan.cpp
index 9bb5fa699c..73f7c9ff9f 100644
--- 
a/src/backend/gporca/libnaucrates/src/parser/CParseHandlerPhysicalBitmapTableScan.cpp
+++ 
b/src/backend/gporca/libnaucrates/src/parser/CParseHandlerPhysicalBitmapTableScan.cpp
@@ -49,5 +49,6 @@ CParseHandlerPhysicalBitmapTableScan::EndElement(
        const XMLCh *const      // element_qname
 )
 {
-       EndElementHelper(element_local_name, EdxltokenPhysicalBitmapTableScan);
+       EndElementHelper(element_local_name, EdxltokenPhysicalBitmapTableScan,
+                                        nullptr);
 }
diff --git 
a/src/backend/gporca/libnaucrates/src/parser/CParseHandlerPhysicalDynamicBitmapTableScan.cpp
 
b/src/backend/gporca/libnaucrates/src/parser/CParseHandlerPhysicalDynamicBitmapTableScan.cpp
index 49f9def6ae..17dcc49cf3 100644
--- 
a/src/backend/gporca/libnaucrates/src/parser/CParseHandlerPhysicalDynamicBitmapTableScan.cpp
+++ 
b/src/backend/gporca/libnaucrates/src/parser/CParseHandlerPhysicalDynamicBitmapTableScan.cpp
@@ -32,17 +32,10 @@ CParseHandlerPhysicalDynamicBitmapTableScan::StartElement(
 {
        StartElementHelper(element_local_name,
                                           
EdxltokenPhysicalDynamicBitmapTableScan);
-       m_part_index_id = CDXLOperatorFactory::ExtractConvertAttrValueToUlong(
-               m_parse_handler_mgr->GetDXLMemoryManager(), attrs, 
EdxltokenPartIndexId,
-               EdxltokenPhysicalDynamicBitmapTableScan);
 
-       m_part_index_id_printable =
-               CDXLOperatorFactory::ExtractConvertAttrValueToUlong(
-                       m_parse_handler_mgr->GetDXLMemoryManager(), attrs,
-                       EdxltokenPartIndexIdPrintable,
-                       EdxltokenPhysicalDynamicBitmapTableScan,
-                       true,  //is_optional
-                       m_part_index_id);
+       m_selector_ids = CDXLOperatorFactory::ExtractConvertValuesToArray(
+               m_parse_handler_mgr->GetDXLMemoryManager(), attrs, 
EdxltokenSelectorIds,
+               EdxltokenPhysicalDynamicTableScan);
 }
 
 //---------------------------------------------------------------------------
@@ -61,8 +54,7 @@ CParseHandlerPhysicalDynamicBitmapTableScan::EndElement(
 )
 {
        EndElementHelper(element_local_name,
-                                        
EdxltokenPhysicalDynamicBitmapTableScan, m_part_index_id,
-                                        m_part_index_id_printable);
+                                        
EdxltokenPhysicalDynamicBitmapTableScan, m_selector_ids);
 }
 
 // EOF
diff --git a/src/include/executor/nodeDynamicBitmapHeapscan.h 
b/src/include/executor/nodeDynamicBitmapHeapscan.h
index b12954cf66..45c48ade8d 100644
--- a/src/include/executor/nodeDynamicBitmapHeapscan.h
+++ b/src/include/executor/nodeDynamicBitmapHeapscan.h
@@ -16,12 +16,9 @@
 
 #include "nodes/execnodes.h"
 
-/* GPDB_12_MERGE_FIXME */
-#if 0
 extern DynamicBitmapHeapScanState 
*ExecInitDynamicBitmapHeapScan(DynamicBitmapHeapScan *node, EState *estate, int 
eflags);
-extern TupleTableSlot *ExecDynamicBitmapHeapScan(DynamicBitmapHeapScanState 
*node);
+extern TupleTableSlot *ExecDynamicBitmapHeapScan(PlanState *pstate);
 extern void ExecEndDynamicBitmapHeapScan(DynamicBitmapHeapScanState *node);
 extern void ExecReScanDynamicBitmapHeapScan(DynamicBitmapHeapScanState *node);
-#endif
 
 #endif
diff --git a/src/include/executor/nodeDynamicBitmapIndexscan.h 
b/src/include/executor/nodeDynamicBitmapIndexscan.h
index 7faa624a97..0de904ef40 100644
--- a/src/include/executor/nodeDynamicBitmapIndexscan.h
+++ b/src/include/executor/nodeDynamicBitmapIndexscan.h
@@ -16,12 +16,9 @@
 
 #include "nodes/execnodes.h"
 
-/* GPDB_12_MERGE_FIXME */
-#if 0
 extern DynamicBitmapIndexScanState 
*ExecInitDynamicBitmapIndexScan(DynamicBitmapIndexScan *node, EState *estate, 
int eflags);
 extern Node *MultiExecDynamicBitmapIndexScan(DynamicBitmapIndexScanState 
*node);
 extern void ExecEndDynamicBitmapIndexScan(DynamicBitmapIndexScanState *node);
 extern void ExecReScanDynamicBitmapIndex(DynamicBitmapIndexScanState *node);
-#endif
 
 #endif   /* NODEDYNAMICBITMAPINDEXSCAN_H */


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]


Reply via email to