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 2617770361b6b1c8c804dec78040e15301a0d49b
Author: Chris Hajas <[email protected]>
AuthorDate: Mon May 23 14:51:47 2022 -0700

    Adds Orca support for Dynamic Index Scan
---
 src/backend/executor/nodeDynamicIndexscan.c        | 176 +++++++-------------
 src/backend/executor/nodeIndexscan.c               |  39 +++--
 .../gpopt/translate/CTranslatorDXLToPlStmt.cpp     | 136 +++++++++++++++-
 .../src/translate/CTranslatorExprToDXL.cpp         | 179 ++++++++-------------
 .../dxl/operators/CDXLPhysicalDynamicIndexScan.h   |  29 ++--
 .../dxl/parser/CParseHandlerDynamicIndexScan.h     |   6 +-
 .../naucrates/dxl/parser/CParseHandlerIndexScan.h  |   4 +-
 .../src/operators/CDXLPhysicalDynamicIndexScan.cpp |  62 +++----
 .../src/operators/CDXLPhysicalIndexScan.cpp        |   7 +
 .../src/parser/CParseHandlerDynamicIndexScan.cpp   |  15 +-
 .../src/parser/CParseHandlerIndexOnlyScan.cpp      |   3 +-
 .../src/parser/CParseHandlerIndexScan.cpp          |  24 ++-
 src/include/executor/nodeDynamicIndexscan.h        |   6 +-
 .../gpopt/translate/CTranslatorDXLToPlStmt.h       |  12 +-
 14 files changed, 360 insertions(+), 338 deletions(-)

diff --git a/src/backend/executor/nodeDynamicIndexscan.c 
b/src/backend/executor/nodeDynamicIndexscan.c
index 2fcad60607..5115fa9d9c 100644
--- a/src/backend/executor/nodeDynamicIndexscan.c
+++ b/src/backend/executor/nodeDynamicIndexscan.c
@@ -20,17 +20,17 @@
 
 #include "postgres.h"
 
-#include "cdb/cdbvars.h"
-#include "cdb/partitionselection.h"
-#include "executor/execDynamicScan.h"
+#include "catalog/partition.h"
 #include "executor/executor.h"
 #include "executor/instrument.h"
 #include "nodes/execnodes.h"
+#include "executor/execPartition.h"
 #include "executor/nodeIndexscan.h"
 #include "executor/nodeDynamicIndexscan.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 DynamicIndexScan.
@@ -39,6 +39,8 @@ DynamicIndexScanState *
 ExecInitDynamicIndexScan(DynamicIndexScan *node, EState *estate, int eflags)
 {
        DynamicIndexScanState *dynamicIndexScanState;
+       ListCell *lc;
+       int i;
 
        /* check for unsupported flags */
        Assert(!(eflags & (EXEC_FLAG_BACKWARD | EXEC_FLAG_MARK)));
@@ -46,9 +48,15 @@ ExecInitDynamicIndexScan(DynamicIndexScan *node, EState 
*estate, int eflags)
        dynamicIndexScanState = makeNode(DynamicIndexScanState);
        dynamicIndexScanState->ss.ps.plan = (Plan *) node;
        dynamicIndexScanState->ss.ps.state = estate;
+       dynamicIndexScanState->ss.ps.ExecProcNode = ExecDynamicIndexScan;
        dynamicIndexScanState->eflags = eflags;
 
        dynamicIndexScanState->scan_state = SCAN_INIT;
+       dynamicIndexScanState->whichPart = -1;
+       dynamicIndexScanState->nOids = list_length(node->partOids);
+       dynamicIndexScanState->partOids = palloc(sizeof(Oid) * 
dynamicIndexScanState->nOids);
+       foreach_with_count(lc, node->partOids, i)
+               dynamicIndexScanState->partOids[i] = lfirst_oid(lc);
 
        /*
         * Initialize child expressions
@@ -57,24 +65,19 @@ ExecInitDynamicIndexScan(DynamicIndexScan *node, EState 
*estate, int eflags)
         * to do all evaluation for us. But I think this is still needed to
         * find and process any SubPlans. See comment in ExecInitIndexScan.
         */
-       dynamicIndexScanState->ss.ps.targetlist = (List *)
-               ExecInitExpr((Expr *) node->indexscan.scan.plan.targetlist,
+       dynamicIndexScanState->ss.ps.qual = 
ExecInitQual(node->indexscan.scan.plan.qual,
                                         (PlanState *) dynamicIndexScanState);
-       dynamicIndexScanState->ss.ps.qual = (List *)
-               ExecInitExpr((Expr *) node->indexscan.scan.plan.qual,
-                                        (PlanState *) dynamicIndexScanState);
-       (void) ExecInitExpr((Expr *) node->indexscan.indexqualorig,
-                                               (PlanState *) 
dynamicIndexScanState);
 
        /*
         * tuple table initialization
         */
-       ExecInitResultTupleSlot(estate, &dynamicIndexScanState->ss.ps);
+       Relation scanRel = ExecOpenScanRelation(estate, 
node->indexscan.scan.scanrelid, eflags);
+       ExecInitScanTupleSlot(estate, &dynamicIndexScanState->ss, 
RelationGetDescr(scanRel), table_slot_callbacks(scanRel));
 
        /*
         * Initialize result tuple type and projection info.
         */
-       ExecAssignResultTypeFromTL(&dynamicIndexScanState->ss.ps);
+       ExecInitResultTypeTL(&dynamicIndexScanState->ss.ps);
 
        /*
         * This context will be reset per-partition to free up per-partition
@@ -110,9 +113,6 @@ DynamicIndexScan_ReMapColumns(DynamicIndexScan *dIndexScan, 
Oid oldOid, Oid newO
 
        if (attMap)
        {
-               IndexScan_MapLogicalIndexInfo(dIndexScan->logicalIndexInfo, 
attMap,
-                                                                         
indexScan->scan.scanrelid);
-
                /* Also map attrnos in targetlist and quals */
                change_varattnos_of_a_varno((Node *) 
indexScan->scan.plan.targetlist,
                                                                        attMap, 
indexScan->scan.scanrelid);
@@ -144,7 +144,8 @@ beginCurrentIndexScan(DynamicIndexScanState *node, EState 
*estate,
        /*
         * open the base relation and acquire appropriate lock on it.
         */
-       currentRelation = heap_open(tableOid, AccessShareLock);
+       currentRelation = table_open(tableOid, AccessShareLock);
+       node->ss.ss_currentRelation = currentRelation;
 
        save_tupletable = estate->es_tupleTable;
        estate->es_tupleTable = NIL;
@@ -157,18 +158,18 @@ beginCurrentIndexScan(DynamicIndexScanState *node, EState 
*estate,
        if (!OidIsValid(node->columnLayoutOid))
        {
                /* Very first partition */
-               node->columnLayoutOid = rel_partition_get_root(tableOid);
+               // Just get the direct parent, we don't support multi-level 
partitioning
+               node->columnLayoutOid = get_partition_parent(tableOid);
        }
        DynamicIndexScan_ReMapColumns(dynamicIndexScan,
-                                                                 
node->columnLayoutOid, tableOid);
+                                                                 tableOid, 
node->columnLayoutOid);
        node->columnLayoutOid = tableOid;
 
-       indexOid = getPhysicalIndexRelid(currentRelation, 
dynamicIndexScan->logicalIndexInfo);
+       indexOid = index_get_partition(currentRelation, 
dynamicIndexScan->indexscan.indexid);
        if (!OidIsValid(indexOid))
                elog(ERROR, "failed to find index for partition \"%s\" in 
dynamic index scan",
                         RelationGetRelationName(currentRelation));
 
-       DynamicScan_SetTableOid(&node->ss, tableOid);
        node->indexScanState = 
ExecInitIndexScanForPartition(&dynamicIndexScan->indexscan, estate,
                                                                                
                                 node->eflags,
                                                                                
                                 currentRelation, indexOid);
@@ -188,6 +189,7 @@ endCurrentIndexScan(DynamicIndexScanState *node)
        {
                ExecEndIndexScan(node->indexScanState);
                node->indexScanState = NULL;
+               table_close(node->ss.ss_currentRelation, NoLock);
        }
        ExecResetTupleTable(node->tuptable, true);
        node->tuptable = NIL;
@@ -208,16 +210,10 @@ initNextIndexToScan(DynamicIndexScanState *node)
        {
                /* This is the oid of a partition of the table (*not* index) */
                Oid                     tableOid;
-               Oid                *pid;
-
-               pid = hash_seq_search(&node->pidxStatus);
-               if (pid == NULL)
-               {
-                       /* Return if all parts have been scanned. */
-                       node->shouldCallHashSeqTerm = false;
+               if (++node->whichPart < node->nOids)
+                       tableOid = node->partOids[node->whichPart];
+               else
                        return false;
-               }
-               tableOid = *pid;
 
                /* Collect number of partitions scanned in EXPLAIN ANALYZE */
                if (node->ss.ps.instrument)
@@ -233,53 +229,40 @@ initNextIndexToScan(DynamicIndexScanState *node)
        return true;
 }
 
-/*
- * setPidIndex
- *   Set the hash table of Oids to scan.
- */
-static void
-setPidIndex(DynamicIndexScanState *node)
-{
-       IndexScanState *indexState = (IndexScanState *)node;
-       DynamicIndexScan *plan = (DynamicIndexScan *) indexState->ss.ps.plan;
-       EState     *estate = indexState->ss.ps.state;
-       int                     partIndex = plan->partIndex;
-
-       Assert(node->pidxIndex == NULL);
-       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, partIndex,
-                                                                         
InvalidOid, InvalidPartitionSelectorId);
-
-       Assert(NULL != estate->dynamicTableScanInfo->pidIndexes);
-       Assert(estate->dynamicTableScanInfo->numScans >= partIndex);
-       node->pidxIndex = estate->dynamicTableScanInfo->pidIndexes[partIndex - 
1];
-       Assert(node->pidxIndex != NULL);
-}
-
 /*
  * Execution of DynamicIndexScan
  */
 TupleTableSlot *
-ExecDynamicIndexScan(DynamicIndexScanState *node)
+ExecDynamicIndexScan(PlanState *pstate)
 {
+       DynamicIndexScanState *node = castNode(DynamicIndexScanState, 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->pidxIndex == NULL)
+       DynamicIndexScan           *plan = (DynamicIndexScan *) 
node->ss.ps.plan;
+       node->as_valid_subplans = NULL;
+       if (NULL != plan->join_prune_paramids && !node->did_pruning)
        {
-               setPidIndex(node);
-               Assert(node->pidxIndex != 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;
+               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->pidxStatus, node->pidxIndex);
-               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);
        }
 
        /*
@@ -289,7 +272,7 @@ ExecDynamicIndexScan(DynamicIndexScanState *node)
        while (TupIsNull(slot) &&
                   initNextIndexToScan(node))
        {
-               slot = ExecIndexScan(node->indexScanState);
+               slot = ExecProcNode(&node->indexScanState->ss.ps);
 
                if (TupIsNull(slot))
                {
@@ -311,12 +294,6 @@ ExecEndDynamicIndexScan(DynamicIndexScanState *node)
 
        node->scan_state = SCAN_END;
 
-       if (node->shouldCallHashSeqTerm)
-       {
-               hash_seq_term(&node->pidxStatus);
-               node->shouldCallHashSeqTerm = false;
-       }
-
        MemoryContextDelete(node->partitionMemoryContext);
 }
 
@@ -332,47 +309,8 @@ ExecReScanDynamicIndex(DynamicIndexScanState *node)
                node->indexScanState = NULL;
        }
        node->scan_state = SCAN_INIT;
-
-       if (node->shouldCallHashSeqTerm)
-       {
-               hash_seq_term(&node->pidxStatus);
-               node->shouldCallHashSeqTerm = false;
-       }
-
-       /* Force reloading the hash table */
-       node->pidxIndex = NULL;
-}
-
-
-/*
- * IndexScan_MapLogicalIndexInfo
- *             Remaps the columns of the expressions of a provided 
logicalIndexInfo
- *             using attMap for a given varno.
- *
- *             Returns true if mapping was done.
- */
-bool
-IndexScan_MapLogicalIndexInfo(LogicalIndexInfo *logicalIndexInfo, AttrNumber 
*attMap, Index varno)
-{
-       if (NULL == attMap)
-       {
-               /* Columns are already aligned, and therefore, no mapping is 
necessary */
-               return false;
-       }
-       /* map the attrnos if necessary */
-       for (int i = 0; i < logicalIndexInfo->nColumns; i++)
-       {
-               if (logicalIndexInfo->indexKeys[i] != 0)
-               {
-                       logicalIndexInfo->indexKeys[i] = 
attMap[(logicalIndexInfo->indexKeys[i]) - 1];
-               }
-       }
-
-       /* map the attrnos in the indExprs and indPred */
-       change_varattnos_of_a_varno((Node *)logicalIndexInfo->indPred, attMap, 
varno);
-       change_varattnos_of_a_varno((Node *)logicalIndexInfo->indExprs, attMap, 
varno);
-
-       return true;
+       // reset partition internal state
+       node->whichPart = -1;
 }
 
 /*
@@ -388,7 +326,7 @@ IndexScan_GetColumnMapping(Oid oldOid, Oid newOid)
        if (oldOid == newOid)
                return NULL;
 
-       AttrNumber      *attMap;
+       AttrNumber        *attMap;
 
        Relation oldRel = heap_open(oldOid, AccessShareLock);
        Relation newRel = heap_open(newOid, AccessShareLock);
@@ -396,7 +334,7 @@ IndexScan_GetColumnMapping(Oid oldOid, Oid newOid)
        TupleDesc oldTupDesc = oldRel->rd_att;
        TupleDesc newTupDesc = newRel->rd_att;
 
-       attMap = varattnos_map(oldTupDesc, newTupDesc);
+       attMap = convert_tuples_by_name_map_if_req(oldTupDesc, newTupDesc, 
"unused msg");
 
        heap_close(oldRel, AccessShareLock);
        heap_close(newRel, AccessShareLock);
diff --git a/src/backend/executor/nodeIndexscan.c 
b/src/backend/executor/nodeIndexscan.c
index 690f80970b..77e6cee0ee 100644
--- a/src/backend/executor/nodeIndexscan.c
+++ b/src/backend/executor/nodeIndexscan.c
@@ -911,8 +911,22 @@ ExecIndexRestrPos(IndexScanState *node)
 IndexScanState *
 ExecInitIndexScan(IndexScan *node, EState *estate, int eflags)
 {
-       IndexScanState *indexstate;
        Relation        currentRelation;
+
+       /*
+        * open the base relation and acquire appropriate lock on it.
+        */
+       currentRelation = ExecOpenScanRelation(estate, node->scan.scanrelid, 
eflags);
+
+       return ExecInitIndexScanForPartition(node, estate, eflags,
+                                            currentRelation, node->indexid);
+}
+
+IndexScanState *
+ExecInitIndexScanForPartition(IndexScan *node, EState *estate, int eflags,
+                                 Relation currentRelation, Oid indexid)
+{
+       IndexScanState *indexstate;
        LOCKMODE        lockmode;
 
        /*
@@ -930,11 +944,6 @@ ExecInitIndexScan(IndexScan *node, EState *estate, int 
eflags)
         */
        ExecAssignExprContext(estate, &indexstate->ss.ps);
 
-       /*
-        * open the scan relation
-        */
-       currentRelation = ExecOpenScanRelation(estate, node->scan.scanrelid, 
eflags);
-
        indexstate->ss.ss_currentRelation = currentRelation;
        indexstate->ss.ss_currentScanDesc = NULL;       /* no heap scan here */
 
@@ -962,11 +971,11 @@ ExecInitIndexScan(IndexScan *node, EState *estate, int 
eflags)
         * in the expression must be found now...)
         */
        indexstate->ss.ps.qual =
-               ExecInitQual(node->scan.plan.qual, (PlanState *) indexstate);
+                       ExecInitQual(node->scan.plan.qual, (PlanState *) 
indexstate);
        indexstate->indexqualorig =
-               ExecInitQual(node->indexqualorig, (PlanState *) indexstate);
+                       ExecInitQual(node->indexqualorig, (PlanState *) 
indexstate);
        indexstate->indexorderbyorig =
-               ExecInitExprList(node->indexorderbyorig, (PlanState *) 
indexstate);
+                       ExecInitExprList(node->indexorderbyorig, (PlanState *) 
indexstate);
 
        /*
         * If we are just doing EXPLAIN (ie, aren't going to run the plan), stop
@@ -978,7 +987,7 @@ ExecInitIndexScan(IndexScan *node, EState *estate, int 
eflags)
 
        /* Open the index relation. */
        lockmode = exec_rt_fetch(node->scan.scanrelid, estate)->rellockmode;
-       indexstate->iss_RelationDesc = index_open(node->indexid, lockmode);
+       indexstate->iss_RelationDesc = index_open(indexid, lockmode);
 
        /*
         * Initialize index-specific scan state
@@ -1030,11 +1039,11 @@ ExecInitIndexScan(IndexScan *node, EState *estate, int 
eflags)
                Assert(numOrderByKeys == list_length(node->indexorderbyops));
                Assert(numOrderByKeys == list_length(node->indexorderbyorig));
                indexstate->iss_SortSupport = (SortSupportData *)
-                       palloc0(numOrderByKeys * sizeof(SortSupportData));
+                               palloc0(numOrderByKeys * 
sizeof(SortSupportData));
                indexstate->iss_OrderByTypByVals = (bool *)
-                       palloc(numOrderByKeys * sizeof(bool));
+                               palloc(numOrderByKeys * sizeof(bool));
                indexstate->iss_OrderByTypLens = (int16 *)
-                       palloc(numOrderByKeys * sizeof(int16));
+                               palloc(numOrderByKeys * sizeof(int16));
                i = 0;
                forboth(lco, node->indexorderbyops, lcx, node->indexorderbyorig)
                {
@@ -1063,9 +1072,9 @@ ExecInitIndexScan(IndexScan *node, EState *estate, int 
eflags)
 
                /* allocate arrays to hold the re-calculated distances */
                indexstate->iss_OrderByValues = (Datum *)
-                       palloc(numOrderByKeys * sizeof(Datum));
+                               palloc(numOrderByKeys * sizeof(Datum));
                indexstate->iss_OrderByNulls = (bool *)
-                       palloc(numOrderByKeys * sizeof(bool));
+                               palloc(numOrderByKeys * sizeof(bool));
 
                /* and initialize the reorder queue */
                indexstate->iss_ReorderQueue = 
pairingheap_allocate(reorderqueue_cmp,
diff --git a/src/backend/gpopt/translate/CTranslatorDXLToPlStmt.cpp 
b/src/backend/gpopt/translate/CTranslatorDXLToPlStmt.cpp
index 7ddfcfccaf..425e05f55e 100644
--- a/src/backend/gpopt/translate/CTranslatorDXLToPlStmt.cpp
+++ b/src/backend/gpopt/translate/CTranslatorDXLToPlStmt.cpp
@@ -66,6 +66,7 @@ extern "C" {
 #include "naucrates/dxl/operators/CDXLPhysicalCTEConsumer.h"
 #include "naucrates/dxl/operators/CDXLPhysicalCTEProducer.h"
 #include "naucrates/dxl/operators/CDXLPhysicalDynamicBitmapTableScan.h"
+#include "naucrates/dxl/operators/CDXLPhysicalDynamicIndexScan.h"
 #include "naucrates/dxl/operators/CDXLPhysicalDynamicTableScan.h"
 #include "naucrates/dxl/operators/CDXLPhysicalGatherMotion.h"
 #include "naucrates/dxl/operators/CDXLPhysicalHashJoin.h"
@@ -430,7 +431,12 @@ CTranslatorDXLToPlStmt::TranslateDXLOperatorToPlan(
                                                                                
  ctxt_translation_prev_siblings);
                        break;
                }
-               /* case EdxlopPhysicalDynamicIndexScan: { plan = 
TranslateDXLDynIdxScan(dxlnode, output_context, 
ctxt_translation_prev_siblings); break;} */
+               case EdxlopPhysicalDynamicIndexScan:
+               {
+                       plan = TranslateDXLDynIdxScan(dxlnode, output_context,
+                                                                               
  ctxt_translation_prev_siblings);
+                       break;
+               }
                case EdxlopPhysicalTVF:
                {
                        plan = TranslateDXLTvf(dxlnode, output_context,
@@ -4106,12 +4112,130 @@ CTranslatorDXLToPlStmt::TranslateDXLDynTblScan(
                &plan->targetlist, &plan->qual, output_context);
 
        SetParamIds(plan);
-       /*
-        *      auto *prune_result = 
m_dxl_to_plstmt_context->GetStaticPruneResult(
-               dyn_tbl_scan_dxlop->GetPartIndexIdPrintable());
 
-       dyn_seq_scan->partOids = prune_result;
-*/
+       return plan;
+}
+
+//---------------------------------------------------------------------------
+//     @function:
+//             CTranslatorDXLToPlStmt::TranslateDXLDynIdxScan
+//
+//     @doc:
+//             Translates a DXL dynamic index scan node into a 
DynamicIndexScan node
+//
+//---------------------------------------------------------------------------
+Plan *
+CTranslatorDXLToPlStmt::TranslateDXLDynIdxScan(
+       const CDXLNode *dyn_idx_scan_dxlnode, CDXLTranslateContext 
*output_context,
+       CDXLTranslationContextArray *ctxt_translation_prev_siblings)
+{
+       CDXLPhysicalDynamicIndexScan *dyn_index_scan_dxlop =
+               
CDXLPhysicalDynamicIndexScan::Cast(dyn_idx_scan_dxlnode->GetOperator());
+
+       // translation context for column mappings in the base relation
+       CDXLTranslateContextBaseTable base_table_context(m_mp);
+
+       Index index =
+               
gpdb::ListLength(m_dxl_to_plstmt_context->GetRTableEntriesList()) + 1;
+
+       const IMDRelation *md_rel = m_md_accessor->RetrieveRel(
+               dyn_index_scan_dxlop->GetDXLTableDescr()->MDId());
+       RangeTblEntry *rte = TranslateDXLTblDescrToRangeTblEntry(
+               dyn_index_scan_dxlop->GetDXLTableDescr(), index, 
&base_table_context);
+       GPOS_ASSERT(NULL != rte);
+       rte->requiredPerms |= ACL_SELECT;
+       m_dxl_to_plstmt_context->AddRTE(rte);
+
+       DynamicIndexScan *dyn_idx_scan = MakeNode(DynamicIndexScan);
+
+       dyn_idx_scan->indexscan.scan.scanrelid = index;
+
+       IMdIdArray *parts = dyn_index_scan_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);
+       }
+
+       dyn_idx_scan->partOids = oids_list;
+
+       dyn_idx_scan->join_prune_paramids = NIL;
+
+       OID oid_type =
+               
CMDIdGPDB::CastMdid(m_md_accessor->PtMDType<IMDTypeInt4>()->MDId())
+                       ->Oid();
+       const ULongPtrArray *selector_ids = 
dyn_index_scan_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);
+               dyn_idx_scan->join_prune_paramids =
+                       gpdb::LAppendInt(dyn_idx_scan->join_prune_paramids, 
param_id);
+       }
+
+       CMDIdGPDB *mdid_index =
+               
CMDIdGPDB::CastMdid(dyn_index_scan_dxlop->GetDXLIndexDescr()->MDId());
+       const IMDIndex *md_index = m_md_accessor->RetrieveIndex(mdid_index);
+       Oid index_oid = mdid_index->Oid();
+
+       GPOS_ASSERT(InvalidOid != index_oid);
+       dyn_idx_scan->indexscan.indexid = index_oid;
+
+       Plan *plan = &(dyn_idx_scan->indexscan.scan.plan);
+       plan->plan_node_id = m_dxl_to_plstmt_context->GetNextPlanId();
+
+       // translate operator costs
+       TranslatePlanCosts(dyn_idx_scan_dxlnode, plan);
+
+       // an index scan node must have 3 children: projection list, filter and 
index condition list
+       GPOS_ASSERT(3 == dyn_idx_scan_dxlnode->Arity());
+
+       // translate proj list and filter
+       CDXLNode *project_list_dxlnode = (*dyn_idx_scan_dxlnode)
+               [CDXLPhysicalDynamicIndexScan::EdxldisIndexProjList];
+       CDXLNode *filter_dxlnode = (*dyn_idx_scan_dxlnode)
+               [CDXLPhysicalDynamicIndexScan::EdxldisIndexFilter];
+       CDXLNode *index_cond_list_dxlnode = (*dyn_idx_scan_dxlnode)
+               [CDXLPhysicalDynamicIndexScan::EdxldisIndexCondition];
+
+       // translate proj list
+       plan->targetlist =
+               TranslateDXLProjList(project_list_dxlnode, &base_table_context,
+                                                        NULL 
/*child_contexts*/, output_context);
+
+       // translate index filter
+       plan->qual = TranslateDXLIndexFilter(filter_dxlnode, output_context,
+                                                                               
 &base_table_context,
+                                                                               
 ctxt_translation_prev_siblings);
+
+       dyn_idx_scan->indexscan.indexorderdir = 
CTranslatorUtils::GetScanDirection(
+               dyn_index_scan_dxlop->GetIndexScanDir());
+
+       // translate index condition list
+       List *index_cond = NIL;
+       List *index_orig_cond = NIL;
+       List *index_strategy_list = NIL;
+       List *index_subtype_list = NIL;
+
+       TranslateIndexConditions(
+               index_cond_list_dxlnode, 
dyn_index_scan_dxlop->GetDXLTableDescr(),
+               false,  // is_bitmap_index_probe
+               md_index, md_rel, output_context, &base_table_context,
+               ctxt_translation_prev_siblings, &index_cond, &index_orig_cond,
+               &index_strategy_list, &index_subtype_list);
+
+
+       dyn_idx_scan->indexscan.indexqual = index_cond;
+       dyn_idx_scan->indexscan.indexqualorig = index_orig_cond;
+
+       SetParamIds(plan);
+
+       return (Plan *) dyn_idx_scan;
 }
 //---------------------------------------------------------------------------
 //     @function:
diff --git a/src/backend/gporca/libgpopt/src/translate/CTranslatorExprToDXL.cpp 
b/src/backend/gporca/libgpopt/src/translate/CTranslatorExprToDXL.cpp
index bca5ff694a..efc6c873a4 100644
--- a/src/backend/gporca/libgpopt/src/translate/CTranslatorExprToDXL.cpp
+++ b/src/backend/gporca/libgpopt/src/translate/CTranslatorExprToDXL.cpp
@@ -101,6 +101,8 @@
 #include "naucrates/dxl/operators/CDXLPhysicalCTAS.h"
 #include "naucrates/dxl/operators/CDXLPhysicalCTEConsumer.h"
 #include "naucrates/dxl/operators/CDXLPhysicalCTEProducer.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"
@@ -1577,140 +1579,97 @@ CTranslatorExprToDXL::PdxlnDynamicIndexScan(
        CExpression *pexprDIS, CColRefArray *colref_array,
        CDXLPhysicalProperties *dxl_properties, CReqdPropPlan *prpp)
 {
-       GPOS_ASSERT(nullptr != pexprDIS);
-       GPOS_ASSERT(nullptr != dxl_properties);
-       GPOS_ASSERT(nullptr != prpp);
+       GPOS_ASSERT(NULL != pexprDIS);
+       GPOS_ASSERT(NULL != dxl_properties);
+       GPOS_ASSERT(NULL != prpp);
 
        CPhysicalDynamicIndexScan *popDIS =
                CPhysicalDynamicIndexScan::PopConvert(pexprDIS->Pop());
+       CColRefArray *pdrgpcrOutput = popDIS->PdrgpcrOutput();
 
-       // construct projection list
-       CColRefSet *pcrsOutput = prpp->PcrsRequired();
-       CDXLNode *pdxlnPrLAppend = PdxlnProjList(pcrsOutput, colref_array);
-
-       IMdIdArray *part_mdids = popDIS->GetPartitionMdids();
+       // translate table descriptor
+       CDXLTableDescr *table_descr =
+               MakeDXLTableDescr(popDIS->Ptabdesc(), pdrgpcrOutput, 
pexprDIS->Prpp());
 
-       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));
+       // create index descriptor
+       CIndexDescriptor *pindexdesc = popDIS->Pindexdesc();
+       CMDName *pmdnameIndex =
+               GPOS_NEW(m_mp) CMDName(m_mp, pindexdesc->Name().Pstr());
+       IMDId *pmdidIndex = pindexdesc->MDId();
+       pmdidIndex->AddRef();
+       CDXLIndexDescr *dxl_index_descr =
+               GPOS_NEW(m_mp) CDXLIndexDescr(pmdidIndex, pmdnameIndex);
 
-       // construct set of child indexes from parent list of child indexes
-       IMDId *pmdidIndex = popDIS->Pindexdesc()->MDId();
-       const IMDIndex *md_index = m_pmda->RetrieveIndex(pmdidIndex);
-       IMdIdArray *child_indexes = md_index->ChildIndexMdids();
 
-       MdidHashSet *child_index_mdids_set = GPOS_NEW(m_mp) MdidHashSet(m_mp);
-       for (ULONG ul = 0; ul < child_indexes->Size(); ul++)
-       {
-               (*child_indexes)[ul]->AddRef();
-               child_index_mdids_set->Insert((*child_indexes)[ul]);
-       }
+       // construct dynamic table scan operator
+       IMdIdArray *part_mdids = popDIS->GetPartitionMdids();
+       part_mdids->AddRef();
 
-       for (ULONG ul = 0; ul < part_mdids->Size(); ++ul)
+       ULongPtrArray *selector_ids = GPOS_NEW(m_mp) ULongPtrArray(m_mp);
+       CPartitionPropagationSpec *pps_reqd = prpp->Pepp()->PppsRequired();
+       if (pps_reqd->Contains(popDIS->ScanId()))
        {
-               IMDId *part_mdid = (*part_mdids)[ul];
-               const IMDRelation *part = m_pmda->RetrieveRel(part_mdid);
-
-               CPhysicalDynamicIndexScan *popDIS =
-                       CPhysicalDynamicIndexScan::PopConvert(pexprDIS->Pop());
-
-               // GPDB_12_MERGE_FIXME: ideally MakeTableDescForPart(part, 
pexprDIS->DeriveTableDescriptor());
-               // should just work, at this point all properties should've 
been derived, but we
-               // haven't derived the table descriptor.
-               CTableDescriptor *part_tabdesc =
-                       MakeTableDescForPart(part, popDIS->Ptabdesc());
-
-               // create new colrefs for every child partition
-               CColRefArray *part_colrefs = GPOS_NEW(m_mp) CColRefArray(m_mp);
-               for (ULONG ul = 0; ul < part_tabdesc->ColumnCount(); ++ul)
+               const CBitSet *bs = pps_reqd->SelectorIds(popDIS->ScanId());
+               CBitSetIter bsi(*bs);
+               for (ULONG ul = 0; bsi.Advance(); ul++)
                {
-                       const CColumnDescriptor *cd = 
part_tabdesc->Pcoldesc(ul);
-                       CColRef *cr = m_pcf->PcrCreate(cd->RetrieveType(),
-                                                                               
   cd->TypeModifier(), cd->Name());
-                       part_colrefs->Append(cr);
+                       selector_ids->Append(GPOS_NEW(m_mp) ULONG(bsi.Bit()));
                }
+       }
 
-               CDXLTableDescr *dxl_table_descr =
-                       MakeDXLTableDescr(part_tabdesc, part_colrefs, 
pexprDIS->Prpp());
-               part_tabdesc->Release();
-
-               CIndexDescriptor *pindexdesc = popDIS->Pindexdesc();
-               CDXLIndexDescr *dxl_index_descr = PdxlnIndexDescForPart(
-                       m_mp, child_index_mdids_set, part, 
pindexdesc->Name().Pstr());
+       // TODO: we assume that the index are always forward access.
 
-               // Finally create the IndexScan DXL node
-               CDXLNode *dxlnode = GPOS_NEW(m_mp) CDXLNode(
-                       m_mp, GPOS_NEW(m_mp) CDXLPhysicalIndexScan(
-                                         m_mp, dxl_table_descr, 
dxl_index_descr, EdxlisdForward));
+       CDXLNode *pdxlnDIS = GPOS_NEW(m_mp)
+               CDXLNode(m_mp, GPOS_NEW(m_mp) CDXLPhysicalDynamicIndexScan(
+                                                  m_mp, table_descr, 
dxl_index_descr, EdxlisdForward,
+                                                  part_mdids, selector_ids));
 
-               // GPDB_12_MERGE_FIXME: Compute stats & properties per scan
-               dxl_properties->AddRef();
-               dxlnode->SetProperties(dxl_properties);
+       // set plan costs
+       pdxlnDIS->SetProperties(dxl_properties);
 
-               // construct projection list
-               auto root_col_mapping = 
(*popDIS->GetRootColMappingPerPart())[ul];
+       // construct projection list
+       CColRefSet *pcrsOutput = prpp->PcrsRequired();
+       CDXLNode *pdxlnPrL = PdxlnProjList(pcrsOutput, colref_array);
 
-               CDXLNode *pdxlnPrL = PdxlnProjListForChildPart(
-                       root_col_mapping, part_colrefs, pcrsOutput, 
colref_array);
-               dxlnode->AddChild(pdxlnPrL);  // project list
+       // translate index predicates
+       CExpression *pexprCond = (*pexprDIS)[0];
+       CDXLNode *pdxlnIndexCondList = GPOS_NEW(m_mp)
+               CDXLNode(m_mp, GPOS_NEW(m_mp) CDXLScalarIndexCondList(m_mp));
 
-               CDXLNode *filter_dxlnode;
-               if (2 == pexprDIS->Arity())
-               {
-                       // translate residual predicates into the filter node
-                       CExpression *pexprResidualCond = (*pexprDIS)[1];
+       CExpressionArray *pdrgpexprConds =
+               CPredicateUtils::PdrgpexprConjuncts(m_mp, pexprCond);
+       const ULONG length = pdrgpexprConds->Size();
+       for (ULONG ul = 0; ul < length; ul++)
+       {
+               CExpression *pexprIndexCond = (*pdrgpexprConds)[ul];
+               CDXLNode *pdxlnIndexCond = PdxlnScalar(pexprIndexCond);
+               pdxlnIndexCondList->AddChild(pdxlnIndexCond);
+       }
+       pdrgpexprConds->Release();
 
-                       if (COperator::EopScalarConst != 
pexprResidualCond->Pop()->Eopid())
-                       {
-                               // construct the filter
-                               filter_dxlnode = 
PdxlnFilter(PdxlnCondForChildPart(
-                                       root_col_mapping, part_colrefs, 
popDIS->PdrgpcrOutput(),
-                                       pexprResidualCond));
-                       }
-                       else
-                       {
-                               filter_dxlnode = PdxlnFilter(nullptr);
-                       }
-               }
-               else
+       CDXLNode *pdxlnResidualCond = NULL;
+       if (2 == pexprDIS->Arity())
+       {
+               // translate residual predicates into the filter node
+               CExpression *pexprResidualCond = (*pexprDIS)[1];
+               if (COperator::EopScalarConst != 
pexprResidualCond->Pop()->Eopid())
                {
-                       // construct an empty filter
-                       filter_dxlnode = PdxlnFilter(nullptr);
+                       pdxlnResidualCond = PdxlnScalar(pexprResidualCond);
                }
-               dxlnode->AddChild(filter_dxlnode);      // filter
-
-               // translate index predicates
-               CExpression *pexprCond = (*pexprDIS)[0];
-               CDXLNode *pdxlnIndexCondList = GPOS_NEW(m_mp)
-                       CDXLNode(m_mp, GPOS_NEW(m_mp) 
CDXLScalarIndexCondList(m_mp));
+       }
 
-               CExpressionArray *pdrgpexprConds =
-                       CPredicateUtils::PdrgpexprConjuncts(m_mp, pexprCond);
-               const ULONG length = pdrgpexprConds->Size();
-               for (ULONG ul = 0; ul < length; ul++)
-               {
-                       CExpression *pexprIndexCond = (*pdrgpexprConds)[ul];
-                       // construct the condition as a filter
-                       CDXLNode *pdxlnIndexCond =
-                               PdxlnCondForChildPart(root_col_mapping, 
part_colrefs,
-                                                                         
popDIS->PdrgpcrOutput(), pexprIndexCond);
-                       pdxlnIndexCondList->AddChild(pdxlnIndexCond);
-               }
-               pdrgpexprConds->Release();
-               dxlnode->AddChild(pdxlnIndexCondList);
+       CDXLNode *filter_dxlnode = PdxlnFilter(pdxlnResidualCond);
 
-               // add to the other scans under the created Append node
-               pdxlnResult->AddChild(dxlnode);
+       pdxlnDIS->AddChild(pdxlnPrL);
+       pdxlnDIS->AddChild(filter_dxlnode);
+       pdxlnDIS->AddChild(pdxlnIndexCondList);
 
-               // cleanup
-               part_colrefs->Release();
-       }
-       child_index_mdids_set->Release();
+#ifdef GPOS_DEBUG
+       pdxlnDIS->GetOperator()->AssertValid(pdxlnDIS,
+                                                                               
 false /* validate_children */);
+#endif
 
-       return pdxlnResult;
+       return pdxlnDIS;
 }
 
 
diff --git 
a/src/backend/gporca/libnaucrates/include/naucrates/dxl/operators/CDXLPhysicalDynamicIndexScan.h
 
b/src/backend/gporca/libnaucrates/include/naucrates/dxl/operators/CDXLPhysicalDynamicIndexScan.h
index bc1c8bf081..14d3bded7e 100644
--- 
a/src/backend/gporca/libnaucrates/include/naucrates/dxl/operators/CDXLPhysicalDynamicIndexScan.h
+++ 
b/src/backend/gporca/libnaucrates/include/naucrates/dxl/operators/CDXLPhysicalDynamicIndexScan.h
@@ -35,18 +35,16 @@ private:
        // table descriptor for the scanned table
        CDXLTableDescr *m_dxl_table_descr;
 
-       // part index id
-       ULONG m_part_index_id;
-
-       // printable partition index id
-       ULONG m_part_index_id_printable;
-
        // index descriptor associated with the scanned table
        CDXLIndexDescr *m_dxl_index_descr;
 
        // scan direction of the index
        EdxlIndexScanDirection m_index_scan_dir;
 
+       IMdIdArray *m_part_mdids;
+
+       ULongPtrArray *m_selector_ids = nullptr;
+
 public:
        CDXLPhysicalDynamicIndexScan(CDXLPhysicalDynamicIndexScan &) = delete;
 
@@ -61,9 +59,10 @@ public:
 
        //ctor
        CDXLPhysicalDynamicIndexScan(CMemoryPool *mp, CDXLTableDescr 
*table_descr,
-                                                                ULONG 
part_idx_id, ULONG part_idx_id_printable,
                                                                 CDXLIndexDescr 
*dxl_index_descr,
-                                                                
EdxlIndexScanDirection idx_scan_direction);
+                                                                
EdxlIndexScanDirection idx_scan_direction,
+                                                                IMdIdArray 
*part_mdids,
+                                                                ULongPtrArray 
*selector_ids);
 
        //dtor
        ~CDXLPhysicalDynamicIndexScan() override;
@@ -80,15 +79,17 @@ public:
        //table descriptor
        const CDXLTableDescr *GetDXLTableDescr() const;
 
-       // partition index id
-       ULONG GetPartIndexId() const;
-
-       // printable partition index id
-       ULONG GetPartIndexIdPrintable() const;
-
        // scan direction
        EdxlIndexScanDirection GetIndexScanDir() const;
 
+       IMdIdArray *GetParts() const;
+
+       const ULongPtrArray *
+       GetSelectorIds() const
+       {
+               return m_selector_ids;
+       }
+
        // serialize operator in DXL format
        void SerializeToDXL(CXMLSerializer *xml_serializer,
                                                const CDXLNode *node) const 
override;
diff --git 
a/src/backend/gporca/libnaucrates/include/naucrates/dxl/parser/CParseHandlerDynamicIndexScan.h
 
b/src/backend/gporca/libnaucrates/include/naucrates/dxl/parser/CParseHandlerDynamicIndexScan.h
index b5a2738e39..e173af8c8b 100644
--- 
a/src/backend/gporca/libnaucrates/include/naucrates/dxl/parser/CParseHandlerDynamicIndexScan.h
+++ 
b/src/backend/gporca/libnaucrates/include/naucrates/dxl/parser/CParseHandlerDynamicIndexScan.h
@@ -35,11 +35,7 @@ XERCES_CPP_NAMESPACE_USE
 class CParseHandlerDynamicIndexScan : public CParseHandlerIndexScan
 {
 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(
diff --git 
a/src/backend/gporca/libnaucrates/include/naucrates/dxl/parser/CParseHandlerIndexScan.h
 
b/src/backend/gporca/libnaucrates/include/naucrates/dxl/parser/CParseHandlerIndexScan.h
index e1fcba1232..3c6a873084 100644
--- 
a/src/backend/gporca/libnaucrates/include/naucrates/dxl/parser/CParseHandlerIndexScan.h
+++ 
b/src/backend/gporca/libnaucrates/include/naucrates/dxl/parser/CParseHandlerIndexScan.h
@@ -60,8 +60,8 @@ protected:
 
        // common EndElement functionality for IndexScan and IndexOnlyScan
        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:
        CParseHandlerIndexScan(const CParseHandlerIndexScan &) = delete;
diff --git 
a/src/backend/gporca/libnaucrates/src/operators/CDXLPhysicalDynamicIndexScan.cpp
 
b/src/backend/gporca/libnaucrates/src/operators/CDXLPhysicalDynamicIndexScan.cpp
index dbcb9439a1..e8e1a0ecd4 100644
--- 
a/src/backend/gporca/libnaucrates/src/operators/CDXLPhysicalDynamicIndexScan.cpp
+++ 
b/src/backend/gporca/libnaucrates/src/operators/CDXLPhysicalDynamicIndexScan.cpp
@@ -11,8 +11,10 @@
 
 #include "naucrates/dxl/operators/CDXLPhysicalDynamicIndexScan.h"
 
+#include "naucrates/dxl/CDXLUtils.h"
 #include "naucrates/dxl/operators/CDXLNode.h"
 #include "naucrates/dxl/xml/CXMLSerializer.h"
+#include "naucrates/md/IMDCacheObject.h"
 
 using namespace gpos;
 using namespace gpdxl;
@@ -27,15 +29,15 @@ using namespace gpdxl;
 //
 //---------------------------------------------------------------------------
 CDXLPhysicalDynamicIndexScan::CDXLPhysicalDynamicIndexScan(
-       CMemoryPool *mp, CDXLTableDescr *table_descr, ULONG part_idx_id,
-       ULONG part_idx_id_printable, CDXLIndexDescr *dxl_index_descr,
-       EdxlIndexScanDirection idx_scan_direction)
+       CMemoryPool *mp, CDXLTableDescr *table_descr,
+       CDXLIndexDescr *dxl_index_descr, EdxlIndexScanDirection 
idx_scan_direction,
+       IMdIdArray *part_mdids, ULongPtrArray *selector_ids)
        : CDXLPhysical(mp),
          m_dxl_table_descr(table_descr),
-         m_part_index_id(part_idx_id),
-         m_part_index_id_printable(part_idx_id_printable),
          m_dxl_index_descr(dxl_index_descr),
-         m_index_scan_dir(idx_scan_direction)
+         m_index_scan_dir(idx_scan_direction),
+         m_part_mdids(part_mdids),
+         m_selector_ids(selector_ids)
 {
        GPOS_ASSERT(nullptr != m_dxl_table_descr);
        GPOS_ASSERT(nullptr != m_dxl_index_descr);
@@ -53,6 +55,8 @@ CDXLPhysicalDynamicIndexScan::~CDXLPhysicalDynamicIndexScan()
 {
        m_dxl_index_descr->Release();
        m_dxl_table_descr->Release();
+       m_part_mdids->Release();
+       CRefCount::SafeRelease(m_selector_ids);
 }
 
 //---------------------------------------------------------------------------
@@ -125,32 +129,10 @@ CDXLPhysicalDynamicIndexScan::GetDXLTableDescr() const
        return m_dxl_table_descr;
 }
 
-//---------------------------------------------------------------------------
-//     @function:
-//             CDXLPhysicalDynamicIndexScan::GetPartIndexId
-//
-//     @doc:
-//             Part index id
-//
-//---------------------------------------------------------------------------
-ULONG
-CDXLPhysicalDynamicIndexScan::GetPartIndexId() const
-{
-       return m_part_index_id;
-}
-
-//---------------------------------------------------------------------------
-//     @function:
-//             CDXLPhysicalDynamicIndexScan::GetPartIndexIdPrintable
-//
-//     @doc:
-//             Printable partition index id
-//
-//---------------------------------------------------------------------------
-ULONG
-CDXLPhysicalDynamicIndexScan::GetPartIndexIdPrintable() const
+IMdIdArray *
+CDXLPhysicalDynamicIndexScan::GetParts() const
 {
-       return m_part_index_id_printable;
+       return m_part_mdids;
 }
 
 //---------------------------------------------------------------------------
@@ -173,14 +155,12 @@ 
CDXLPhysicalDynamicIndexScan::SerializeToDXL(CXMLSerializer *xml_serializer,
                CDXLTokens::GetDXLTokenStr(EdxltokenIndexScanDirection),
                CDXLOperator::GetIdxScanDirectionStr(m_index_scan_dir));
 
+       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);
 
        // serialize properties
        node->SerializePropertiesToDXL(xml_serializer);
@@ -188,6 +168,12 @@ 
CDXLPhysicalDynamicIndexScan::SerializeToDXL(CXMLSerializer *xml_serializer,
        // serialize children
        node->SerializeChildrenToDXL(xml_serializer);
 
+       // serialize partition mdids
+       IMDCacheObject::SerializeMDIdList(
+               xml_serializer, m_part_mdids,
+               CDXLTokens::GetDXLTokenStr(EdxltokenPartitions),
+               CDXLTokens::GetDXLTokenStr(EdxltokenPartition));
+
        // serialize index descriptor
        m_dxl_index_descr->SerializeToDXL(xml_serializer);
 
diff --git 
a/src/backend/gporca/libnaucrates/src/operators/CDXLPhysicalIndexScan.cpp 
b/src/backend/gporca/libnaucrates/src/operators/CDXLPhysicalIndexScan.cpp
index 1424fabdca..38e6308e3e 100644
--- a/src/backend/gporca/libnaucrates/src/operators/CDXLPhysicalIndexScan.cpp
+++ b/src/backend/gporca/libnaucrates/src/operators/CDXLPhysicalIndexScan.cpp
@@ -13,6 +13,7 @@
 
 #include "naucrates/dxl/operators/CDXLNode.h"
 #include "naucrates/dxl/xml/CXMLSerializer.h"
+#include "naucrates/md/IMDCacheObject.h"
 
 using namespace gpos;
 using namespace gpdxl;
@@ -148,6 +149,12 @@ CDXLPhysicalIndexScan::SerializeToDXL(CXMLSerializer 
*xml_serializer,
        // serialize children
        node->SerializeChildrenToDXL(xml_serializer);
 
+       // serialize partition mdids (null in this case)
+       IMdIdArray *empty = GPOS_NEW(m_mp) IMdIdArray(m_mp);
+       IMDCacheObject::SerializeMDIdList(
+               xml_serializer, empty, 
CDXLTokens::GetDXLTokenStr(EdxltokenPartitions),
+               CDXLTokens::GetDXLTokenStr(EdxltokenPartition));
+       empty->Release();
        // serialize index descriptor
        m_dxl_index_descr->SerializeToDXL(xml_serializer);
 
diff --git 
a/src/backend/gporca/libnaucrates/src/parser/CParseHandlerDynamicIndexScan.cpp 
b/src/backend/gporca/libnaucrates/src/parser/CParseHandlerDynamicIndexScan.cpp
index 48983c8b73..ea511e20de 100644
--- 
a/src/backend/gporca/libnaucrates/src/parser/CParseHandlerDynamicIndexScan.cpp
+++ 
b/src/backend/gporca/libnaucrates/src/parser/CParseHandlerDynamicIndexScan.cpp
@@ -43,9 +43,7 @@ XERCES_CPP_NAMESPACE_USE
 CParseHandlerDynamicIndexScan::CParseHandlerDynamicIndexScan(
        CMemoryPool *mp, CParseHandlerManager *parse_handler_mgr,
        CParseHandlerBase *parse_handler_root)
-       : CParseHandlerIndexScan(mp, parse_handler_mgr, parse_handler_root),
-         m_part_index_id(0),
-         m_part_index_id_printable(0)
+       : CParseHandlerIndexScan(mp, parse_handler_mgr, parse_handler_root)
 {
 }
 
@@ -67,14 +65,9 @@ CParseHandlerDynamicIndexScan::StartElement(
        StartElementHelper(element_local_name, attrs,
                                           EdxltokenPhysicalDynamicIndexScan);
 
-       m_part_index_id = CDXLOperatorFactory::ExtractConvertAttrValueToUlong(
-               m_parse_handler_mgr->GetDXLMemoryManager(), attrs, 
EdxltokenPartIndexId,
+       m_selector_ids = CDXLOperatorFactory::ExtractConvertValuesToArray(
+               m_parse_handler_mgr->GetDXLMemoryManager(), attrs, 
EdxltokenSelectorIds,
                EdxltokenPhysicalDynamicIndexScan);
-       m_part_index_id_printable =
-               CDXLOperatorFactory::ExtractConvertAttrValueToUlong(
-                       m_parse_handler_mgr->GetDXLMemoryManager(), attrs,
-                       EdxltokenPartIndexIdPrintable, 
EdxltokenPhysicalDynamicIndexScan,
-                       true /*is_optional*/, m_part_index_id);
 }
 
 //---------------------------------------------------------------------------
@@ -92,7 +85,7 @@ CParseHandlerDynamicIndexScan::EndElement(const XMLCh *const, 
 // element_uri,
 )
 {
        EndElementHelper(element_local_name, EdxltokenPhysicalDynamicIndexScan,
-                                        m_part_index_id, 
m_part_index_id_printable);
+                                        m_selector_ids /*m_selector_ids*/);
 }
 
 
diff --git 
a/src/backend/gporca/libnaucrates/src/parser/CParseHandlerIndexOnlyScan.cpp 
b/src/backend/gporca/libnaucrates/src/parser/CParseHandlerIndexOnlyScan.cpp
index 30fe0fc3ab..c46f789260 100644
--- a/src/backend/gporca/libnaucrates/src/parser/CParseHandlerIndexOnlyScan.cpp
+++ b/src/backend/gporca/libnaucrates/src/parser/CParseHandlerIndexOnlyScan.cpp
@@ -68,7 +68,8 @@ CParseHandlerIndexOnlyScan::EndElement(const XMLCh *const,    
// element_uri,
                                                                           
const XMLCh *const  // element_qname
 )
 {
-       EndElementHelper(element_local_name, EdxltokenPhysicalIndexOnlyScan);
+       EndElementHelper(element_local_name, EdxltokenPhysicalIndexOnlyScan,
+                                        nullptr);
 }
 
 // EOF
diff --git 
a/src/backend/gporca/libnaucrates/src/parser/CParseHandlerIndexScan.cpp 
b/src/backend/gporca/libnaucrates/src/parser/CParseHandlerIndexScan.cpp
index b4d6282442..becb70f640 100644
--- a/src/backend/gporca/libnaucrates/src/parser/CParseHandlerIndexScan.cpp
+++ b/src/backend/gporca/libnaucrates/src/parser/CParseHandlerIndexScan.cpp
@@ -24,6 +24,7 @@
 #include "naucrates/dxl/parser/CParseHandlerFilter.h"
 #include "naucrates/dxl/parser/CParseHandlerIndexCondList.h"
 #include "naucrates/dxl/parser/CParseHandlerIndexDescr.h"
+#include "naucrates/dxl/parser/CParseHandlerMetadataIdList.h"
 #include "naucrates/dxl/parser/CParseHandlerProjList.h"
 #include "naucrates/dxl/parser/CParseHandlerProperties.h"
 #include "naucrates/dxl/parser/CParseHandlerScalarOp.h"
@@ -129,6 +130,12 @@ CParseHandlerIndexScan::StartElementHelper(
                        m_parse_handler_mgr, this);
        m_parse_handler_mgr->ActivateParseHandler(index_descr_parse_handler);
 
+       CParseHandlerBase *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 index condition list
        CParseHandlerBase *index_condition_list_parse_handler =
                CParseHandlerFactory::GetParseHandler(
@@ -163,6 +170,7 @@ CParseHandlerIndexScan::StartElementHelper(
        this->Append(proj_list_parse_handler);
        this->Append(filter_parse_handler);
        this->Append(index_condition_list_parse_handler);
+       this->Append(partition_mdids_parse_handler);
        this->Append(index_descr_parse_handler);
        this->Append(table_descr_parse_handler);
 }
@@ -178,8 +186,7 @@ CParseHandlerIndexScan::StartElementHelper(
 void
 CParseHandlerIndexScan::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))
@@ -199,10 +206,12 @@ CParseHandlerIndexScan::EndElementHelper(const XMLCh 
*const element_local_name,
                dynamic_cast<CParseHandlerFilter *>((*this)[2]);
        CParseHandlerIndexCondList *index_condition_list_parse_handler =
                dynamic_cast<CParseHandlerIndexCondList *>((*this)[3]);
+       CParseHandlerMetadataIdList *partition_mdids_parse_handler =
+               dynamic_cast<CParseHandlerMetadataIdList *>((*this)[4]);
        CParseHandlerIndexDescr *index_descr_parse_handler =
-               dynamic_cast<CParseHandlerIndexDescr *>((*this)[4]);
+               dynamic_cast<CParseHandlerIndexDescr *>((*this)[5]);
        CParseHandlerTableDescr *table_descr_parse_handler =
-               dynamic_cast<CParseHandlerTableDescr *>((*this)[5]);
+               dynamic_cast<CParseHandlerTableDescr *>((*this)[6]);
 
        CDXLTableDescr *dxl_table_descr =
                table_descr_parse_handler->GetDXLTableDescr();
@@ -229,9 +238,12 @@ CParseHandlerIndexScan::EndElementHelper(const XMLCh 
*const element_local_name,
        {
                GPOS_ASSERT(EdxltokenPhysicalDynamicIndexScan == token_type);
 
+               IMdIdArray *mdid_partitions_array =
+                       partition_mdids_parse_handler->GetMdIdArray();
+               mdid_partitions_array->AddRef();
                dxl_op = GPOS_NEW(m_mp) CDXLPhysicalDynamicIndexScan(
-                       m_mp, dxl_table_descr, part_idx_id, 
part_idx_id_printable,
-                       dxl_index_descr, m_index_scan_dir);
+                       m_mp, dxl_table_descr, dxl_index_descr, 
m_index_scan_dir,
+                       mdid_partitions_array, selector_ids);
                m_dxl_node = GPOS_NEW(m_mp) CDXLNode(m_mp, dxl_op);
        }
 
diff --git a/src/include/executor/nodeDynamicIndexscan.h 
b/src/include/executor/nodeDynamicIndexscan.h
index 2fdf08d594..64e9045423 100644
--- a/src/include/executor/nodeDynamicIndexscan.h
+++ b/src/include/executor/nodeDynamicIndexscan.h
@@ -16,15 +16,11 @@
 
 #include "nodes/execnodes.h"
 
-/* GPDB_12_MERGE_FIXME */
-#if 0
 extern DynamicIndexScanState *ExecInitDynamicIndexScan(DynamicIndexScan *node, 
EState *estate, int eflags);
-extern TupleTableSlot *ExecDynamicIndexScan(DynamicIndexScanState *node);
+extern TupleTableSlot *ExecDynamicIndexScan(PlanState *node);
 extern void ExecEndDynamicIndexScan(DynamicIndexScanState *node);
 extern void ExecReScanDynamicIndex(DynamicIndexScanState *node);
 
-extern bool IndexScan_MapLogicalIndexInfo(LogicalIndexInfo *logicalIndexInfo, 
AttrNumber *attMap, Index varno);
 extern AttrNumber *IndexScan_GetColumnMapping(Oid oldOid, Oid newOid);
-#endif
 
 #endif
diff --git a/src/include/gpopt/translate/CTranslatorDXLToPlStmt.h 
b/src/include/gpopt/translate/CTranslatorDXLToPlStmt.h
index c157850e51..dbb7662904 100644
--- a/src/include/gpopt/translate/CTranslatorDXLToPlStmt.h
+++ b/src/include/gpopt/translate/CTranslatorDXLToPlStmt.h
@@ -342,12 +342,12 @@ private:
        );
 
        // translate a dynamic index scan operator
-       /* Plan *TranslateDXLDynIdxScan */
-       /*      ( */
-       /*      const CDXLNode *dyn_idx_scan_dxlnode, */
-       /*      CDXLTranslateContext *output_context, */
-       /*      CDXLTranslationContextArray *ctxt_translation_prev_siblings // 
translation contexts of previous siblings */
-       /*      ); */
+       Plan *TranslateDXLDynIdxScan(
+               const CDXLNode *dyn_idx_scan_dxlnode,
+               CDXLTranslateContext *output_context,
+               CDXLTranslationContextArray *
+                       ctxt_translation_prev_siblings  // translation contexts 
of previous siblings
+       );
 
        // translate a DML operator
        Plan *TranslateDXLDml(


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


Reply via email to