//--------------------------------------------------------------------------- // @function: // CCTEReq::PcterUnresolved // // @doc: // Unresolved CTE requirements given a derived CTE map // //--------------------------------------------------------------------------- CCTEReq * CCTEReq::PcterUnresolved ( IMemoryPool *pmp, CCTEMap *pcm ) { GPOS_ASSERT(NULL != pcm); CCTEReq *pcterUnresolved = GPOS_NEW(pmp) CCTEReq(pmp); HMCteReqIter hmcri(m_phmcter); while (hmcri.FAdvance()) { // if a cte is marked as required and it is not found in the given map // then keep it as required, else make it optional const CCTEReqEntry *pcre = hmcri.Pt(); ULONG ulId = pcre->UlId(); BOOL fRequired = pcre->FRequired() && CCTEMap::EctSentinel == pcm->Ect(ulId); CDrvdPropPlan *pdpplan = pcre->PdpplanProducer(); if (NULL != pdpplan) { pdpplan->AddRef(); } pcterUnresolved->Insert(ulId, pcre->Ect(), fRequired, pdpplan); } return pcterUnresolved; }
//--------------------------------------------------------------------------- // @function: // CDrvdPropCtxtPlan::PdpctxtCopy // // @doc: // Copy function // //--------------------------------------------------------------------------- CDrvdPropCtxt * CDrvdPropCtxtPlan::PdpctxtCopy ( IMemoryPool *pmp ) const { CDrvdPropCtxtPlan *pdpctxtplan = GPOS_NEW(pmp) CDrvdPropCtxtPlan(pmp); pdpctxtplan->m_ulExpectedPartitionSelectors = m_ulExpectedPartitionSelectors; HMUlPdpIter hmulpdpiter(m_phmulpdpCTEs); while (hmulpdpiter.FAdvance()) { ULONG ulId = *(hmulpdpiter.Pk()); CDrvdPropPlan *pdpplan = const_cast<CDrvdPropPlan *>(hmulpdpiter.Pt()); pdpplan->AddRef(); #ifdef GPOS_DEBUG BOOL fInserted = #endif // GPOS_DEBUG pdpctxtplan->m_phmulpdpCTEs->FInsert(GPOS_NEW(m_pmp) ULONG(ulId), pdpplan); GPOS_ASSERT(fInserted); } return pdpctxtplan; }
//--------------------------------------------------------------------------- // @function: // CDrvdPropCtxtPlan::AddProps // // @doc: // Add props to context // //--------------------------------------------------------------------------- void CDrvdPropCtxtPlan::AddProps ( CDrvdProp *pdp ) { if (CDrvdProp::EptPlan != pdp->Ept()) { // passed property is not a plan property container return; } CDrvdPropPlan *pdpplan = CDrvdPropPlan::Pdpplan(pdp); ULONG ulProducerId = ULONG_MAX; CDrvdPropPlan *pdpplanProducer = pdpplan->Pcm()->PdpplanProducer(&ulProducerId); if (NULL == pdpplanProducer) { return; } if (m_fUpdateCTEMap) { pdpplanProducer->AddRef(); #ifdef GPOS_DEBUG BOOL fInserted = #endif // GPOS_DEBUG m_phmulpdpCTEs->FInsert(GPOS_NEW(m_pmp) ULONG(ulProducerId), pdpplanProducer); GPOS_ASSERT(fInserted); } }
//--------------------------------------------------------------------------- // @function: // CExpressionHandle::DerivePlanProps // // @doc: // Derive the properties of the plan carried by attached cost context // //--------------------------------------------------------------------------- void CExpressionHandle::DerivePlanProps ( CDrvdPropCtxtPlan *pdpctxtplan ) { GPOS_ASSERT(NULL != m_pcc); GPOS_ASSERT(NULL != m_pgexpr); GPOS_ASSERT(NULL == m_pdrgpdp); GPOS_ASSERT(NULL == m_pdp); GPOS_CHECK_ABORT; // check if properties have been already derived if (NULL != m_pcc->Pdpplan()) { CopyCostCtxtProps(); return; } GPOS_ASSERT(NULL != pdpctxtplan); // extract children's properties m_pdrgpdp = GPOS_NEW(m_pmp) DrgPdp(m_pmp); const ULONG ulArity = m_pcc->Pdrgpoc()->UlLength(); for (ULONG ul = 0; ul < ulArity; ul++) { COptimizationContext *pocChild = (*m_pcc->Pdrgpoc())[ul]; CDrvdPropPlan *pdpplan = pocChild->PccBest()->Pdpplan(); GPOS_ASSERT(NULL != pdpplan); pdpplan->AddRef(); m_pdrgpdp->Append(pdpplan); // add child props to derivation context CDrvdPropCtxt::AddDerivedProps(pdpplan, pdpctxtplan); } COperator *pop = m_pgexpr->Pop(); if (COperator::EopPhysicalCTEConsumer == pop->Eopid()) { // copy producer plan properties to passed derived plan properties context ULONG ulCTEId = CPhysicalCTEConsumer::PopConvert(pop)->UlCTEId(); CDrvdPropPlan *pdpplan = m_pcc->Poc()->Prpp()->Pcter()->Pdpplan(ulCTEId); if (NULL != pdpplan) { pdpctxtplan->CopyCTEProducerProps(pdpplan, ulCTEId); } } // set the number of expected partition selectors in the context pdpctxtplan->SetExpectedPartitionSelectors(pop, m_pcc); // create/derive local properties m_pdp = Pop()->PdpCreate(m_pmp); m_pdp->Derive(m_pmp, *this, pdpctxtplan); }
//--------------------------------------------------------------------------- // @function: // CCTEReq::InsertConsumer // // @doc: // Insert a new consumer entry. with the given id. The plan properties are // taken from the given context // //--------------------------------------------------------------------------- void CCTEReq::InsertConsumer ( ULONG ulId, DrgPdp *pdrgpdpCtxt ) { ULONG ulProducerId = ULONG_MAX; CDrvdPropPlan *pdpplan = CDrvdPropPlan::Pdpplan((*pdrgpdpCtxt)[0])->Pcm()->PdpplanProducer(&ulProducerId); GPOS_ASSERT(NULL != pdpplan); GPOS_ASSERT(ulProducerId == ulId && "unexpected CTE producer plan properties"); pdpplan->AddRef(); Insert(ulId, CCTEMap::EctConsumer, true /*fRequired*/, pdpplan); }
//--------------------------------------------------------------------------- // @function: // CCTEReq::PcterAllOptional // // @doc: // Create a copy of the current requirement where all the entries are marked optional // //--------------------------------------------------------------------------- CCTEReq * CCTEReq::PcterAllOptional ( IMemoryPool *pmp ) { CCTEReq *pcter = GPOS_NEW(pmp) CCTEReq(pmp); HMCteReqIter hmcri(m_phmcter); while (hmcri.FAdvance()) { const CCTEReqEntry *pcre = hmcri.Pt(); CDrvdPropPlan *pdpplan = pcre->PdpplanProducer(); if (NULL != pdpplan) { pdpplan->AddRef(); } pcter->Insert(pcre->UlId(), pcre->Ect(), false /*fRequired*/, pdpplan); } return pcter; }
//--------------------------------------------------------------------------- // @function: // CCostContext::DerivePlanProps // // @doc: // Derive properties of the plan carried by cost context // //--------------------------------------------------------------------------- void CCostContext::DerivePlanProps ( IMemoryPool *pmp ) { GPOS_ASSERT(NULL != m_pdrgpoc); if (NULL == m_pdpplan) { // derive properties of the plan carried by cost context CExpressionHandle exprhdl(pmp); exprhdl.Attach(this); exprhdl.DerivePlanProps(); CDrvdPropPlan *pdpplan = CDrvdPropPlan::Pdpplan(exprhdl.Pdp()); GPOS_ASSERT(NULL != pdpplan); // set derived plan properties pdpplan->AddRef(); m_pdpplan = pdpplan; GPOS_ASSERT(NULL != m_pdpplan); } }
//--------------------------------------------------------------------------- // @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; }