本文整理汇总了C++中DrgPul::UlLength方法的典型用法代码示例。如果您正苦于以下问题:C++ DrgPul::UlLength方法的具体用法?C++ DrgPul::UlLength怎么用?C++ DrgPul::UlLength使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类DrgPul
的用法示例。
在下文中一共展示了DrgPul::UlLength方法的10个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: DrgULONG
//---------------------------------------------------------------------------
// @function:
// CDynamicPtrArrayTest::EresUnittest_PdrgpulSubsequenceIndexes
//
// @doc:
// Finding the first occurrences of the elements of the first array
// in the second one.
//
//---------------------------------------------------------------------------
GPOS_RESULT
CDynamicPtrArrayTest::EresUnittest_PdrgpulSubsequenceIndexes()
{
typedef CDynamicPtrArray<ULONG, CleanupNULL<ULONG> > DrgULONG;
CAutoMemoryPool amp;
IMemoryPool *pmp = amp.Pmp();
// the array containing elements to look up
DrgULONG *pdrgULONGLookup = GPOS_NEW(pmp) DrgULONG(pmp);
// the array containing the target elements that will give the positions
DrgULONG *pdrgULONGTarget = GPOS_NEW(pmp) DrgULONG(pmp);
ULONG *pul1 = GPOS_NEW(pmp) ULONG(10);
ULONG *pul2 = GPOS_NEW(pmp) ULONG(20);
ULONG *pul3 = GPOS_NEW(pmp) ULONG(30);
pdrgULONGLookup->Append(pul1);
pdrgULONGLookup->Append(pul2);
pdrgULONGLookup->Append(pul3);
pdrgULONGLookup->Append(pul3);
// since target is empty, there are elements in lookup with no match, so the function
// should return NULL
GPOS_ASSERT(NULL ==
CDynamicPtrArrayUtils::PdrgpulSubsequenceIndexes(pmp, pdrgULONGLookup, pdrgULONGTarget));
pdrgULONGTarget->Append(pul1);
pdrgULONGTarget->Append(pul3);
pdrgULONGTarget->Append(pul3);
pdrgULONGTarget->Append(pul3);
pdrgULONGTarget->Append(pul2);
DrgPul *pdrgpulIndexes =
CDynamicPtrArrayUtils::PdrgpulSubsequenceIndexes(pmp, pdrgULONGLookup, pdrgULONGTarget);
GPOS_ASSERT(NULL != pdrgpulIndexes);
GPOS_ASSERT(4 == pdrgpulIndexes->UlLength());
GPOS_ASSERT(0 == *(*pdrgpulIndexes)[0]);
GPOS_ASSERT(4 == *(*pdrgpulIndexes)[1]);
GPOS_ASSERT(1 == *(*pdrgpulIndexes)[2]);
GPOS_ASSERT(1 == *(*pdrgpulIndexes)[3]);
GPOS_DELETE(pul1);
GPOS_DELETE(pul2);
GPOS_DELETE(pul3);
pdrgpulIndexes->Release();
pdrgULONGTarget->Release();
pdrgULONGLookup->Release();
return GPOS_OK;
}
示例2: GPOS_NEW
//---------------------------------------------------------------------------
// @function:
// CPhysicalMotion::PppsRequired
//
// @doc:
// Compute required partition propagation of the n-th child
//
//---------------------------------------------------------------------------
CPartitionPropagationSpec *
CPhysicalMotion::PppsRequired
(
IMemoryPool *pmp,
CExpressionHandle &exprhdl,
CPartitionPropagationSpec *pppsRequired,
ULONG
#ifdef GPOS_DEBUG
ulChildIndex
#endif // GPOS_DEBUG
,
DrgPdp *, //pdrgpdpCtxt,
ULONG //ulOptReq
)
{
GPOS_ASSERT(0 == ulChildIndex);
GPOS_ASSERT(NULL != pppsRequired);
CPartIndexMap *ppimReqd = pppsRequired->Ppim();
CPartFilterMap *ppfmReqd = pppsRequired->Ppfm();
DrgPul *pdrgpul = ppimReqd->PdrgpulScanIds(pmp);
CPartIndexMap *ppimResult = GPOS_NEW(pmp) CPartIndexMap(pmp);
CPartFilterMap *ppfmResult = GPOS_NEW(pmp) CPartFilterMap(pmp);
/// get derived part consumers
CPartInfo *ppartinfo = exprhdl.Pdprel(0)->Ppartinfo();
const ULONG ulPartIndexSize = pdrgpul->UlLength();
for (ULONG ul = 0; ul < ulPartIndexSize; ul++)
{
ULONG ulPartIndexId = *((*pdrgpul)[ul]);
if (!ppartinfo->FContainsScanId(ulPartIndexId))
{
// part index id does not exist in child nodes: do not push it below
// the motion
continue;
}
ppimResult->AddRequiredPartPropagation(ppimReqd, ulPartIndexId, CPartIndexMap::EppraPreservePropagators);
(void) ppfmResult->FCopyPartFilter(m_pmp, ulPartIndexId, ppfmReqd);
}
pdrgpul->Release();
return GPOS_NEW(pmp) CPartitionPropagationSpec(ppimResult, ppfmResult);
}
示例3: DrgPul
//---------------------------------------------------------------------------
// @function:
// CPhysicalUnionAll::PdrgpulMap
//
// @doc:
// Map given array of scalar identifier expressions to positions of
// UnionAll input columns in the given child;
// the function returns NULL if no mapping could be constructed
//
//---------------------------------------------------------------------------
DrgPul *
CPhysicalUnionAll::PdrgpulMap
(
IMemoryPool *pmp,
DrgPexpr *pdrgpexpr,
ULONG ulChildIndex
)
const
{
GPOS_ASSERT(NULL != pdrgpexpr);
DrgPcr *pdrgpcr = (*m_pdrgpdrgpcrInput)[ulChildIndex];
const ULONG ulExprs = pdrgpexpr->UlLength();
const ULONG ulCols = pdrgpcr->UlLength();
DrgPul *pdrgpul = GPOS_NEW(pmp) DrgPul(pmp);
for (ULONG ulExpr = 0; ulExpr < ulExprs; ulExpr++)
{
CExpression *pexpr = (*pdrgpexpr)[ulExpr];
if (COperator::EopScalarIdent != pexpr->Pop()->Eopid())
{
continue;
}
const CColRef *pcr = CScalarIdent::PopConvert(pexpr->Pop())->Pcr();
for (ULONG ulCol = 0; ulCol < ulCols; ulCol++)
{
if ((*pdrgpcr)[ulCol] == pcr)
{
pdrgpul->Append(GPOS_NEW(pmp) ULONG(ulCol));
}
}
}
if (0 == pdrgpul->UlLength())
{
// mapping failed
pdrgpul->Release();
pdrgpul = NULL;
}
return pdrgpul;
}
示例4:
//---------------------------------------------------------------------------
// @function:
// CParseHandlerTraceFlags::StartElement
//
// @doc:
// Invoked by Xerces to process an opening tag
//
//---------------------------------------------------------------------------
void
CParseHandlerTraceFlags::StartElement
(
const XMLCh* const , //xmlszUri,
const XMLCh* const xmlszLocalname,
const XMLCh* const , //xmlszQname,
const Attributes& attrs
)
{
if(0 != XMLString::compareString(CDXLTokens::XmlstrToken(EdxltokenTraceFlags), xmlszLocalname))
{
CWStringDynamic *pstr = CDXLUtils::PstrFromXMLCh(m_pphm->Pmm(), xmlszLocalname);
GPOS_RAISE(gpdxl::ExmaDXL, gpdxl::ExmiDXLUnexpectedTag, pstr->Wsz());
}
// parse and tokenize traceflags
const XMLCh *xmlszTraceFlags = CDXLOperatorFactory::XmlstrFromAttrs
(
attrs,
EdxltokenValue,
EdxltokenTraceFlags
);
DrgPul *pdrgpul = CDXLOperatorFactory::PdrgpulFromXMLCh
(
m_pphm->Pmm(),
xmlszTraceFlags,
EdxltokenDistrColumns,
EdxltokenRelation
);
for (ULONG ul = 0; ul < pdrgpul->UlLength(); ul++)
{
ULONG *pul = (*pdrgpul)[ul];
m_pbs->FExchangeSet(*pul);
}
pdrgpul->Release();
}
示例5: hmcri
//---------------------------------------------------------------------------
// @function:
// CCTEReq::PcterUnresolvedSequence
//
// @doc:
// Unresolved CTE requirements given a derived CTE map for a sequence
// operator
//
//---------------------------------------------------------------------------
CCTEReq *
CCTEReq::PcterUnresolvedSequence
(
IMemoryPool *pmp,
CCTEMap *pcm,
DrgPdp *pdrgpdpCtxt // context contains derived plan properties of producer tree
)
{
GPOS_ASSERT(NULL != pcm);
CCTEReq *pcterUnresolved = GPOS_NEW(pmp) CCTEReq(pmp);
HMCteReqIter hmcri(m_phmcter);
while (hmcri.FAdvance())
{
const CCTEReqEntry *pcre = hmcri.Pt();
ULONG ulId = pcre->UlId();
CCTEMap::ECteType ect = pcre->Ect();
BOOL fRequired = pcre->FRequired();
CCTEMap::ECteType ectDrvd = pcm->Ect(ulId);
if (fRequired && CCTEMap::EctSentinel != ectDrvd)
{
GPOS_ASSERT(CCTEMap::EctConsumer == ect);
GPOS_ASSERT(CCTEMap::EctConsumer == ectDrvd);
// already found, so mark it as optional
CDrvdPropPlan *pdpplan = pcre->PdpplanProducer();
GPOS_ASSERT(NULL != pdpplan);
pdpplan->AddRef();
pcterUnresolved->Insert(ulId, ect, false /*fReqiored*/, pdpplan);
}
else if (!fRequired && CCTEMap::EctProducer == ect && CCTEMap::EctSentinel != ectDrvd)
{
GPOS_ASSERT(CCTEMap::EctProducer == ectDrvd);
// found a producer. require the corresponding consumer and
// extract producer plan properties from passed context
pcterUnresolved->InsertConsumer(ulId, pdrgpdpCtxt);
}
else
{
// either required and not found yet, or optional
// in both cases, pass it down as is
CDrvdPropPlan *pdpplan = pcre->PdpplanProducer();
GPOS_ASSERT_IMP(NULL == pdpplan, CCTEMap::EctProducer == ect);
if (NULL != pdpplan)
{
pdpplan->AddRef();
}
pcterUnresolved->Insert(ulId, ect, fRequired, pdpplan);
}
}
// if something is in pcm and not in the requirments, it has to be a producer
// in which case, add the corresponding consumer as unresolved
DrgPul *pdrgpulProducers = pcm->PdrgpulAdditionalProducers(pmp, this);
const ULONG ulLen = pdrgpulProducers->UlLength();
for (ULONG ul = 0; ul < ulLen; ul++)
{
ULONG *pulId = (*pdrgpulProducers)[ul];
pcterUnresolved->InsertConsumer(*pulId, pdrgpdpCtxt);
}
pdrgpulProducers->Release();
return pcterUnresolved;
}
示例6: HMUlExpr
//---------------------------------------------------------------------------
// @function:
// CPartitionPropagationSpec::AppendEnforcers
//
// @doc:
// Add required enforcers to dynamic array
//
//---------------------------------------------------------------------------
void
CPartitionPropagationSpec::AppendEnforcers
(
IMemoryPool *pmp,
CExpressionHandle &exprhdl,
CReqdPropPlan *
#ifdef GPOS_DEBUG
prpp
#endif // GPOS_DEBUG
,
DrgPexpr *pdrgpexpr,
CExpression *pexpr
)
{
GPOS_ASSERT(NULL != prpp);
GPOS_ASSERT(NULL != pmp);
GPOS_ASSERT(NULL != pdrgpexpr);
GPOS_ASSERT(NULL != pexpr);
DrgPul *pdrgpul = m_ppim->PdrgpulScanIds(pmp);
const ULONG ulSize = pdrgpul->UlLength();
for (ULONG ul = 0; ul < ulSize; ul++)
{
ULONG ulScanId = *((*pdrgpul)[ul]);
GPOS_ASSERT(m_ppim->FContains(ulScanId));
if (CPartIndexMap::EpimConsumer != m_ppim->Epim(ulScanId) || 0 < m_ppim->UlExpectedPropagators(ulScanId))
{
continue;
}
if (!FRequiresPartitionPropagation(pmp, pexpr, exprhdl, ulScanId))
{
continue;
}
CExpression *pexprResolver = NULL;
IMDId *pmdid = m_ppim->PmdidRel(ulScanId);
DrgDrgPcr *pdrgpdrgpcrKeys = NULL;
DrgPpartkeys *pdrgppartkeys = m_ppim->Pdrgppartkeys(ulScanId);
CPartConstraint *ppartcnstr = m_ppim->PpartcnstrRel(ulScanId);
PartCnstrMap *ppartcnstrmap = m_ppim->Ppartcnstrmap(ulScanId);
pmdid->AddRef();
ppartcnstr->AddRef();
ppartcnstrmap->AddRef();
pexpr->AddRef();
// check if there is a predicate on this part index id
HMUlExpr *phmulexprEqFilter = GPOS_NEW(pmp) HMUlExpr(pmp);
HMUlExpr *phmulexprFilter = GPOS_NEW(pmp) HMUlExpr(pmp);
CExpression *pexprResidual = NULL;
if (m_ppfm->FContainsScanId(ulScanId))
{
CExpression *pexprScalar = PexprFilter(pmp, ulScanId);
// find out which keys are used in the predicate, in case there are multiple
// keys at this point (e.g. from a union of multiple CTE consumers)
CColRefSet *pcrsUsed = CDrvdPropScalar::Pdpscalar(pexprScalar->PdpDerive())->PcrsUsed();
const ULONG ulKeysets = pdrgppartkeys->UlLength();
for (ULONG ulKey = 0; NULL == pdrgpdrgpcrKeys && ulKey < ulKeysets; ulKey++)
{
// get partition key
CPartKeys *ppartkeys = (*pdrgppartkeys)[ulKey];
if (ppartkeys->FOverlap(pcrsUsed))
{
pdrgpdrgpcrKeys = ppartkeys->Pdrgpdrgpcr();
}
}
// if we cannot find partition keys mapping the partition predicates, fall back to planner
if (NULL == pdrgpdrgpcrKeys)
{
GPOS_RAISE(gpopt::ExmaGPOPT, gpopt::ExmiUnsatisfiedRequiredProperties);
}
pdrgpdrgpcrKeys->AddRef();
// split predicates and put them in the appropriate hashmaps
SplitPartPredicates(pmp, pexprScalar, pdrgpdrgpcrKeys, phmulexprEqFilter, phmulexprFilter, &pexprResidual);
pexprScalar->Release();
}
else
{
// doesn't matter which keys we use here since there is no filter
GPOS_ASSERT(1 <= pdrgppartkeys->UlLength());
pdrgpdrgpcrKeys = (*pdrgppartkeys)[0]->Pdrgpdrgpcr();
pdrgpdrgpcrKeys->AddRef();
}
pexprResolver = GPOS_NEW(pmp) CExpression
//.........这里部分代码省略.........
示例7: GPOS_NEW
//---------------------------------------------------------------------------
// @function:
// CPhysicalPartitionSelector::PppsRequired
//
// @doc:
// Compute required partition propagation of the n-th child
//
//---------------------------------------------------------------------------
CPartitionPropagationSpec *
CPhysicalPartitionSelector::PppsRequired
(
IMemoryPool *pmp,
CExpressionHandle & exprhdl,
CPartitionPropagationSpec *pppsRequired,
ULONG
#ifdef GPOS_DEBUG
ulChildIndex
#endif // GPOS_DEBUG
,
DrgPdp *, //pdrgpdpCtxt,
ULONG //ulOptReq
)
{
GPOS_ASSERT(0 == ulChildIndex);
GPOS_ASSERT(NULL != pppsRequired);
CPartIndexMap *ppimInput = pppsRequired->Ppim();
CPartFilterMap *ppfmInput = pppsRequired->Ppfm();
DrgPul *pdrgpulInputScanIds = ppimInput->PdrgpulScanIds(pmp);
CPartIndexMap *ppim = GPOS_NEW(pmp) CPartIndexMap(pmp);
CPartFilterMap *ppfm = GPOS_NEW(pmp) CPartFilterMap(pmp);
CPartInfo *ppartinfo = exprhdl.Pdprel(0)->Ppartinfo();
const ULONG ulScanIds = pdrgpulInputScanIds->UlLength();
for (ULONG ul = 0; ul < ulScanIds; ul++)
{
ULONG ulScanId = *((*pdrgpulInputScanIds)[ul]);
ULONG ulExpectedPropagators = ppimInput->UlExpectedPropagators(ulScanId);
if (ulScanId == m_ulScanId)
{
// partition propagation resolved - do not need to require from children
continue;
}
if (!ppartinfo->FContainsScanId(ulScanId) && ppartinfo->FContainsScanId(m_ulScanId))
{
// dynamic scan for the required id not defined below, but the current one is: do not push request down
continue;
}
IMDId *pmdid = ppimInput->PmdidRel(ulScanId);
DrgPpartkeys *pdrgppartkeys = ppimInput->Pdrgppartkeys(ulScanId);
PartCnstrMap *ppartcnstrmap = ppimInput->Ppartcnstrmap(ulScanId);
CPartConstraint *ppartcnstr = ppimInput->PpartcnstrRel(ulScanId);
CPartIndexMap::EPartIndexManipulator epim = ppimInput->Epim(ulScanId);
pmdid->AddRef();
pdrgppartkeys->AddRef();
ppartcnstrmap->AddRef();
ppartcnstr->AddRef();
ppim->Insert(ulScanId, ppartcnstrmap, epim, ulExpectedPropagators, pmdid, pdrgppartkeys, ppartcnstr);
(void) ppfm->FCopyPartFilter(m_pmp, ulScanId, ppfmInput);
}
// cleanup
pdrgpulInputScanIds->Release();
return GPOS_NEW(pmp) CPartitionPropagationSpec(ppim, ppfm);
}
示例8:
//---------------------------------------------------------------------------
// @function:
// CPhysicalUnionAll::EpetPartitionPropagation
//
// @doc:
// Compute the enforcing type for the operator
//
//---------------------------------------------------------------------------
CEnfdProp::EPropEnforcingType
CPhysicalUnionAll::EpetPartitionPropagation
(
CExpressionHandle &exprhdl,
const CEnfdPartitionPropagation *pepp
)
const
{
CPartIndexMap *ppimReqd = pepp->PppsRequired()->Ppim();
if (!ppimReqd->FContainsUnresolved())
{
// no unresolved partition consumers left
return CEnfdProp::EpetUnnecessary;
}
CPartIndexMap *ppimDrvd = CDrvdPropPlan::Pdpplan(exprhdl.Pdp())->Ppim();
GPOS_ASSERT(NULL != ppimDrvd);
BOOL fInScope = pepp->FInScope(m_pmp, ppimDrvd);
BOOL fResolved = pepp->FResolved(m_pmp, ppimDrvd);
if (fResolved)
{
// all required partition consumers are resolved
return CEnfdProp::EpetUnnecessary;
}
if (!fInScope)
{
// some partition consumers are not covered downstream
return CEnfdProp::EpetRequired;
}
DrgPul *pdrgpul = ppimReqd->PdrgpulScanIds(m_pmp);
const ULONG ulScanIds = pdrgpul->UlLength();
const ULONG ulArity = exprhdl.UlNonScalarChildren();
for (ULONG ul = 0; ul < ulScanIds; ul++)
{
ULONG ulScanId = *((*pdrgpul)[ul]);
ULONG ulChildrenWithConsumers = 0;
for (ULONG ulChildIdx = 0; ulChildIdx < ulArity; ulChildIdx++)
{
if (exprhdl.Pdprel(ulChildIdx)->Ppartinfo()->FContainsScanId(ulScanId))
{
ulChildrenWithConsumers++;
}
}
if (1 < ulChildrenWithConsumers)
{
// partition consumer exists in more than one child, so enforce it here
pdrgpul->Release();
return CEnfdProp::EpetRequired;
}
}
pdrgpul->Release();
// required part propagation can be enforced here or passed to the children
return CEnfdProp::EpetOptional;
}
示例9: PppsRequiredPushThruNAry
//---------------------------------------------------------------------------
// @function:
// CPhysicalNLJoin::PppsRequiredNLJoinChild
//
// @doc:
// Compute required partition propagation of the n-th child
//
//---------------------------------------------------------------------------
CPartitionPropagationSpec *
CPhysicalNLJoin::PppsRequiredNLJoinChild
(
IMemoryPool *pmp,
CExpressionHandle &exprhdl,
CPartitionPropagationSpec *pppsRequired,
ULONG ulChildIndex,
DrgPdp *, //pdrgpdpCtxt,
ULONG ulOptReq
)
{
GPOS_ASSERT(NULL != pppsRequired);
if (1 == ulOptReq)
{
// request (1): push partition propagation requests to join's children,
// do not consider possible dynamic partition elimination using join predicate here,
// this is handled by optimization request (0) below
return CPhysical::PppsRequiredPushThruNAry(pmp, exprhdl, pppsRequired, ulChildIndex);
}
GPOS_ASSERT(0 == ulOptReq);
CPartIndexMap *ppim = pppsRequired->Ppim();
CPartFilterMap *ppfm = pppsRequired->Ppfm();
DrgPul *pdrgpul = ppim->PdrgpulScanIds(pmp);
CPartIndexMap *ppimResult = GPOS_NEW(pmp) CPartIndexMap(pmp);
CPartFilterMap *ppfmResult = GPOS_NEW(pmp) CPartFilterMap(pmp);
CPartInfo *ppartinfoOuter = exprhdl.Pdprel(0)->Ppartinfo();
CColRefSet *pcrsOutputOuter = exprhdl.Pdprel(0)->PcrsOutput();
CColRefSet *pcrsOutputInner = exprhdl.Pdprel(1)->PcrsOutput();
const ULONG ulPartIndexIds = pdrgpul->UlLength();
for (ULONG ul = 0; ul < ulPartIndexIds; ul++)
{
ULONG ulPartIndexId = *((*pdrgpul)[ul]);
if (ppfm->FContainsScanId(ulPartIndexId))
{
GPOS_ASSERT(NULL != ppfm->Pexpr(ulPartIndexId));
// a selection-based propagation request pushed from above: do not propagate any
// further as the join will reduce cardinality and thus may select more partitions
// for scanning
continue;
}
BOOL fOuterPartConsumer = ppartinfoOuter->FContainsScanId(ulPartIndexId);
// in order to find interesting join predicates that can be used for DPE,
// one side of the predicate must be the partition key, while the other side must only contain
// references from the join child that does not have the partition consumer
CColRefSet *pcrsAllowedRefs = pcrsOutputOuter;
if (fOuterPartConsumer)
{
pcrsAllowedRefs = pcrsOutputInner;
}
if (0 == ulChildIndex && fOuterPartConsumer)
{
// always push through required partition propagation for consumers on the
// outer side of the nested loop join
DrgPpartkeys *pdrgppartkeys = ppartinfoOuter->PdrgppartkeysByScanId(ulPartIndexId);
GPOS_ASSERT(NULL != pdrgppartkeys);
pdrgppartkeys->AddRef();
ppimResult->AddRequiredPartPropagation(ppim, ulPartIndexId, CPartIndexMap::EppraPreservePropagators, pdrgppartkeys);
}
else
{
// check if there is an interesting condition involving the partition key
CExpression *pexprScalar = exprhdl.PexprScalarChild(2 /*ulChildIndex*/);
AddFilterOnPartKey(pmp, true /*fNLJoin*/, pexprScalar, ppim, ppfm, ulChildIndex, ulPartIndexId, fOuterPartConsumer, ppimResult, ppfmResult, pcrsAllowedRefs);
}
}
pdrgpul->Release();
return GPOS_NEW(pmp) CPartitionPropagationSpec(ppimResult, ppfmResult);
}
示例10: GPOS_NEW
//---------------------------------------------------------------------------
// @function:
// CPhysicalHashJoin::PppsRequiredCompute
//
// @doc:
// Compute required partition propagation of the n-th child
//
//---------------------------------------------------------------------------
CPartitionPropagationSpec *
CPhysicalHashJoin::PppsRequiredCompute
(
IMemoryPool *pmp,
CExpressionHandle &exprhdl,
CPartitionPropagationSpec *pppsRequired,
ULONG ulChildIndex
)
{
CPartIndexMap *ppim = pppsRequired->Ppim();
CPartFilterMap *ppfm = pppsRequired->Ppfm();
DrgPul *pdrgpul = ppim->PdrgpulScanIds(pmp);
CPartIndexMap *ppimResult = GPOS_NEW(pmp) CPartIndexMap(pmp);
CPartFilterMap *ppfmResult = GPOS_NEW(pmp) CPartFilterMap(pmp);
// get outer partition consumers
CPartInfo *ppartinfo = exprhdl.Pdprel(0)->Ppartinfo();
CColRefSet *pcrsOutputOuter = exprhdl.Pdprel(0)->PcrsOutput();
CColRefSet *pcrsOutputInner = exprhdl.Pdprel(1)->PcrsOutput();
const ULONG ulPartIndexIds = pdrgpul->UlLength();
for (ULONG ul = 0; ul < ulPartIndexIds; ul++)
{
ULONG ulPartIndexId = *((*pdrgpul)[ul]);
if (ppfm->FContainsScanId(ulPartIndexId))
{
GPOS_ASSERT(NULL != ppfm->Pexpr(ulPartIndexId));
// a selection-based propagation request pushed from above: do not propagate any
// further as the join will reduce cardinality and thus may select more partitions
// for scanning
continue;
}
BOOL fOuterPartConsumer = ppartinfo->FContainsScanId(ulPartIndexId);
// in order to find interesting join predicates that can be used for DPE,
// one side of the predicate must be the partition key, while the other side must only contain
// references from the join child that does not have the partition consumer
CColRefSet *pcrsAllowedRefs = pcrsOutputOuter;
if (fOuterPartConsumer)
{
pcrsAllowedRefs = pcrsOutputInner;
}
if (1 == ulChildIndex && !fOuterPartConsumer)
{
// always push through required partition propagation for consumers on the
// inner side of the hash join
DrgPpartkeys *pdrgppartkeys = exprhdl.Pdprel(1 /*ulChildIndex*/)->Ppartinfo()->PdrgppartkeysByScanId(ulPartIndexId);
GPOS_ASSERT(NULL != pdrgppartkeys);
pdrgppartkeys->AddRef();
ppimResult->AddRequiredPartPropagation(ppim, ulPartIndexId, CPartIndexMap::EppraPreservePropagators, pdrgppartkeys);
}
else
{
// look for a filter on the part key
CExpression *pexprScalar = exprhdl.PexprScalarChild(2 /*ulChildIndex*/);
AddFilterOnPartKey(pmp, false /*fNLJoin*/, pexprScalar, ppim, ppfm, ulChildIndex, ulPartIndexId, fOuterPartConsumer, ppimResult, ppfmResult, pcrsAllowedRefs);
}
}
pdrgpul->Release();
return GPOS_NEW(pmp) CPartitionPropagationSpec(ppimResult, ppfmResult);
}