本文整理汇总了C++中COperator::Eopid方法的典型用法代码示例。如果您正苦于以下问题:C++ COperator::Eopid方法的具体用法?C++ COperator::Eopid怎么用?C++ COperator::Eopid使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类COperator
的用法示例。
在下文中一共展示了COperator::Eopid方法的11个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: GPOS_NEW
//---------------------------------------------------------------------------
// @function:
// CXformGbAggWithMDQA2Join::PexprTransform
//
// @doc:
// Main transformation driver
//
//---------------------------------------------------------------------------
CExpression *
CXformGbAggWithMDQA2Join::PexprTransform
(
IMemoryPool *pmp,
CExpression *pexpr
)
{
// protect against stack overflow during recursion
GPOS_CHECK_STACK_SIZE;
GPOS_ASSERT(NULL != pmp);
GPOS_ASSERT(NULL != pexpr);
COperator *pop = pexpr->Pop();
if (COperator::EopLogicalGbAgg == pop->Eopid())
{
CExpression *pexprResult = PexprExpandMDQAs(pmp, pexpr);
if (NULL != pexprResult)
{
return pexprResult;
}
}
// recursively process child expressions
const ULONG ulArity = pexpr->UlArity();
DrgPexpr *pdrgpexprChildren = GPOS_NEW(pmp) DrgPexpr(pmp);
for (ULONG ul = 0; ul < ulArity; ul++)
{
CExpression *pexprChild = PexprTransform(pmp, (*pexpr)[ul]);
pdrgpexprChildren->Append(pexprChild);
}
pop->AddRef();
return GPOS_NEW(pmp) CExpression(pmp, pop, pdrgpexprChildren);
}
示例2:
//---------------------------------------------------------------------------
// @function:
// CDecorrelator::FProcessMaxOneRow
//
// @doc:
// Decorrelate max one row operator
//
//---------------------------------------------------------------------------
BOOL
CDecorrelator::FProcessMaxOneRow
(
IMemoryPool *pmp,
CExpression *pexpr,
BOOL fEqualityOnly,
CExpression **ppexprDecorrelated,
DrgPexpr *pdrgpexprCorrelations
)
{
GPOS_ASSERT(NULL != pexpr);
COperator *pop = pexpr->Pop();
GPOS_ASSERT(COperator::EopLogicalMaxOneRow == pop->Eopid());
// fail if MaxOneRow expression has outer references
if (CUtils::FHasOuterRefs(pexpr))
{
return false;
}
// decorrelate relational child
CExpression *pexprRelational = NULL;
if (!FProcess(pmp, (*pexpr)[0], fEqualityOnly, &pexprRelational, pdrgpexprCorrelations))
{
GPOS_ASSERT(NULL == pexprRelational);
return false;
}
// assemble new project
pop->AddRef();
*ppexprDecorrelated = GPOS_NEW(pmp) CExpression(pmp, pop, pexprRelational);
return true;
}
示例3: FOptimizeMotion
//---------------------------------------------------------------------------
// @function:
// COptimizationContext::FOptimize
//
// @doc:
// Return true if given group expression should be optimized under
// given context
//
//---------------------------------------------------------------------------
BOOL
COptimizationContext::FOptimize
(
IMemoryPool *mp,
CGroupExpression *pgexprParent,
CGroupExpression *pgexprChild,
COptimizationContext *pocChild,
ULONG ulSearchStages
)
{
COperator *pop = pgexprChild->Pop();
if (CUtils::FPhysicalMotion(pop))
{
return FOptimizeMotion(mp, pgexprParent, pgexprChild, pocChild, ulSearchStages);
}
if (COperator::EopPhysicalSort == pop->Eopid())
{
return FOptimizeSort(mp, pgexprParent, pgexprChild, pocChild, ulSearchStages);
}
if (CUtils::FPhysicalAgg(pop))
{
return FOptimizeAgg(mp, pgexprParent, pgexprChild, pocChild, ulSearchStages);
}
if (CUtils::FNLJoin(pop))
{
return FOptimizeNLJoin(mp, pgexprParent, pgexprChild, pocChild, ulSearchStages);
}
return true;
}
示例4: PopConvert
//---------------------------------------------------------------------------
// @function:
// CPhysicalHashJoin::FNullableHashKey
//
// @doc:
// Check whether a hash key is nullable
//
//---------------------------------------------------------------------------
BOOL
CPhysicalHashJoin::FNullableHashKey
(
ULONG ulKey,
CColRefSet *pcrsNotNull,
BOOL fInner
)
const
{
COperator *pop = NULL;
if (fInner)
{
pop = (*m_pdrgpexprInnerKeys)[ulKey]->Pop();
}
else
{
pop = (*m_pdrgpexprOuterKeys)[ulKey]->Pop();
}
EOperatorId eopid = pop->Eopid();
if (COperator::EopScalarIdent == eopid)
{
const CColRef *pcr = CScalarIdent::PopConvert(pop)->Pcr();
return (!pcrsNotNull->FMember(pcr));
}
if (COperator::EopScalarConst == eopid)
{
return CScalarConst::PopConvert(pop)->Pdatum()->FNull();
}
// be conservative for all other scalar expressions where we cannot easily
// determine nullability
return true;
}
示例5: DrgPdp
//---------------------------------------------------------------------------
// @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);
}
示例6: GPOS_NEW
//---------------------------------------------------------------------------
// @function:
// CDistributionSpecHashed::PdshashedExcludeColumns
//
// @doc:
// Return a copy of the distribution spec after excluding the given
// columns, return NULL if all distribution expressions are excluded
//
//---------------------------------------------------------------------------
CDistributionSpecHashed *
CDistributionSpecHashed::PdshashedExcludeColumns
(
IMemoryPool *pmp,
CColRefSet *pcrs
)
{
GPOS_ASSERT(NULL != pcrs);
DrgPexpr *pdrgpexprNew = GPOS_NEW(pmp) DrgPexpr(pmp);
const ULONG ulExprs = m_pdrgpexpr->UlLength();
for (ULONG ul = 0; ul < ulExprs; ul++)
{
CExpression *pexpr = (*m_pdrgpexpr)[ul];
COperator *pop = pexpr->Pop();
if (COperator::EopScalarIdent == pop->Eopid())
{
// we only care here about column identifiers,
// any more complicated expressions are copied to output
const CColRef *pcr = CScalarIdent::PopConvert(pop)->Pcr();
if (pcrs->FMember(pcr))
{
continue;
}
}
pexpr->AddRef();
pdrgpexprNew->Append(pexpr);
}
if (0 == pdrgpexprNew->UlLength())
{
pdrgpexprNew->Release();
return NULL;
}
return GPOS_NEW(pmp) CDistributionSpecHashed(pdrgpexprNew, m_fNullsColocated);
}
示例7: GPOS_NEW
//---------------------------------------------------------------------------
// @function:
// CQueryContext::PqcGenerate
//
// @doc:
// Generate the query context for the given expression and array of
// output column ref ids
//
//---------------------------------------------------------------------------
CQueryContext *
CQueryContext::PqcGenerate
(
IMemoryPool *pmp,
CExpression * pexpr,
DrgPul *pdrgpulQueryOutputColRefId,
DrgPmdname *pdrgpmdname,
BOOL fDeriveStats
)
{
GPOS_ASSERT(NULL != pexpr && NULL != pdrgpulQueryOutputColRefId);
CColRefSet *pcrs = GPOS_NEW(pmp) CColRefSet(pmp);
DrgPcr *pdrgpcr = GPOS_NEW(pmp) DrgPcr(pmp);
COptCtxt *poptctxt = COptCtxt::PoctxtFromTLS();
CColumnFactory *pcf = poptctxt->Pcf();
GPOS_ASSERT(NULL != pcf);
const ULONG ulLen = pdrgpulQueryOutputColRefId->UlLength();
for (ULONG ul = 0; ul < ulLen; ul++)
{
ULONG *pul = (*pdrgpulQueryOutputColRefId)[ul];
GPOS_ASSERT(NULL != pul);
CColRef *pcr = pcf->PcrLookup(*pul);
GPOS_ASSERT(NULL != pcr);
pcrs->Include(pcr);
pdrgpcr->Append(pcr);
}
COrderSpec *pos = NULL;
CExpression *pexprResult = pexpr;
COperator *popTop = PopTop(pexpr);
if (COperator::EopLogicalLimit == popTop->Eopid())
{
// top level operator is a limit, copy order spec to query context
pos = CLogicalLimit::PopConvert(popTop)->Pos();
pos->AddRef();
}
else
{
// no order required
pos = GPOS_NEW(pmp) COrderSpec(pmp);
}
CDistributionSpec *pds = NULL;
BOOL fDML = CUtils::FLogicalDML(pexpr->Pop());
poptctxt->MarkDMLQuery(fDML);
if (fDML)
{
pds = GPOS_NEW(pmp) CDistributionSpecAny(COperator::EopSentinel);
}
else
{
pds = GPOS_NEW(pmp) CDistributionSpecSingleton(CDistributionSpecSingleton::EstMaster);
}
CRewindabilitySpec *prs = GPOS_NEW(pmp) CRewindabilitySpec(CRewindabilitySpec::ErtNone /*ert*/);
CEnfdOrder *peo = GPOS_NEW(pmp) CEnfdOrder(pos, CEnfdOrder::EomSatisfy);
// we require satisfy matching on distribution since final query results must be sent to master
CEnfdDistribution *ped = GPOS_NEW(pmp) CEnfdDistribution(pds, CEnfdDistribution::EdmSatisfy);
CEnfdRewindability *per = GPOS_NEW(pmp) CEnfdRewindability(prs, CEnfdRewindability::ErmSatisfy);
CCTEReq *pcter = poptctxt->Pcteinfo()->PcterProducers(pmp);
CReqdPropPlan *prpp = GPOS_NEW(pmp) CReqdPropPlan(pcrs, peo, ped, per, pcter);
pdrgpmdname->AddRef();
return GPOS_NEW(pmp) CQueryContext(pmp, pexprResult, prpp, pdrgpcr, pdrgpmdname, fDeriveStats);
}
示例8: GPOS_NEW
//---------------------------------------------------------------------------
// @function:
// CQueryContext::PqcGenerate
//
// @doc:
// Generate the query context for the given expression and array of
// output column ref ids
//
//---------------------------------------------------------------------------
CQueryContext *
CQueryContext::PqcGenerate
(
IMemoryPool *mp,
CExpression * pexpr,
ULongPtrArray *pdrgpulQueryOutputColRefId,
CMDNameArray *pdrgpmdname,
BOOL fDeriveStats
)
{
GPOS_ASSERT(NULL != pexpr && NULL != pdrgpulQueryOutputColRefId);
CColRefSet *pcrs = GPOS_NEW(mp) CColRefSet(mp);
CColRefArray *colref_array = GPOS_NEW(mp) CColRefArray(mp);
COptCtxt *poptctxt = COptCtxt::PoctxtFromTLS();
CColumnFactory *col_factory = poptctxt->Pcf();
GPOS_ASSERT(NULL != col_factory);
// Collect required column references (colref_array)
const ULONG length = pdrgpulQueryOutputColRefId->Size();
for (ULONG ul = 0; ul < length; ul++)
{
ULONG *pul = (*pdrgpulQueryOutputColRefId)[ul];
GPOS_ASSERT(NULL != pul);
CColRef *colref = col_factory->LookupColRef(*pul);
GPOS_ASSERT(NULL != colref);
pcrs->Include(colref);
colref_array->Append(colref);
}
// Collect required properties (prpp) at the top level:
// By default no sort order requirement is added, unless the root operator in
// the input logical expression is a LIMIT. This is because Orca always
// attaches top level Sort to a LIMIT node.
COrderSpec *pos = NULL;
CExpression *pexprResult = pexpr;
COperator *popTop = PopTop(pexpr);
if (COperator::EopLogicalLimit == popTop->Eopid())
{
// top level operator is a limit, copy order spec to query context
pos = CLogicalLimit::PopConvert(popTop)->Pos();
pos->AddRef();
}
else
{
// no order required
pos = GPOS_NEW(mp) COrderSpec(mp);
}
CDistributionSpec *pds = NULL;
BOOL fDML = CUtils::FLogicalDML(pexpr->Pop());
poptctxt->MarkDMLQuery(fDML);
// DML commands do not have distribution requirement. Otherwise the
// distribution requirement is Singleton.
if (fDML)
{
pds = GPOS_NEW(mp) CDistributionSpecAny(COperator::EopSentinel);
}
else
{
pds = GPOS_NEW(mp) CDistributionSpecSingleton(CDistributionSpecSingleton::EstMaster);
}
// By default, no rewindability requirement needs to be satisfied at the top level
CRewindabilitySpec *prs = GPOS_NEW(mp) CRewindabilitySpec(CRewindabilitySpec::ErtNotRewindable, CRewindabilitySpec::EmhtNoMotion);
// Ensure order, distribution and rewindability meet 'satisfy' matching at the top level
CEnfdOrder *peo = GPOS_NEW(mp) CEnfdOrder(pos, CEnfdOrder::EomSatisfy);
CEnfdDistribution *ped = GPOS_NEW(mp) CEnfdDistribution(pds, CEnfdDistribution::EdmSatisfy);
CEnfdRewindability *per = GPOS_NEW(mp) CEnfdRewindability(prs, CEnfdRewindability::ErmSatisfy);
// Required CTEs are obtained from the CTEInfo global information in the optimizer context
CCTEReq *pcter = poptctxt->Pcteinfo()->PcterProducers(mp);
// NB: Partition propagation requirements are not initialized here. They are
// constructed later based on derived relation properties (CPartInfo) by
// CReqdPropPlan::InitReqdPartitionPropagation().
CReqdPropPlan *prpp = GPOS_NEW(mp) CReqdPropPlan(pcrs, peo, ped, per, pcter);
// Finally, create the CQueryContext
pdrgpmdname->AddRef();
return GPOS_NEW(mp) CQueryContext(mp, pexprResult, prpp, colref_array, pdrgpmdname, fDeriveStats);
}
示例9: if
//---------------------------------------------------------------------------
// @function:
// CStatsPredUtils::FCmpColsIgnoreCast
//
// @doc:
// Is the expression a comparison of scalar ident or cast of a scalar ident?
// Extract relevant info.
//
//---------------------------------------------------------------------------
BOOL
CStatsPredUtils::FCmpColsIgnoreCast
(
CExpression *pexpr,
const CColRef **ppcrLeft,
CStatsPred::EStatsCmpType *pescmpt,
const CColRef **ppcrRight
)
{
GPOS_ASSERT(NULL != ppcrLeft);
GPOS_ASSERT(NULL != ppcrRight);
COperator *pop = pexpr->Pop();
BOOL fINDF = CPredicateUtils::FINDF(pexpr);
BOOL fIDF = CPredicateUtils::FIDF(pexpr);
BOOL fScalarCmp = (COperator::EopScalarCmp == pop->Eopid());
if (!fScalarCmp && !fINDF && !fIDF)
{
return false;
}
CExpression *pexprLeft = NULL;
CExpression *pexprRight = NULL;
if (fINDF)
{
(*pescmpt) = CStatsPred::EstatscmptINDF;
CExpression *pexprIDF = (*pexpr)[0];
pexprLeft = (*pexprIDF)[0];
pexprRight = (*pexprIDF)[1];
}
else if (fIDF)
{
(*pescmpt) = CStatsPred::EstatscmptIDF;
pexprLeft = (*pexpr)[0];
pexprRight = (*pexpr)[1];
}
else
{
GPOS_ASSERT(fScalarCmp);
CScalarCmp *popScCmp = CScalarCmp::PopConvert(pop);
// Comparison semantics for stats purposes is looser
// than regular comparison.
(*pescmpt) = CStatsPredUtils::Estatscmpt(popScCmp->PmdidOp());
pexprLeft = (*pexpr)[0];
pexprRight = (*pexpr)[1];
}
(*ppcrLeft) = CUtils::PcrExtractFromScIdOrCastScId(pexprLeft);
(*ppcrRight) = CUtils::PcrExtractFromScIdOrCastScId(pexprRight);
if (NULL == *ppcrLeft || NULL == *ppcrRight)
{
// failed to extract a scalar ident
return false;
}
return true;
}
示例10: DrgPexpr
//---------------------------------------------------------------------------
// @function:
// CNormalizer::PushThruJoin
//
// @doc:
// Push a conjunct through a join
//
//
//---------------------------------------------------------------------------
void
CNormalizer::PushThruJoin
(
IMemoryPool *pmp,
CExpression *pexprJoin,
CExpression *pexprConj,
CExpression **ppexprResult
)
{
GPOS_ASSERT(NULL != pexprConj);
GPOS_ASSERT(NULL != ppexprResult);
COperator *pop = pexprJoin->Pop();
const ULONG ulArity = pexprJoin->UlArity();
BOOL fLASApply = CUtils::FLeftAntiSemiApply(pop);
COperator::EOperatorId eopid = pop->Eopid();
BOOL fOuterJoin =
COperator::EopLogicalLeftOuterJoin == eopid ||
COperator::EopLogicalLeftOuterApply == eopid ||
COperator::EopLogicalLeftOuterCorrelatedApply == eopid;
if (fOuterJoin && !CUtils::FScalarConstTrue(pexprConj))
{
// whenever possible, push incoming predicate through outer join's outer child,
// recursion will eventually reach the rest of PushThruJoin() to process join predicates
PushThruOuterChild(pmp, pexprJoin, pexprConj, ppexprResult);
return;
}
// combine conjunct with join predicate
CExpression *pexprScalar = (*pexprJoin)[ulArity - 1];
CExpression *pexprPred = CPredicateUtils::PexprConjunction(pmp, pexprScalar, pexprConj);
// break predicate to conjuncts
DrgPexpr *pdrgpexprConjuncts = CPredicateUtils::PdrgpexprConjuncts(pmp, pexprPred);
pexprPred->Release();
// push predicates through children and compute new child expressions
DrgPexpr *pdrgpexprChildren = GPOS_NEW(pmp) DrgPexpr(pmp);
for (ULONG ul = 0; ul < ulArity - 1; ul++)
{
CExpression *pexprChild = (*pexprJoin)[ul];
CExpression *pexprNewChild = NULL;
if (fLASApply)
{
// do not push anti-semi-apply predicates to any of the children
pexprNewChild = PexprNormalize(pmp, pexprChild);
pdrgpexprChildren->Append(pexprNewChild);
continue;
}
if (0 == ul && fOuterJoin)
{
// do not push outer join predicates through outer child
// otherwise, we will throw away outer child's tuples that should
// be part of the join result
pexprNewChild = PexprNormalize(pmp, pexprChild);
pdrgpexprChildren->Append(pexprNewChild);
continue;
}
DrgPexpr *pdrgpexprRemaining = NULL;
PushThru(pmp, pexprChild, pdrgpexprConjuncts, &pexprNewChild, &pdrgpexprRemaining);
pdrgpexprChildren->Append(pexprNewChild);
pdrgpexprConjuncts->Release();
pdrgpexprConjuncts = pdrgpexprRemaining;
}
// remaining conjuncts become the new join predicate
CExpression *pexprNewScalar = CPredicateUtils::PexprConjunction(pmp, pdrgpexprConjuncts);
pdrgpexprChildren->Append(pexprNewScalar);
// create a new join expression
pop->AddRef();
*ppexprResult = GPOS_NEW(pmp) CExpression(pmp, pop, pdrgpexprChildren);
}
示例11: exprhdl
//---------------------------------------------------------------------------
// @function:
// CNormalizer::PexprPullUpAndCombineProjects
//
// @doc:
// Pulls up logical projects as far as possible, and combines consecutive
// projects if possible
//
//---------------------------------------------------------------------------
CExpression *
CNormalizer::PexprPullUpAndCombineProjects
(
IMemoryPool *pmp,
CExpression *pexpr,
BOOL *pfSuccess // output to indicate whether anything was pulled up
)
{
GPOS_ASSERT(NULL != pexpr);
GPOS_ASSERT(NULL != pfSuccess);
COperator *pop = pexpr->Pop();
const ULONG ulArity = pexpr->UlArity();
if (!pop->FLogical() || 0 == ulArity)
{
pexpr->AddRef();
return pexpr;
}
DrgPexpr *pdrgpexprChildren = GPOS_NEW(pmp) DrgPexpr(pmp);
DrgPexpr *pdrgpexprPrElPullUp = GPOS_NEW(pmp) DrgPexpr(pmp);
CExpressionHandle exprhdl(pmp);
exprhdl.Attach(pexpr);
CColRefSet *pcrsOutput = CDrvdPropRelational::Pdprel(pexpr->PdpDerive())->PcrsOutput();
// extract the columns used by the scalar expression and the operator itself (for grouping, sorting, etc.)
CColRefSet *pcrsUsed = exprhdl.PcrsUsedColumns(pmp);
for (ULONG ul = 0; ul < ulArity; ul++)
{
CExpression *pexprChild = PexprPullUpAndCombineProjects(pmp, (*pexpr)[ul], pfSuccess);
if (pop->FLogical() && CLogical::PopConvert(pop)->FCanPullProjectionsUp(ul) &&
COperator::EopLogicalProject == pexprChild->Pop()->Eopid())
{
// this child is a project - see if any project elements can be pulled up
CExpression *pexprNewChild = PexprPullUpProjectElements
(
pmp,
pexprChild,
pcrsUsed,
pcrsOutput,
&pdrgpexprPrElPullUp
);
pexprChild->Release();
pexprChild = pexprNewChild;
}
pdrgpexprChildren->Append(pexprChild);
}
pcrsUsed->Release();
pop->AddRef();
if (0 < pdrgpexprPrElPullUp->UlLength() && COperator::EopLogicalProject == pop->Eopid())
{
// some project elements have been pulled up and the original expression
// was a project - combine its project list with the pulled up project elements
GPOS_ASSERT(2 == pdrgpexprChildren->UlLength());
*pfSuccess = true;
CExpression *pexprRelational = (*pdrgpexprChildren)[0];
CExpression *pexprPrLOld = (*pdrgpexprChildren)[1];
pexprRelational->AddRef();
CUtils::AddRefAppend(pdrgpexprPrElPullUp, pexprPrLOld->PdrgPexpr());
pdrgpexprChildren->Release();
CExpression *pexprPrjList = GPOS_NEW(pmp) CExpression(pmp, GPOS_NEW(pmp) CScalarProjectList(pmp), pdrgpexprPrElPullUp);
GPOS_ASSERT(CDrvdPropRelational::Pdprel(pexprRelational->PdpDerive())->PcrsOutput()->FSubset(CDrvdPropScalar::Pdpscalar(pexprPrjList->PdpDerive())->PcrsUsed()));
return GPOS_NEW(pmp) CExpression(pmp, pop, pexprRelational, pexprPrjList);
}
CExpression *pexprOutput = GPOS_NEW(pmp) CExpression(pmp, pop, pdrgpexprChildren);
if (0 == pdrgpexprPrElPullUp->UlLength())
{
// no project elements were pulled up
pdrgpexprPrElPullUp->Release();
return pexprOutput;
}
// some project elements were pulled - add a project on top of output expression
*pfSuccess = true;
CExpression *pexprPrjList = GPOS_NEW(pmp) CExpression(pmp, GPOS_NEW(pmp) CScalarProjectList(pmp), pdrgpexprPrElPullUp);
GPOS_ASSERT(CDrvdPropRelational::Pdprel(pexprOutput->PdpDerive())->PcrsOutput()->FSubset(CDrvdPropScalar::Pdpscalar(pexprPrjList->PdpDerive())->PcrsUsed()));
return GPOS_NEW(pmp) CExpression(pmp, GPOS_NEW(pmp) CLogicalProject(pmp), pexprOutput, pexprPrjList);
}