//--------------------------------------------------------------------------- // @function: // CPartIndexMap::FSatisfies // // @doc: // Check if part index map satisfies required partition propagation spec // //--------------------------------------------------------------------------- BOOL CPartIndexMap::FSatisfies ( const CPartitionPropagationSpec *ppps ) const { GPOS_ASSERT(NULL != ppps); CPartIndexMap *ppimReqd = ppps->Ppim(); if (NULL == ppimReqd || !ppimReqd->FContainsUnresolved()) { // no reqiurements specified return true; } // check if all required entries are satisfied PartIndexMapIter pimiReqd(ppimReqd->m_pim); while (pimiReqd.FAdvance()) { const CPartTableInfo *pptiReqd = pimiReqd.Pt(); CPartTableInfo *ppti = PptiLookup(pptiReqd->UlScanId()); if (NULL != ppti && !FSatisfiesEntry(pptiReqd, ppti)) { return false; } } return true; }
//--------------------------------------------------------------------------- // @function: // CPhysical::EpetPartitionPropagation // // @doc: // Compute the enforcing type for the operator // //--------------------------------------------------------------------------- CEnfdProp::EPropEnforcingType CPhysical::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_mp, ppimDrvd); BOOL fResolved = pepp->FResolved(m_mp, ppimDrvd); if (fResolved) { // all required partition consumers are resolved return CEnfdProp::EpetUnnecessary; } if (!fInScope) { // some partition consumers are not in scope of the operator: need to enforce these on top return CEnfdProp::EpetRequired; } // all partition resolvers are in scope of the operator: do not enforce them on top return CEnfdProp::EpetProhibited; }
//--------------------------------------------------------------------------- // @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; }