예제 #1
0
//---------------------------------------------------------------------------
//	@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;
}
예제 #2
0
//---------------------------------------------------------------------------
//	@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;
}
예제 #3
0
//---------------------------------------------------------------------------
//	@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);
    }
}
예제 #4
0
//---------------------------------------------------------------------------
//	@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);
}
예제 #5
0
//---------------------------------------------------------------------------
//	@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);
}
예제 #6
0
//---------------------------------------------------------------------------
//	@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;
}
예제 #7
0
파일: CCostContext.cpp 프로젝트: d/gporca
//---------------------------------------------------------------------------
//	@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);
	}
}
예제 #8
0
//---------------------------------------------------------------------------
//	@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;
}