//--------------------------------------------------------------------------- // @function: // CPhysicalPartitionSelector::PpimDerive // // @doc: // Derive partition index map // //--------------------------------------------------------------------------- CPartIndexMap * CPhysicalPartitionSelector::PpimDerive ( IMemoryPool *mp, CExpressionHandle &exprhdl, CDrvdPropCtxt *pdpctxt ) const { GPOS_ASSERT(NULL != pdpctxt); CDrvdPropPlan *pdpplan = exprhdl.Pdpplan(0 /*child_index*/); CPartIndexMap *ppimInput = pdpplan->Ppim(); GPOS_ASSERT(NULL != ppimInput); ULONG ulExpectedPartitionSelectors = CDrvdPropCtxtPlan::PdpctxtplanConvert(pdpctxt)->UlExpectedPartitionSelectors(); CPartIndexMap *ppim = ppimInput->PpimPartitionSelector(mp, m_scan_id, ulExpectedPartitionSelectors); if (!ppim->Contains(m_scan_id)) { // the consumer of this scan id does not come from the child, i.e. it // is on the other side of a join MDId()->AddRef(); m_pdrgpdrgpcr->AddRef(); m_ppartcnstrmap->AddRef(); m_part_constraint->AddRef(); CPartKeysArray *pdrgppartkeys = GPOS_NEW(mp) CPartKeysArray(mp); pdrgppartkeys->Append(GPOS_NEW(mp) CPartKeys(m_pdrgpdrgpcr)); ppim->Insert(m_scan_id, m_ppartcnstrmap, CPartIndexMap::EpimPropagator, 0 /*ulExpectedPropagators*/, MDId(), pdrgppartkeys, m_part_constraint); } return ppim; }
//--------------------------------------------------------------------------- // @function: // CPhysicalScan::PpimDeriveFromDynamicScan // // @doc: // Derive partition index map from a dynamic scan operator // //--------------------------------------------------------------------------- CPartIndexMap * CPhysicalScan::PpimDeriveFromDynamicScan ( IMemoryPool *pmp, ULONG ulPartIndexId, IMDId *pmdidRel, DrgDrgPcr *pdrgpdrgpcrPart, ULONG ulSecondaryPartIndexId, CPartConstraint *ppartcnstr, CPartConstraint *ppartcnstrRel, ULONG ulExpectedPropagators ) { CPartIndexMap *ppim = GPOS_NEW(pmp) CPartIndexMap(pmp); PartCnstrMap *ppartcnstrmap = GPOS_NEW(pmp) PartCnstrMap(pmp); (void) ppartcnstrmap->FInsert(GPOS_NEW(pmp) ULONG(ulSecondaryPartIndexId), ppartcnstr); DrgPpartkeys *pdrgppartkeys = GPOS_NEW(pmp) DrgPpartkeys(pmp); pdrgppartkeys->Append(GPOS_NEW(pmp) CPartKeys(pdrgpdrgpcrPart)); ppim->Insert(ulPartIndexId, ppartcnstrmap, CPartIndexMap::EpimConsumer, ulExpectedPropagators, pmdidRel, pdrgppartkeys, ppartcnstrRel); return ppim; }
//--------------------------------------------------------------------------- // @function: // CPartIndexMap::PpimPartitionSelector // // @doc: // Return a new part index map for a partition selector with the given // scan id, and the given number of expected selectors above it // //--------------------------------------------------------------------------- CPartIndexMap * CPartIndexMap::PpimPartitionSelector ( IMemoryPool *pmp, ULONG ulScanId, ULONG ulExpectedFromReq ) const { CPartIndexMap *ppimResult = GPOS_NEW(pmp) CPartIndexMap(pmp); PartIndexMapIter pimi(m_pim); while (pimi.FAdvance()) { const CPartTableInfo *ppti = pimi.Pt(); PartCnstrMap *ppartcnstrmap = ppti->Ppartcnstrmap(); IMDId *pmdid = ppti->Pmdid(); DrgPpartkeys *pdrgppartkeys = ppti->Pdrgppartkeys(); CPartConstraint *ppartcnstrRel = ppti->PpartcnstrRel(); ppartcnstrmap->AddRef(); pmdid->AddRef(); pdrgppartkeys->AddRef(); ppartcnstrRel->AddRef(); EPartIndexManipulator epim = ppti->Epim(); ULONG ulExpectedPropagators = ppti->UlExpectedPropagators(); if (ppti->UlScanId() == ulScanId) { if (0 == ulExpectedFromReq) { // this are no other expected partition selectors // so this scan id is resolved epim = EpimResolver; ulExpectedPropagators = 0; } else { // this is not resolved yet epim = EpimConsumer; ulExpectedPropagators = ulExpectedFromReq; } } ppimResult->Insert(ppti->UlScanId(), ppartcnstrmap, epim, ulExpectedPropagators, pmdid, pdrgppartkeys, ppartcnstrRel); } return ppimResult; }
//--------------------------------------------------------------------------- // @function: // CPartitionPropagationSpec::FRequiresPartitionPropagation // // @doc: // Check if given part index id needs to be enforced on top of the given // expression // //--------------------------------------------------------------------------- BOOL CPartitionPropagationSpec::FRequiresPartitionPropagation ( IMemoryPool *mp, CExpression *pexpr, CExpressionHandle &exprhdl, ULONG part_idx_id ) const { GPOS_ASSERT(m_ppim->Contains(part_idx_id)); // construct partition propagation spec with the given id only, and check if it needs to be // enforced on top CPartIndexMap *ppim = GPOS_NEW(mp) CPartIndexMap(mp); IMDId *mdid = m_ppim->GetRelMdId(part_idx_id); CPartKeysArray *pdrgppartkeys = m_ppim->Pdrgppartkeys(part_idx_id); CPartConstraint *ppartcnstr = m_ppim->PpartcnstrRel(part_idx_id); UlongToPartConstraintMap *ppartcnstrmap = m_ppim->Ppartcnstrmap(part_idx_id); mdid->AddRef(); pdrgppartkeys->AddRef(); ppartcnstr->AddRef(); ppartcnstrmap->AddRef(); ppim->Insert(part_idx_id, ppartcnstrmap, m_ppim->Epim(part_idx_id), m_ppim->UlExpectedPropagators(part_idx_id), mdid, pdrgppartkeys, ppartcnstr); CPartitionPropagationSpec *ppps = GPOS_NEW(mp) CPartitionPropagationSpec(ppim, GPOS_NEW(mp) CPartFilterMap(mp)); CEnfdPartitionPropagation *pepp = GPOS_NEW(mp) CEnfdPartitionPropagation(ppps, CEnfdPartitionPropagation::EppmSatisfy, GPOS_NEW(mp) CPartFilterMap(mp)); CEnfdProp::EPropEnforcingType epetPartitionPropagation = pepp->Epet(exprhdl, CPhysical::PopConvert(pexpr->Pop()), true /*fPartitionPropagationRequired*/); pepp->Release(); return CEnfdProp::FEnforce(epetPartitionPropagation); }
//--------------------------------------------------------------------------- // @function: // CPhysicalPartitionSelector::PppsRequired // // @doc: // Compute required partition propagation of the n-th child // //--------------------------------------------------------------------------- CPartitionPropagationSpec * CPhysicalPartitionSelector::PppsRequired ( IMemoryPool *mp, CExpressionHandle & exprhdl, CPartitionPropagationSpec *pppsRequired, ULONG #ifdef GPOS_DEBUG child_index #endif // GPOS_DEBUG , CDrvdProp2dArray *, //pdrgpdpCtxt, ULONG //ulOptReq ) { GPOS_ASSERT(0 == child_index); GPOS_ASSERT(NULL != pppsRequired); CPartIndexMap *ppimInput = pppsRequired->Ppim(); CPartFilterMap *ppfmInput = pppsRequired->Ppfm(); ULongPtrArray *pdrgpulInputScanIds = ppimInput->PdrgpulScanIds(mp); CPartIndexMap *ppim = GPOS_NEW(mp) CPartIndexMap(mp); CPartFilterMap *ppfm = GPOS_NEW(mp) CPartFilterMap(mp); CPartInfo *ppartinfo = exprhdl.GetRelationalProperties(0)->Ppartinfo(); const ULONG ulScanIds = pdrgpulInputScanIds->Size(); for (ULONG ul = 0; ul < ulScanIds; ul++) { ULONG scan_id = *((*pdrgpulInputScanIds)[ul]); ULONG ulExpectedPropagators = ppimInput->UlExpectedPropagators(scan_id); if (scan_id == m_scan_id) { // partition propagation resolved - do not need to require from children continue; } if (!ppartinfo->FContainsScanId(scan_id) && ppartinfo->FContainsScanId(m_scan_id)) { // dynamic scan for the required id not defined below, but the current one is: do not push request down continue; } IMDId *mdid = ppimInput->GetRelMdId(scan_id); CPartKeysArray *pdrgppartkeys = ppimInput->Pdrgppartkeys(scan_id); UlongToPartConstraintMap *ppartcnstrmap = ppimInput->Ppartcnstrmap(scan_id); CPartConstraint *ppartcnstr = ppimInput->PpartcnstrRel(scan_id); CPartIndexMap::EPartIndexManipulator epim = ppimInput->Epim(scan_id); mdid->AddRef(); pdrgppartkeys->AddRef(); ppartcnstrmap->AddRef(); ppartcnstr->AddRef(); ppim->Insert(scan_id, ppartcnstrmap, epim, ulExpectedPropagators, mdid, pdrgppartkeys, ppartcnstr); (void) ppfm->FCopyPartFilter(m_mp, scan_id, ppfmInput); } // cleanup pdrgpulInputScanIds->Release(); return GPOS_NEW(mp) CPartitionPropagationSpec(ppim, ppfm); }
//--------------------------------------------------------------------------- // @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); }