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

    Adds Orca support for Dynamic Table Scan
---
 src/backend/executor/execDynamicScan.c             | 158 ---------------------
 src/backend/executor/nodeDynamicSeqscan.c          | 148 ++++++++-----------
 .../gpopt/translate/CTranslatorDXLToPlStmt.cpp     |  33 ++++-
 .../src/translate/CTranslatorExprToDXL.cpp         | 154 +++-----------------
 .../dxl/operators/CDXLPhysicalDynamicTableScan.h   |  21 ++-
 .../dxl/parser/CParseHandlerDynamicTableScan.h     |   6 +-
 .../src/operators/CDXLPhysicalDynamicTableScan.cpp |  57 +++-----
 .../src/parser/CParseHandlerDynamicTableScan.cpp   |  30 ++--
 src/include/executor/execDynamicScan.h             |  28 ----
 9 files changed, 163 insertions(+), 472 deletions(-)

diff --git a/src/backend/executor/execDynamicScan.c 
b/src/backend/executor/execDynamicScan.c
deleted file mode 100644
index d0496f2e50..0000000000
--- a/src/backend/executor/execDynamicScan.c
+++ /dev/null
@@ -1,158 +0,0 @@
-/*-------------------------------------------------------------------------
- *
- * execDynamicScan.c
- *       Support routines for iterating through dynamically chosen partitions 
of a relation
- *
- * Portions Copyright (c) 2014-Present VMware, Inc. or its affiliates.
- *
- *
- * IDENTIFICATION
- *         src/backend/executor/execDynamicScan.c
- *
- *-------------------------------------------------------------------------
- */
-#include "postgres.h"
-
-#include "cdb/partitionselection.h"
-#include "executor/executor.h"
-#include "executor/execDynamicScan.h"
-#include "parser/parsetree.h"
-
-/*
- * isDynamicScan
- *             Returns true if the scan node is dynamic (i.e., determining
- *             relations to scan at runtime).
- */
-bool
-isDynamicScan(const Plan *plan)
-{
-       switch (nodeTag(plan))
-       {
-               case T_DynamicSeqScan:
-               case T_DynamicIndexScan:
-               case T_DynamicBitmapHeapScan:
-               case T_DynamicBitmapIndexScan:
-                       return true;
-
-               default:
-                       return false;
-       }
-}
-
-/*
- * DynamicScan_GetDynamicScanId
- *             Returns the index into EState->dynamicTableScanInfo arrays for 
this
- *      dynamic scan node.
- */
-static int
-DynamicScan_GetDynamicScanId(Plan *plan)
-{
-       switch (nodeTag(plan))
-       {
-               case T_DynamicSeqScan:
-                       return ((DynamicSeqScan *) plan)->partIndex;
-
-               case T_DynamicIndexScan:
-                       return ((DynamicIndexScan *) plan)->partIndex;
-
-               case T_DynamicBitmapHeapScan:
-                       return ((DynamicBitmapHeapScan *) plan)->partIndex;
-
-               case T_DynamicBitmapIndexScan:
-                       return ((DynamicBitmapIndexScan *) plan)->partIndex;
-
-               default:
-                       elog(ERROR, "unknown dynamic scan node type %u", 
nodeTag(plan));
-       }
-}
-
-/*
- * DynamicScan_GetDynamicScanIdPrintable
- *             Return "printable" scan id for a node, for EXPLAIN
- */
-int
-DynamicScan_GetDynamicScanIdPrintable(Plan *plan)
-{
-       switch (nodeTag(plan))
-       {
-               case T_DynamicSeqScan:
-                       return ((DynamicSeqScan *) plan)->partIndexPrintable;
-
-               case T_DynamicIndexScan:
-                       return ((DynamicIndexScan *) plan)->partIndexPrintable;
-
-               case T_DynamicBitmapHeapScan:
-                       return ((DynamicBitmapHeapScan *) 
plan)->partIndexPrintable;
-
-               case T_DynamicBitmapIndexScan:
-                       return ((DynamicBitmapIndexScan *) 
plan)->partIndexPrintable;
-
-               default:
-                       elog(ERROR, "unknown dynamic scan node type %u", 
nodeTag(plan));
-       }
-}
-
-/*
- * DynamicScan_GetTableOid
- *             Returns the Oid of the table/partition to scan.
- *
- *             A partition must have been selected already.
- */
-Oid
-DynamicScan_GetTableOid(ScanState *scanState)
-{
-       int                     partIndex;
-       Oid                     curRelOid;
-
-       partIndex = DynamicScan_GetDynamicScanId(scanState->ps.plan);
-
-       /* Get the oid of the current relation */
-       Assert(NULL != scanState->ps.state->dynamicTableScanInfo);
-       Assert(partIndex <= 
scanState->ps.state->dynamicTableScanInfo->numScans);
-
-       curRelOid = 
scanState->ps.state->dynamicTableScanInfo->curRelOids[partIndex - 1];
-       if (!OidIsValid(curRelOid))
-               elog(ERROR, "no partition selected for dynamic scan id %d", 
partIndex);
-
-       return curRelOid;
-}
-
-/*
- * DynamicScan_SetTableOid
- *             Select a partition to scan in a dynamic scan.
- *
- *             This is used to advertise the selected partition in 
EState->dynamicTableScanInfo.
- */
-void
-DynamicScan_SetTableOid(ScanState *scanState, Oid curRelOid)
-{
-       int                     partIndex;
-
-       partIndex = DynamicScan_GetDynamicScanId(scanState->ps.plan);
-
-       Assert(NULL != scanState->ps.state->dynamicTableScanInfo);
-       Assert(partIndex <= 
scanState->ps.state->dynamicTableScanInfo->numScans);
-
-       scanState->ps.state->dynamicTableScanInfo->curRelOids[partIndex - 1] = 
curRelOid;
-}
-
-/*
- * DynamicScan_RemapExpression
- *             Re-maps the expression using the provided attMap.
- */
-bool
-DynamicScan_RemapExpression(ScanState *scanState, AttrNumber *attMap, Node 
*expr)
-{
-       if (!isDynamicScan(scanState->ps.plan))
-       {
-               return false;
-       }
-
-       if (NULL != attMap)
-       {
-               change_varattnos_of_a_varno((Node*)expr, attMap, ((Scan 
*)scanState->ps.plan)->scanrelid);
-               return true;
-       }
-
-       return false;
-}
diff --git a/src/backend/executor/nodeDynamicSeqscan.c 
b/src/backend/executor/nodeDynamicSeqscan.c
index 9a0d31fc1a..717a1849a4 100644
--- a/src/backend/executor/nodeDynamicSeqscan.c
+++ b/src/backend/executor/nodeDynamicSeqscan.c
@@ -8,13 +8,11 @@
  * DynamicSeqScan node scans each relation one after the other. For each
  * relation, it opens the table, scans the tuple, and returns relevant tuples.
  *
- * GPDB_12_MERGE_FIXME: This is currently disabled altogether. If it is
- * resurrected, some changes are needed to GPORCA. The way Partition
- * Selectors work has been heavily rewritten, there's no global hash table
- * of selected partitions anymore. For "static selection", there's a
- * partOids field in the DynamicSeqScan plan node that holds the selected
- * partitions; but none of the code in this file has been fixed to
- * actually work that way. Same with all the other Dynamic*Scan nodes.
+ * This has a smaller plan size than using an append with many partitions.
+ * Instead of determining the column mapping for each partition during 
planning,
+ * this mapping is determined during execution. When there are many partitions
+ * with many columns, the plan size improvement becomes very large, on the 
order of
+ * 100+ MB in some cases.
  *
  * Portions Copyright (c) 2012 - present, EMC/Greenplum
  * Portions Copyright (c) 2012-Present VMware, Inc. or its affiliates.
@@ -30,81 +28,16 @@
 #include "executor/executor.h"
 #include "executor/instrument.h"
 #include "nodes/execnodes.h"
-#include "nodes/nodeFuncs.h"
-#include "executor/execDynamicScan.h"
+#include "executor/execPartition.h"
 #include "executor/nodeDynamicSeqscan.h"
 #include "executor/nodeSeqscan.h"
-#include "utils/hsearch.h"
-#include "parser/parsetree.h"
 #include "utils/memutils.h"
 #include "utils/rel.h"
-#include "cdb/cdbvars.h"
 #include "access/table.h"
 #include "access/tableam.h"
 
 static void CleanupOnePartition(DynamicSeqScanState *node);
 
-/*
- * During attribute re-mapping for heterogeneous partitions, we use
- * this struct to identify which varno's attributes will be re-mapped.
- * Using this struct as a *context* during expression tree walking, we
- * can skip varattnos that do not belong to a given varno.
- */
-typedef struct AttrMapContext
-{
-       const AttrNumber *newattno; /* The mapping table to remap the varattno 
*/
-       Index           varno;                  /* Which rte's varattno to 
re-map */
-} AttrMapContext;
-
-/*
- * Remaps the varattno of a varattno in a Var node using an attribute map.
- */
-static bool
-change_varattnos_varno_walker(Node *node, const AttrMapContext *attrMapCxt)
-{
-       if (node == NULL)
-               return false;
-       if (IsA(node, Var))
-       {
-               Var                *var = (Var *) node;
-
-               if (var->varlevelsup == 0 && (var->varno == attrMapCxt->varno) 
&&
-                       var->varattno > 0)
-               {
-                       /*
-                        * ??? the following may be a problem when the node is 
multiply
-                        * referenced though stringToNode() doesn't create such 
a node
-                        * currently.
-                        */
-                       Assert(attrMapCxt->newattno[var->varattno - 1] > 0);
-                       var->varattno = var->varoattno = 
attrMapCxt->newattno[var->varattno - 1];
-               }
-               return false;
-       }
-       return expression_tree_walker(node, change_varattnos_varno_walker,
-                                     (void *) attrMapCxt);
-}
-
-/*
- * Replace varattno values for a given varno RTE index in an expression
- * tree according to the given map array, that is, varattno N is replaced
- * by newattno[N-1].  It is caller's responsibility to ensure that the array
- * is long enough to define values for all user varattnos present in the tree.
- * System column attnos remain unchanged.
- *
- * Note that the passed node tree is modified in-place!
- */
-static void
-change_varattnos_of_a_varno(Node *node, const AttrNumber *newattno, Index 
varno)
-{
-       AttrMapContext attrMapCxt;
-
-       attrMapCxt.newattno = newattno;
-       attrMapCxt.varno = varno;
-
-       (void) change_varattnos_varno_walker(node, &attrMapCxt);
-}
-
 DynamicSeqScanState *
 ExecInitDynamicSeqScan(DynamicSeqScan *node, EState *estate, int eflags)
 {
@@ -120,7 +53,7 @@ ExecInitDynamicSeqScan(DynamicSeqScan *node, EState *estate, 
int eflags)
        state->ss.ps.plan = (Plan *) node;
        state->ss.ps.state = estate;
        state->ss.ps.ExecProcNode = ExecDynamicSeqScan;
-
+       state->did_pruning = false;
        state->scan_state = SCAN_INIT;
 
        /* Initialize child expressions. This is needed to find subplans. */
@@ -150,6 +83,8 @@ ExecInitDynamicSeqScan(DynamicSeqScan *node, EState *estate, 
int eflags)
 
        state->scanrelid = node->seqscan.scanrelid;
 
+       state->as_prune_state = NULL;
+
        /*
         * This context will be reset per-partition to free up per-partition
         * qual and targetlist allocations
@@ -159,7 +94,6 @@ ExecInitDynamicSeqScan(DynamicSeqScan *node, EState *estate, 
int eflags)
                                                                         
ALLOCSET_DEFAULT_MINSIZE,
                                                                         
ALLOCSET_DEFAULT_INITSIZE,
                                                                         
ALLOCSET_DEFAULT_MAXSIZE);
-
        return state;
 }
 
@@ -190,6 +124,13 @@ initNextTableToScan(DynamicSeqScanState *node)
        else
                return false;
 
+       /* Collect number of partitions scanned in EXPLAIN ANALYZE */
+       if (NULL != scanState->ps.instrument)
+       {
+               Instrumentation *instr = scanState->ps.instrument;
+               instr->numPartScanned++;
+       }
+
        currentRelation = scanState->ss_currentRelation =
                table_open(node->partOids[node->whichPart], AccessShareLock);
 
@@ -211,11 +152,6 @@ initNextTableToScan(DynamicSeqScanState *node)
        /* If attribute remapping is not necessary, then do not change the 
varattno */
        if (attMap)
        {
-               /*
-                * FIXME: Ewww, this doesn't really belong in the executor. The 
optimizer
-                * really should explicitly pass a qual and a tlist to us, for 
each
-                * partition
-                */
                change_varattnos_of_a_varno((Node*)scanState->ps.plan->qual, 
attMap, node->scanrelid);
                
change_varattnos_of_a_varno((Node*)scanState->ps.plan->targetlist, attMap, 
node->scanrelid);
 
@@ -227,9 +163,9 @@ initNextTableToScan(DynamicSeqScanState *node)
        }
 
        /*
-        * 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)
        {
@@ -247,7 +183,6 @@ initNextTableToScan(DynamicSeqScanState *node)
        if (attMap)
                pfree(attMap);
 
-//     DynamicScan_SetTableOid(&node->ss, *pid);
        node->seqScanState = ExecInitSeqScanForPartition(&plan->seqscan, estate,
                                                                                
                         currentRelation);
        return true;
@@ -260,6 +195,33 @@ ExecDynamicSeqScan(PlanState *pstate)
        DynamicSeqScanState *node = castNode(DynamicSeqScanState, pstate);
        TupleTableSlot *slot = NULL;
 
+       DynamicSeqScan     *plan = (DynamicSeqScan *) node->ss.ps.plan;
+       node->as_valid_subplans = NULL;
+       if (NULL != plan->join_prune_paramids && !node->did_pruning)
+       {
+               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]);
+               }
+
+               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);
+       }
+
        /*
         * Scan the table to find next tuple to return. If the current table
         * is finished, close it and open the next table for scan.
@@ -337,5 +299,21 @@ ExecReScanDynamicSeqScan(DynamicSeqScanState *node)
 {
        DynamicSeqScanEndCurrentScan(node);
 
-       /* Force reloading the partition hash table */
+       // 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/gpopt/translate/CTranslatorDXLToPlStmt.cpp 
b/src/backend/gpopt/translate/CTranslatorDXLToPlStmt.cpp
index d443c7bd19..7ddfcfccaf 100644
--- a/src/backend/gpopt/translate/CTranslatorDXLToPlStmt.cpp
+++ b/src/backend/gpopt/translate/CTranslatorDXLToPlStmt.cpp
@@ -4054,9 +4054,36 @@ CTranslatorDXLToPlStmt::TranslateDXLDynTblScan(
        DynamicSeqScan *dyn_seq_scan = MakeNode(DynamicSeqScan);
 
        dyn_seq_scan->seqscan.scanrelid = index;
-       dyn_seq_scan->partIndex = dyn_tbl_scan_dxlop->GetPartIndexId();
-       dyn_seq_scan->partIndexPrintable =
-               dyn_tbl_scan_dxlop->GetPartIndexIdPrintable();
+
+       IMdIdArray *parts = dyn_tbl_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_seq_scan->partOids = oids_list;
+
+       dyn_seq_scan->join_prune_paramids = NIL;
+
+       OID oid_type =
+               
CMDIdGPDB::CastMdid(m_md_accessor->PtMDType<IMDTypeInt4>()->MDId())
+                       ->Oid();
+
+       const ULongPtrArray *selector_ids = 
dyn_tbl_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_seq_scan->join_prune_paramids =
+                       gpdb::LAppendInt(dyn_seq_scan->join_prune_paramids, 
param_id);
+       }
+
 
        Plan *plan = &(dyn_seq_scan->seqscan.plan);
        plan->plan_node_id = m_dxl_to_plstmt_context->GetNextPlanId();
diff --git a/src/backend/gporca/libgpopt/src/translate/CTranslatorExprToDXL.cpp 
b/src/backend/gporca/libgpopt/src/translate/CTranslatorExprToDXL.cpp
index b322ac5595..bca5ff694a 100644
--- a/src/backend/gporca/libgpopt/src/translate/CTranslatorExprToDXL.cpp
+++ b/src/backend/gporca/libgpopt/src/translate/CTranslatorExprToDXL.cpp
@@ -1358,9 +1358,26 @@ CTranslatorExprToDXL::PdxlnDynamicTableScan(
        }
 
        // construct dynamic table scan operator
+       IMdIdArray *part_mdids = popDTS->GetPartitionMdids();
+       part_mdids->AddRef();
+
+       ULongPtrArray *selector_ids = GPOS_NEW(m_mp) ULongPtrArray(m_mp);
+       CPartitionPropagationSpec *pps_reqd =
+               pexprDTS->Prpp()->Pepp()->PppsRequired();
+       if (pps_reqd->Contains(popDTS->ScanId()))
+       {
+               const CBitSet *bs = pps_reqd->SelectorIds(popDTS->ScanId());
+               CBitSetIter bsi(*bs);
+               for (ULONG ul = 0; bsi.Advance(); ul++)
+               {
+                       selector_ids->Append(GPOS_NEW(m_mp) ULONG(bsi.Bit()));
+               }
+       }
+
+
        CDXLPhysicalDynamicTableScan *pdxlopDTS =
-               GPOS_NEW(m_mp) CDXLPhysicalDynamicTableScan(
-                       m_mp, table_descr, 0 /* CHRIS */, popDTS->ScanId());
+               GPOS_NEW(m_mp) CDXLPhysicalDynamicTableScan(m_mp, table_descr,
+                                                                               
                        part_mdids, selector_ids);
 
        CDXLNode *pdxlnDTS = GPOS_NEW(m_mp) CDXLNode(m_mp, pdxlopDTS);
        pdxlnDTS->SetProperties(pdxlpropDTS);
@@ -1390,139 +1407,6 @@ CTranslatorExprToDXL::PdxlnDynamicTableScan(
        pdrgpdsBaseTables->Append(pds);
 
        return pdxlnDTS;
-
-       /*
-       GPOS_ASSERT(nullptr != pexprDTS);
-       GPOS_ASSERT_IFF(nullptr != pexprScalarCond, nullptr != dxl_properties);
-
-       CPhysicalDynamicTableScan *popDTS =
-               CPhysicalDynamicTableScan::PopConvert(pexprDTS->Pop());
-
-       ULongPtrArray *selector_ids = GPOS_NEW(m_mp) ULongPtrArray(m_mp);
-       CPartitionPropagationSpec *pps_reqd =
-               pexprDTS->Prpp()->Pepp()->PppsRequired();
-       if (pps_reqd->Contains(popDTS->ScanId()))
-       {
-               const CBitSet *bs = pps_reqd->SelectorIds(popDTS->ScanId());
-               CBitSetIter bsi(*bs);
-               for (ULONG ul = 0; bsi.Advance(); ul++)
-               {
-                       selector_ids->Append(GPOS_NEW(m_mp) ULONG(bsi.Bit()));
-               }
-       }
-
-       // construct plan costs
-       CDXLPhysicalProperties *pdxlpropDTS = GetProperties(pexprDTS);
-
-       if (nullptr != dxl_properties)
-       {
-               CWStringDynamic *rows_out_str = GPOS_NEW(m_mp) CWStringDynamic(
-                       m_mp,
-                       
dxl_properties->GetDXLOperatorCost()->GetRowsOutStr()->GetBuffer());
-               CWStringDynamic *pstrCost = GPOS_NEW(m_mp)
-                       CWStringDynamic(m_mp, 
dxl_properties->GetDXLOperatorCost()
-                                                                         
->GetTotalCostStr()
-                                                                         
->GetBuffer());
-
-               pdxlpropDTS->GetDXLOperatorCost()->SetRows(rows_out_str);
-               pdxlpropDTS->GetDXLOperatorCost()->SetCost(pstrCost);
-               dxl_properties->Release();
-       }
-       GPOS_ASSERT(nullptr != pexprDTS->Prpp());
-
-       // construct projection list for top-level Append node
-       CColRefSet *pcrsOutput = pexprDTS->Prpp()->PcrsRequired();
-       CDXLNode *pdxlnPrLAppend = PdxlnProjList(pcrsOutput, colref_array);
-       CDXLTableDescr *root_dxl_table_descr = MakeDXLTableDescr(
-               popDTS->Ptabdesc(), popDTS->PdrgpcrOutput(), pexprDTS->Prpp());
-
-       // Construct the Append node - even when there is only one child 
partition.
-       // This is done for two reasons:
-       // * Dynamic partition pruning
-       //   Even if one partition is present in the statically pruned plan, we 
could
-       //   still dynamically prune it away. This needs an Append node.
-       // * Col mappings issues
-       //   When the first selected child partition's cols have different 
types/order
-       //   than the root partition, we can no longer re-use the colrefs of 
the root
-       //   partition, since colrefs are immutable. Thus, we create new 
colrefs for
-       //   this partition. But, if there is no Append (in case of just one 
selected
-       //   partition), then we also go through update all references above 
the DTS
-       //   with the new colrefs. For simplicity, we decided to keep the Append
-       //   around to maintain this projection (mapping) from the old root 
colrefs
-       //   to the first selected partition colrefs.
-       //
-       // GPDB_12_MERGE_FIXME: An Append on a single TableScan can be removed 
in
-       // CTranslatorDXLToPlstmt since these points do not apply there.
-       CDXLNode *pdxlnAppend = GPOS_NEW(m_mp) CDXLNode(
-               m_mp,
-               GPOS_NEW(m_mp) CDXLPhysicalAppend(m_mp, false, false, 
popDTS->ScanId(),
-                                                                               
  root_dxl_table_descr, selector_ids));
-       pdxlnAppend->SetProperties(pdxlpropDTS);
-       pdxlnAppend->AddChild(pdxlnPrLAppend);
-       pdxlnAppend->AddChild(PdxlnFilter(nullptr));
-
-       IMdIdArray *part_mdids = popDTS->GetPartitionMdids();
-       for (ULONG ul = 0; ul < part_mdids->Size(); ++ul)
-       {
-               IMDId *part_mdid = (*part_mdids)[ul];
-               const IMDRelation *part = m_pmda->RetrieveRel(part_mdid);
-
-               CTableDescriptor *part_tabdesc =
-                       MakeTableDescForPart(part, popDTS->Ptabdesc());
-
-               // 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_col = 0; ul_col < part_tabdesc->ColumnCount(); 
++ul_col)
-               {
-                       const CColumnDescriptor *cd = 
part_tabdesc->Pcoldesc(ul_col);
-                       CColRef *cr = m_pcf->PcrCreate(cd->RetrieveType(),
-                                                                               
   cd->TypeModifier(), cd->Name());
-                       part_colrefs->Append(cr);
-               }
-
-               CDXLTableDescr *dxl_table_descr =
-                       MakeDXLTableDescr(part_tabdesc, part_colrefs, 
pexprDTS->Prpp());
-               part_tabdesc->Release();
-
-               CDXLNode *dxlnode = GPOS_NEW(m_mp) CDXLNode(
-                       m_mp, GPOS_NEW(m_mp) CDXLPhysicalTableScan(m_mp, 
dxl_table_descr));
-
-               // GPDB_12_MERGE_FIXME: Compute stats & properties per scan
-               pdxlpropDTS->AddRef();
-               dxlnode->SetProperties(pdxlpropDTS);
-
-               // ColRef -> index in child table desc (per partition)
-               auto root_col_mapping = 
(*popDTS->GetRootColMappingPerPart())[ul];
-
-               // construct projection list, re-ordered to match root DTS
-               CDXLNode *pdxlnPrL = PdxlnProjListForChildPart(
-                       root_col_mapping, part_colrefs, pcrsOutput, 
colref_array);
-               dxlnode->AddChild(pdxlnPrL);  // project list
-
-               // construct the filter
-               CDXLNode *filter_dxlnode = PdxlnFilter(
-                       PdxlnCondForChildPart(root_col_mapping, part_colrefs,
-                                                                 
popDTS->PdrgpcrOutput(), pexprScalarCond));
-               dxlnode->AddChild(filter_dxlnode);      // filter
-
-               // add to the other scans under the created Append node
-               pdxlnAppend->AddChild(dxlnode);
-
-               // cleanup
-               part_colrefs->Release();
-       }
-
-       CDistributionSpec *pds = pexprDTS->GetDrvdPropPlan()->Pds();
-       pds->AddRef();
-       pdrgpdsBaseTables->Append(pds);
-
-       GPOS_ASSERT(pdxlnAppend);
-       return pdxlnAppend;
-
- */
 }
 
 //---------------------------------------------------------------------------
diff --git 
a/src/backend/gporca/libnaucrates/include/naucrates/dxl/operators/CDXLPhysicalDynamicTableScan.h
 
b/src/backend/gporca/libnaucrates/include/naucrates/dxl/operators/CDXLPhysicalDynamicTableScan.h
index f0b46d9b3f..786659e3af 100644
--- 
a/src/backend/gporca/libnaucrates/include/naucrates/dxl/operators/CDXLPhysicalDynamicTableScan.h
+++ 
b/src/backend/gporca/libnaucrates/include/naucrates/dxl/operators/CDXLPhysicalDynamicTableScan.h
@@ -44,19 +44,17 @@ private:
        // table descriptor for the scanned table
        CDXLTableDescr *m_dxl_table_descr;
 
-       // 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:
        CDXLPhysicalDynamicTableScan(CDXLPhysicalDynamicTableScan &) = delete;
 
        // ctor
        CDXLPhysicalDynamicTableScan(CMemoryPool *mp, CDXLTableDescr 
*table_descr,
-                                                                ULONG 
part_idx_id,
-                                                                ULONG 
part_idx_id_printable);
+                                                                IMdIdArray 
*part_mdids,
+                                                                ULongPtrArray 
*selector_ids);
 
        // dtor
        ~CDXLPhysicalDynamicTableScan() override;
@@ -70,12 +68,13 @@ public:
        // table descriptor
        const CDXLTableDescr *GetDXLTableDescr() const;
 
-       // partition index id
-       ULONG GetPartIndexId() const;
-
-       // printable partition index id
-       ULONG GetPartIndexIdPrintable() 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/CParseHandlerDynamicTableScan.h
 
b/src/backend/gporca/libnaucrates/include/naucrates/dxl/parser/CParseHandlerDynamicTableScan.h
index 8b5b1d6b4a..c3c1969451 100644
--- 
a/src/backend/gporca/libnaucrates/include/naucrates/dxl/parser/CParseHandlerDynamicTableScan.h
+++ 
b/src/backend/gporca/libnaucrates/include/naucrates/dxl/parser/CParseHandlerDynamicTableScan.h
@@ -36,11 +36,7 @@ class CDXLPhysicalDynamicTableScan;
 class CParseHandlerDynamicTableScan : public CParseHandlerPhysicalOp
 {
 private:
-       // the id of the partition index structure
-       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/src/operators/CDXLPhysicalDynamicTableScan.cpp
 
b/src/backend/gporca/libnaucrates/src/operators/CDXLPhysicalDynamicTableScan.cpp
index f5dc4d0ae1..4731259db0 100644
--- 
a/src/backend/gporca/libnaucrates/src/operators/CDXLPhysicalDynamicTableScan.cpp
+++ 
b/src/backend/gporca/libnaucrates/src/operators/CDXLPhysicalDynamicTableScan.cpp
@@ -12,8 +12,10 @@
 
 #include "naucrates/dxl/operators/CDXLPhysicalDynamicTableScan.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;
@@ -28,12 +30,13 @@ using namespace gpdxl;
 //
 //---------------------------------------------------------------------------
 CDXLPhysicalDynamicTableScan::CDXLPhysicalDynamicTableScan(
-       CMemoryPool *mp, CDXLTableDescr *table_descr, ULONG part_idx_id,
-       ULONG part_idx_id_printable)
+       CMemoryPool *mp, CDXLTableDescr *table_descr, 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_part_mdids(part_mdids),
+         m_selector_ids(selector_ids)
+
 {
        GPOS_ASSERT(nullptr != table_descr);
 }
@@ -50,6 +53,8 @@ CDXLPhysicalDynamicTableScan::CDXLPhysicalDynamicTableScan(
 CDXLPhysicalDynamicTableScan::~CDXLPhysicalDynamicTableScan()
 {
        m_dxl_table_descr->Release();
+       m_part_mdids->Release();
+       CRefCount::SafeRelease(m_selector_ids);
 }
 
 //---------------------------------------------------------------------------
@@ -95,32 +100,10 @@ CDXLPhysicalDynamicTableScan::GetDXLTableDescr() const
        return m_dxl_table_descr;
 }
 
-//---------------------------------------------------------------------------
-//     @function:
-//             CDXLPhysicalDynamicTableScan::GetPartIndexId
-//
-//     @doc:
-//             Id of partition index
-//
-//---------------------------------------------------------------------------
-ULONG
-CDXLPhysicalDynamicTableScan::GetPartIndexId() const
-{
-       return m_part_index_id;
-}
-
-//---------------------------------------------------------------------------
-//     @function:
-//             CDXLPhysicalDynamicTableScan::GetPartIndexIdPrintable
-//
-//     @doc:
-//             Printable partition index id
-//
-//---------------------------------------------------------------------------
-ULONG
-CDXLPhysicalDynamicTableScan::GetPartIndexIdPrintable() const
+IMdIdArray *
+CDXLPhysicalDynamicTableScan::GetParts() const
 {
-       return m_part_index_id_printable;
+       return m_part_mdids;
 }
 
 //---------------------------------------------------------------------------
@@ -139,16 +122,18 @@ 
CDXLPhysicalDynamicTableScan::SerializeToDXL(CXMLSerializer *xml_serializer,
 
        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(
                CDXLTokens::GetDXLTokenStr(EdxltokenNamespacePrefix), 
element_name);
diff --git 
a/src/backend/gporca/libnaucrates/src/parser/CParseHandlerDynamicTableScan.cpp 
b/src/backend/gporca/libnaucrates/src/parser/CParseHandlerDynamicTableScan.cpp
index 8cfd57a3a4..9c78c4549e 100644
--- 
a/src/backend/gporca/libnaucrates/src/parser/CParseHandlerDynamicTableScan.cpp
+++ 
b/src/backend/gporca/libnaucrates/src/parser/CParseHandlerDynamicTableScan.cpp
@@ -16,6 +16,7 @@
 #include "naucrates/dxl/operators/CDXLPhysicalDynamicTableScan.h"
 #include "naucrates/dxl/parser/CParseHandlerFactory.h"
 #include "naucrates/dxl/parser/CParseHandlerFilter.h"
+#include "naucrates/dxl/parser/CParseHandlerMetadataIdList.h"
 #include "naucrates/dxl/parser/CParseHandlerProjList.h"
 #include "naucrates/dxl/parser/CParseHandlerProperties.h"
 #include "naucrates/dxl/parser/CParseHandlerTableDescr.h"
@@ -67,17 +68,10 @@ CParseHandlerDynamicTableScan::StartElement(
                                   str->GetBuffer());
        }
 
-       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,
                EdxltokenPhysicalDynamicTableScan);
 
-       m_part_index_id_printable =
-               CDXLOperatorFactory::ExtractConvertAttrValueToUlong(
-                       m_parse_handler_mgr->GetDXLMemoryManager(), attrs,
-                       EdxltokenPartIndexIdPrintable, 
EdxltokenPhysicalDynamicTableScan,
-                       true,  //is_optional
-                       m_part_index_id);
-
        // create child node parsers in reverse order of their expected 
occurrence
 
        // parse handler for table descriptor
@@ -87,6 +81,13 @@ CParseHandlerDynamicTableScan::StartElement(
                        m_parse_handler_mgr, this);
        m_parse_handler_mgr->ActivateParseHandler(table_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 filter
        CParseHandlerBase *filter_parse_handler =
                CParseHandlerFactory::GetParseHandler(
@@ -112,6 +113,7 @@ CParseHandlerDynamicTableScan::StartElement(
        this->Append(prop_parse_handler);
        this->Append(proj_list_parse_handler);
        this->Append(filter_parse_handler);
+       this->Append(partition_mdids_parse_handler);
        this->Append(table_descr_parse_handler);
 }
 
@@ -146,16 +148,22 @@ CParseHandlerDynamicTableScan::EndElement(const XMLCh 
*const,  // element_uri,
                dynamic_cast<CParseHandlerProjList *>((*this)[1]);
        CParseHandlerFilter *filter_parse_handler =
                dynamic_cast<CParseHandlerFilter *>((*this)[2]);
+       CParseHandlerMetadataIdList *partition_mdids_parse_handler =
+               dynamic_cast<CParseHandlerMetadataIdList *>((*this)[3]);
        CParseHandlerTableDescr *table_descr_parse_handler =
-               dynamic_cast<CParseHandlerTableDescr *>((*this)[3]);
+               dynamic_cast<CParseHandlerTableDescr *>((*this)[4]);
 
 
        // set table descriptor
        CDXLTableDescr *table_descr = 
table_descr_parse_handler->GetDXLTableDescr();
        table_descr->AddRef();
+
+       IMdIdArray *mdid_partitions_array =
+               partition_mdids_parse_handler->GetMdIdArray();
+       mdid_partitions_array->AddRef();
        CDXLPhysicalDynamicTableScan *dxl_op =
                GPOS_NEW(m_mp) CDXLPhysicalDynamicTableScan(
-                       m_mp, table_descr, m_part_index_id, 
m_part_index_id_printable);
+                       m_mp, table_descr, mdid_partitions_array, 
m_selector_ids);
 
        m_dxl_node = GPOS_NEW(m_mp) CDXLNode(m_mp, dxl_op);
        // set statictics and physical properties
diff --git a/src/include/executor/execDynamicScan.h 
b/src/include/executor/execDynamicScan.h
deleted file mode 100644
index f41ae5d34c..0000000000
--- a/src/include/executor/execDynamicScan.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*--------------------------------------------------------------------------
- *
- * execDynamicScan.h
- *      Definitions and API functions for execDynamicScan.c
- *
- * Copyright (c) 2014-Present VMware, Inc. or its affiliates.
- *
- *
- * IDENTIFICATION
- *         src/include/executor/execDynamicScan.h
- *
- *--------------------------------------------------------------------------
- */
-#ifndef EXECDYNAMICSCAN_H
-#define EXECDYNAMICSCAN_H
-
-#include "access/attnum.h"
-#include "nodes/execnodes.h"
-
-extern bool isDynamicScan(const Plan *p);
-extern int DynamicScan_GetDynamicScanIdPrintable(Plan *plan);
-
-extern Oid DynamicScan_GetTableOid(ScanState *scanState);
-extern void DynamicScan_SetTableOid(ScanState *scanState, Oid curRelOid);
-
-extern bool DynamicScan_RemapExpression(ScanState *scanState, AttrNumber 
*attMap, Node *expr);
-
-#endif   /* EXECDYNAMICSCAN_H */


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

Reply via email to