//--------------------------------------------------------------------------- // @function: // CCostContext::FNeedsNewStats // // @doc: // Check if we need to derive new stats for this context, // by default a cost context inherits stats from the owner group, // the only current exception is when part of the plan below cost // context is affected by partition elimination done by partition // selection in some other part of the plan // //--------------------------------------------------------------------------- BOOL CCostContext::FNeedsNewStats() const { COperator *pop = m_pgexpr->Pop(); if (pop->FScalar()) { // return false if scalar operator return false; } CEnfdPartitionPropagation *pepp = Poc()->Prpp()->Pepp(); if (GPOS_FTRACE(EopttraceDeriveStatsForDPE) && CUtils::FPhysicalScan(pop) && CPhysicalScan::PopConvert(pop)->FDynamicScan() && !pepp->PpfmDerived()->FEmpty()) { // context is attached to a dynamic scan that went through // partition elimination in another part of the plan return true; } // we need to derive stats if any child has modified stats BOOL fDeriveStats = false; const ULONG ulArity = Pdrgpoc()->UlLength(); for (ULONG ul = 0; !fDeriveStats && ul < ulArity; ul++) { COptimizationContext *pocChild = (*Pdrgpoc())[ul]; CCostContext *pccChild = pocChild->PccBest(); GPOS_ASSERT(NULL != pccChild); fDeriveStats = pccChild->FOwnsStats(); } return fDeriveStats; }
//--------------------------------------------------------------------------- // @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: // CExpressionHandle::DeriveCostContextStats // // @doc: // Stats derivation based on required plan properties // //--------------------------------------------------------------------------- void CExpressionHandle::DeriveCostContextStats() { GPOS_ASSERT(NULL != m_pcc); GPOS_ASSERT(NULL == m_pcc->Pstats()); // copy group properties and stats CopyGroupProps(); CopyStats(); if (NULL != m_pstats && !m_pcc->FNeedsNewStats()) { // there is no need to derive stats, // stats are copied from owner group return; } CEnfdPartitionPropagation *pepp = m_pcc->Poc()->Prpp()->Pepp(); COperator *pop = Pop(); if (CUtils::FPhysicalScan(pop) && CPhysicalScan::PopConvert(pop)->FDynamicScan() && !pepp->PpfmDerived()->FEmpty()) { // derive stats on dynamic table scan using stats of part selector CPhysicalScan *popScan = CPhysicalScan::PopConvert(m_pgexpr->Pop()); IStatistics *pstatsDS = popScan->PstatsDerive(m_pmp, *this, m_pcc->Poc()->Prpp(), m_pcc->Poc()->Pdrgpstat()); CRefCount::SafeRelease(m_pstats); m_pstats = pstatsDS; return; } // release current stats since we will derive new stats CRefCount::SafeRelease(m_pstats); m_pstats = NULL; // load stats from child cost context -- these may be different from child groups stats CRefCount::SafeRelease(m_pdrgpstat); m_pdrgpstat = NULL; m_pdrgpstat = GPOS_NEW(m_pmp) DrgPstat(m_pmp); const ULONG ulArity = m_pcc->Pdrgpoc()->UlLength(); for (ULONG ul = 0; ul < ulArity; ul++) { COptimizationContext *pocChild = (*m_pcc->Pdrgpoc())[ul]; CCostContext *pccChild = pocChild->PccBest(); GPOS_ASSERT(NULL != pccChild); GPOS_ASSERT(NULL != pccChild->Pstats()); pccChild->Pstats()->AddRef(); m_pdrgpstat->Append(pccChild->Pstats()); } if (CPhysical::PopConvert(m_pgexpr->Pop())->FPassThruStats()) { GPOS_ASSERT(1 == m_pdrgpstat->UlLength()); // copy stats from first child (*m_pdrgpstat)[0]->AddRef(); m_pstats = (*m_pdrgpstat)[0]; return; } // derive stats using the best logical expression with the same children as attached physical operator CGroupExpression *pgexprForStats = m_pcc->PgexprForStats(); GPOS_ASSERT(NULL != pgexprForStats); CExpressionHandle exprhdl(m_pmp); exprhdl.Attach(pgexprForStats); exprhdl.DeriveProps(NULL /*pdpctxt*/); m_pdrgpstat->AddRef(); exprhdl.m_pdrgpstat = m_pdrgpstat; exprhdl.ComputeReqdProps(m_pcc->Poc()->Prprel(), 0 /*ulOptReq*/); GPOS_ASSERT(NULL == exprhdl.m_pstats); IStatistics *pstats = m_pgexpr->Pgroup()->PstatsCompute(m_pcc->Poc(), exprhdl, pgexprForStats); // copy stats to main handle GPOS_ASSERT(NULL == m_pstats); GPOS_ASSERT(NULL != pstats); pstats->AddRef(); m_pstats = pstats; GPOS_ASSERT(m_pstats != NULL); }