本文整理汇总了C++中DrgPexpr::Append方法的典型用法代码示例。如果您正苦于以下问题:C++ DrgPexpr::Append方法的具体用法?C++ DrgPexpr::Append怎么用?C++ DrgPexpr::Append使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类DrgPexpr
的用法示例。
在下文中一共展示了DrgPexpr::Append方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: DrgPexpr
//---------------------------------------------------------------------------
// @function:
// CNormalizer::PexprNormalize
//
// @doc:
// Main driver
//
//---------------------------------------------------------------------------
CExpression *
CNormalizer::PexprNormalize
(
IMemoryPool *pmp,
CExpression *pexpr
)
{
GPOS_CHECK_STACK_SIZE;
GPOS_ASSERT(NULL != pexpr);
if (0 == pexpr->UlArity())
{
// end recursion early for leaf patterns extracted from memo
pexpr->AddRef();
return pexpr;
}
CExpression *pexprResult = NULL;
COperator *pop = pexpr->Pop();
if (pop->FLogical() && CLogical::PopConvert(pop)->FSelectionOp())
{
if (FPushThruOuterChild(pexpr))
{
CExpression *pexprConstTrue = CUtils::PexprScalarConstBool(pmp, true /*fVal*/);
PushThru(pmp, pexpr, pexprConstTrue, &pexprResult);
pexprConstTrue->Release();
}
else
{
// add-ref all children except scalar predicate
const ULONG ulArity = pexpr->UlArity();
DrgPexpr *pdrgpexpr = GPOS_NEW(pmp) DrgPexpr(pmp);
for (ULONG ul = 0; ul < ulArity - 1; ul++)
{
CExpression *pexprChild = (*pexpr)[ul];
pexprChild->AddRef();
pdrgpexpr->Append(pexprChild);
}
// normalize scalar predicate and construct a new expression
CExpression *pexprPred = (*pexpr)[pexpr->UlArity() - 1];
CExpression *pexprPredNormalized = PexprRecursiveNormalize(pmp, pexprPred);
pdrgpexpr->Append(pexprPredNormalized);
COperator *pop = pexpr->Pop();
pop->AddRef();
CExpression *pexprNew = GPOS_NEW(pmp) CExpression(pmp, pop, pdrgpexpr);
// push normalized predicate through
PushThru(pmp, pexprNew, pexprPredNormalized, &pexprResult);
pexprNew->Release();
}
}
else
{
pexprResult = PexprRecursiveNormalize(pmp, pexpr);
}
GPOS_ASSERT(NULL != pexprResult);
return pexprResult;
}
示例2: PexprConjunction
//---------------------------------------------------------------------------
// @function:
// CPhysicalPartitionSelector::PexprCombinedPartPred
//
// @doc:
// Return a single combined partition selection predicate
//
//---------------------------------------------------------------------------
CExpression *
CPhysicalPartitionSelector::PexprCombinedPartPred
(
IMemoryPool *pmp
)
const
{
DrgPexpr *pdrgpexpr = GPOS_NEW(pmp) DrgPexpr(pmp);
const ULONG ulLevels = UlPartLevels();
for (ULONG ul = 0; ul < ulLevels; ul++)
{
CExpression *pexpr = PexprPartPred(pmp, ul);
if (NULL != pexpr)
{
pdrgpexpr->Append(pexpr);
}
}
if (NULL != m_pexprResidual)
{
m_pexprResidual->AddRef();
pdrgpexpr->Append(m_pexprResidual);
}
return CPredicateUtils::PexprConjunction(pmp, pdrgpexpr);
}
示例3: PexprConjunction
//---------------------------------------------------------------------------
// @function:
// CConstraint::PexprScalarConjDisj
//
// @doc:
// Construct a conjunction or disjunction scalar expression from an
// array of constraints
//
//---------------------------------------------------------------------------
CExpression *
CConstraint::PexprScalarConjDisj
(
IMemoryPool *pmp,
DrgPcnstr *pdrgpcnstr,
BOOL fConj
)
const
{
DrgPexpr *pdrgpexpr = GPOS_NEW(pmp) DrgPexpr(pmp);
const ULONG ulLen = pdrgpcnstr->UlLength();
for (ULONG ul = 0; ul < ulLen; ul++)
{
CExpression *pexpr = (*pdrgpcnstr)[ul]->PexprScalar(pmp);
pexpr->AddRef();
pdrgpexpr->Append(pexpr);
}
if (fConj)
{
return CPredicateUtils::PexprConjunction(pmp, pdrgpexpr);
}
return CPredicateUtils::PexprDisjunction(pmp, pdrgpexpr);
}
示例4: DrgPexpr
CHashedDistributions::CHashedDistributions
(
IMemoryPool *pmp,
DrgPcr *pdrgpcrOutput,
DrgDrgPcr *pdrgpdrgpcrInput
)
:
DrgPds(pmp)
{
const ULONG ulCols = pdrgpcrOutput->UlLength();
const ULONG ulArity = pdrgpdrgpcrInput->UlLength();
for (ULONG ulChild = 0; ulChild < ulArity; ulChild++)
{
DrgPcr *pdrgpcr = (*pdrgpdrgpcrInput)[ulChild];
DrgPexpr *pdrgpexpr = GPOS_NEW(pmp) DrgPexpr(pmp);
for (ULONG ulCol = 0; ulCol < ulCols; ulCol++)
{
CColRef *pcr = (*pdrgpcr)[ulCol];
CExpression *pexpr = CUtils::PexprScalarIdent(pmp, pcr);
pdrgpexpr->Append(pexpr);
}
// create a hashed distribution on input columns of the current child
BOOL fNullsColocated = true;
CDistributionSpec *pdshashed = GPOS_NEW(pmp) CDistributionSpecHashed(pdrgpexpr, fNullsColocated);
Append(pdshashed);
}
}
示例5: GPOS_NEW
//---------------------------------------------------------------------------
// @function:
// CPhysicalUnionAll::PdsMatching
//
// @doc:
// Compute output hashed distribution based on the outer child's
// hashed distribution
//---------------------------------------------------------------------------
CDistributionSpecHashed *
CPhysicalUnionAll::PdsMatching
(
IMemoryPool *pmp,
const DrgPul *pdrgpulOuter
)
const
{
GPOS_ASSERT(NULL != pdrgpulOuter);
const ULONG ulCols = pdrgpulOuter->UlLength();
GPOS_ASSERT(ulCols <= m_pdrgpcrOutput->UlLength());
DrgPexpr *pdrgpexpr = GPOS_NEW(pmp) DrgPexpr(pmp);
for (ULONG ulCol = 0; ulCol < ulCols; ulCol++)
{
ULONG ulIdx = *(*pdrgpulOuter)[ulCol];
CExpression *pexpr = CUtils::PexprScalarIdent(pmp, (*m_pdrgpcrOutput)[ulIdx]);
pdrgpexpr->Append(pexpr);
}
GPOS_ASSERT(0 < pdrgpexpr->UlLength());
return GPOS_NEW(pmp) CDistributionSpecHashed(pdrgpexpr, true /*fNullsColocated*/);
}
示例6: CColRefSet
//---------------------------------------------------------------------------
// @function:
// CNormalizer::PushThruSetOp
//
// @doc:
// Push a conjunct through set operation
//
//---------------------------------------------------------------------------
void
CNormalizer::PushThruSetOp
(
IMemoryPool *pmp,
CExpression *pexprSetOp,
CExpression *pexprConj,
CExpression **ppexprResult
)
{
GPOS_ASSERT(NULL != pexprSetOp);
GPOS_ASSERT(CUtils::FLogicalSetOp(pexprSetOp->Pop()));
GPOS_ASSERT(NULL != pexprConj);
GPOS_ASSERT(NULL != ppexprResult);
CLogicalSetOp *popSetOp = CLogicalSetOp::PopConvert(pexprSetOp->Pop());
DrgPcr *pdrgpcrOutput = popSetOp->PdrgpcrOutput();
CColRefSet *pcrsOutput = GPOS_NEW(pmp) CColRefSet(pmp, pdrgpcrOutput);
DrgDrgPcr *pdrgpdrgpcrInput = popSetOp->PdrgpdrgpcrInput();
DrgPexpr *pdrgpexprNewChildren = GPOS_NEW(pmp) DrgPexpr(pmp);
const ULONG ulArity = pexprSetOp->UlArity();
for (ULONG ul = 0; ul < ulArity; ul++)
{
CExpression *pexprChild = (*pexprSetOp)[ul];
DrgPcr *pdrgpcrChild = (*pdrgpdrgpcrInput)[ul];
CColRefSet *pcrsChild = GPOS_NEW(pmp) CColRefSet(pmp, pdrgpcrChild);
pexprConj->AddRef();
CExpression *pexprRemappedConj = pexprConj;
if (!pcrsChild->FEqual(pcrsOutput))
{
// child columns are different from SetOp output columns,
// we need to fix conjunct by mapping output columns to child columns,
// columns that are not in the output of SetOp child need also to be re-mapped
// to new columns,
//
// for example, if the conjunct looks like 'x > (select max(y) from T)'
// and the SetOp child produces only column x, we need to create a new
// conjunct that looks like 'x1 > (select max(y1) from T)'
// where x1 is a copy of x, and y1 is a copy of y
//
// this is achieved by passing (fMustExist = True) flag below, which enforces
// creating column copies for columns not already in the given map
HMUlCr *phmulcr = CUtils::PhmulcrMapping(pmp, pdrgpcrOutput, pdrgpcrChild);
pexprRemappedConj->Release();
pexprRemappedConj = pexprConj->PexprCopyWithRemappedColumns(pmp, phmulcr, true /*fMustExist*/);
phmulcr->Release();
}
CExpression *pexprNewChild = NULL;
PushThru(pmp, pexprChild, pexprRemappedConj, &pexprNewChild);
pdrgpexprNewChildren->Append(pexprNewChild);
pexprRemappedConj->Release();
pcrsChild->Release();
}
pcrsOutput->Release();
popSetOp->AddRef();
*ppexprResult = GPOS_NEW(pmp) CExpression(pmp, popSetOp, pdrgpexprNewChildren);
}
示例7: DrgPds
//---------------------------------------------------------------------------
// @function:
// CPhysicalUnionAll::BuildHashedDistributions
//
// @doc:
// Build hashed distributions used locally during distribution derivation,
//
// the function builds an array of hashed distribution on input column
// of each child, and an output hashed distribution on UnionAll output
// columns
//
//
//---------------------------------------------------------------------------
void
CPhysicalUnionAll::BuildHashedDistributions
(
IMemoryPool *pmp
)
{
GPOS_ASSERT(NULL == m_pdrgpds);
m_pdrgpds = GPOS_NEW(pmp) DrgPds(pmp);
const ULONG ulCols = m_pdrgpcrOutput->UlLength();
const ULONG ulArity = m_pdrgpdrgpcrInput->UlLength();
for (ULONG ulChild = 0; ulChild < ulArity; ulChild++)
{
DrgPcr *pdrgpcr = (*m_pdrgpdrgpcrInput)[ulChild];
DrgPexpr *pdrgpexpr = GPOS_NEW(pmp) DrgPexpr(pmp);
for (ULONG ulCol = 0; ulCol < ulCols; ulCol++)
{
CExpression *pexpr = CUtils::PexprScalarIdent(pmp, (*pdrgpcr)[ulCol]);
pdrgpexpr->Append(pexpr);
}
// create a hashed distribution on input columns of the current child
CDistributionSpecHashed *pdshashed = GPOS_NEW(pmp) CDistributionSpecHashed(pdrgpexpr, true /*fNullsColocated*/);
m_pdrgpds->Append(pdshashed);
}
}
示例8: DrgPdrgPexpr
//---------------------------------------------------------------------------
// @function:
// CCNFConverter::Pdrgpdrgpexpr
//
// @doc:
// Create an array of arrays each holding the children of an expression
// from the given array
//
//
//---------------------------------------------------------------------------
DrgPdrgPexpr *
CCNFConverter::Pdrgpdrgpexpr
(
IMemoryPool *pmp,
DrgPexpr *pdrgpexpr
)
{
GPOS_ASSERT(NULL != pmp);
GPOS_ASSERT(NULL != pdrgpexpr);
DrgPdrgPexpr *pdrgpdrgpexpr = GPOS_NEW(pmp) DrgPdrgPexpr(pmp);
const ULONG ulArity = pdrgpexpr->UlLength();
for (ULONG ul = 0; ul < ulArity; ul++)
{
CExpression *pexpr = (*pdrgpexpr)[ul];
DrgPexpr *pdrgpexprChild = NULL;
if (CPredicateUtils::FAnd(pexpr))
{
pdrgpexprChild = pexpr->PdrgPexpr();
pdrgpexprChild->AddRef();
}
else
{
pdrgpexprChild = GPOS_NEW(pmp) DrgPexpr(pmp);
pexpr->AddRef();
pdrgpexprChild->Append(pexpr);
}
pdrgpdrgpexpr->Append(pdrgpexprChild);
}
return pdrgpdrgpexpr;
}
示例9: 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);
}
示例10: GPOS_NEW
//---------------------------------------------------------------------------
// @function:
// CDistributionSpecHashed::PdsCopyWithRemappedColumns
//
// @doc:
// Return a copy of the distribution spec with remapped columns
//
//---------------------------------------------------------------------------
CDistributionSpec *
CDistributionSpecHashed::PdsCopyWithRemappedColumns
(
IMemoryPool *pmp,
HMUlCr *phmulcr,
BOOL fMustExist
)
{
DrgPexpr *pdrgpexpr = GPOS_NEW(pmp) DrgPexpr(pmp);
const ULONG ulLen = m_pdrgpexpr->UlLength();
for (ULONG ul = 0; ul < ulLen; ul++)
{
CExpression *pexpr = (*m_pdrgpexpr)[ul];
pdrgpexpr->Append(pexpr->PexprCopyWithRemappedColumns(pmp, phmulcr, fMustExist));
}
if (NULL == m_pdshashedEquiv)
{
return GPOS_NEW(pmp) CDistributionSpecHashed(pdrgpexpr, m_fNullsColocated);
}
// copy equivalent distribution
CDistributionSpec *pds = m_pdshashedEquiv->PdsCopyWithRemappedColumns(pmp, phmulcr, fMustExist);
CDistributionSpecHashed *pdshashed = CDistributionSpecHashed::PdsConvert(pds);
return GPOS_NEW(pmp) CDistributionSpecHashed(pdrgpexpr, m_fNullsColocated, pdshashed);
}
示例11: DrgPexpr
//---------------------------------------------------------------------------
// @function:
// CCNFConverter::PexprNot2CNF
//
// @doc:
// Convert a NOT tree into CNF
//
//---------------------------------------------------------------------------
CExpression *
CCNFConverter::PexprNot2CNF
(
IMemoryPool *pmp,
CExpression *pexpr
)
{
GPOS_ASSERT(NULL != pmp);
GPOS_ASSERT(NULL != pexpr);
GPOS_ASSERT(1 == pexpr->UlArity());
CExpression *pexprNotChild = (*pexpr)[0];
if (!FScalarBoolOp(pexprNotChild))
{
pexpr->AddRef();
return pexpr;
}
CScalarBoolOp::EBoolOperator eboolopChild = CScalarBoolOp::PopConvert(pexprNotChild->Pop())->Eboolop();
// apply DeMorgan laws
// NOT(NOT(A)) ==> A
if (CScalarBoolOp::EboolopNot == eboolopChild)
{
return Pexpr2CNF(pmp, (*pexprNotChild)[0]);
}
// Not child must be either an AND or an OR
// NOT(A AND B) ==> NOT(A) OR NOT(B)
// NOT(A OR B) ==> NOT(A) AND NOT(B)
DrgPexpr *pdrgpexpr = GPOS_NEW(pmp) DrgPexpr(pmp);
const ULONG ulArity = pexprNotChild->UlArity();
for (ULONG ul = 0; ul < ulArity; ul++)
{
(*pexprNotChild)[ul]->AddRef();
pdrgpexpr->Append(CUtils::PexprNegate(pmp, (*pexprNotChild)[ul]));
}
CScalarBoolOp::EBoolOperator eboolop = CScalarBoolOp::EboolopAnd;
if (CScalarBoolOp::EboolopAnd == eboolopChild)
{
eboolop = CScalarBoolOp::EboolopOr;
}
CExpression *pexprScalarBoolOp = CUtils::PexprScalarBoolOp(pmp, eboolop, pdrgpexpr);
CExpression *pexprResult = Pexpr2CNF(pmp, pexprScalarBoolOp);
pexprScalarBoolOp->Release();
return pexprResult;
}
示例12: bsi
//---------------------------------------------------------------------------
// @function:
// CJoinOrderDP::PexprBuildPred
//
// @doc:
// Build predicate connecting the two given sets
//
//---------------------------------------------------------------------------
CExpression *
CJoinOrderDP::PexprBuildPred
(
CBitSet *pbsFst,
CBitSet *pbsSnd
)
{
// collect edges connecting the given sets
CBitSet *pbsEdges = GPOS_NEW(m_pmp) CBitSet(m_pmp);
CBitSet *pbs = GPOS_NEW(m_pmp) CBitSet(m_pmp, *pbsFst);
pbs->Union(pbsSnd);
for (ULONG ul = 0; ul < m_ulEdges; ul++)
{
SEdge *pedge = m_rgpedge[ul];
if (
pbs->FSubset(pedge->m_pbs) &&
!pbsFst->FDisjoint(pedge->m_pbs) &&
!pbsSnd->FDisjoint(pedge->m_pbs)
)
{
#ifdef GPOS_DEBUG
BOOL fSet =
#endif // GPOS_DEBUG
pbsEdges->FExchangeSet(ul);
GPOS_ASSERT(!fSet);
}
}
pbs->Release();
CExpression *pexprPred = NULL;
if (0 < pbsEdges->CElements())
{
DrgPexpr *pdrgpexpr = GPOS_NEW(m_pmp) DrgPexpr(m_pmp);
CBitSetIter bsi(*pbsEdges);
while (bsi.FAdvance())
{
ULONG ul = bsi.UlBit();
SEdge *pedge = m_rgpedge[ul];
pedge->m_pexpr->AddRef();
pdrgpexpr->Append(pedge->m_pexpr);
}
pexprPred = CPredicateUtils::PexprConjunction(m_pmp, pdrgpexpr);
}
pbsEdges->Release();
return pexprPred;
}
示例13: DrgPexpr
//---------------------------------------------------------------------------
// @function:
// CPartitionPropagationSpec::PdrgpexprPredicatesOnKey
//
// @doc:
// Returns an array of predicates on the given partitioning key given
// an array of predicates on all keys
//
//---------------------------------------------------------------------------
DrgPexpr *
CPartitionPropagationSpec::PdrgpexprPredicatesOnKey
(
IMemoryPool *pmp,
DrgPexpr *pdrgpexpr,
CColRef *pcr,
CColRefSet *pcrsKeys,
CBitSet **ppbs
)
{
GPOS_ASSERT(NULL != pdrgpexpr);
GPOS_ASSERT(NULL != pcr);
GPOS_ASSERT(NULL != ppbs);
GPOS_ASSERT(NULL != *ppbs);
DrgPexpr *pdrgpexprResult = GPOS_NEW(pmp) DrgPexpr(pmp);
const ULONG ulLen = pdrgpexpr->UlLength();
for (ULONG ul = 0; ul < ulLen; ul++)
{
if ((*ppbs)->FBit(ul))
{
// this expression has already been added for another column
continue;
}
CExpression *pexpr = (*pdrgpexpr)[ul];
GPOS_ASSERT(pexpr->Pop()->FScalar());
CColRefSet *pcrsUsed = CDrvdPropScalar::Pdpscalar(pexpr->PdpDerive())->PcrsUsed();
CColRefSet *pcrsUsedKeys = GPOS_NEW(pmp) CColRefSet(pmp, *pcrsUsed);
pcrsUsedKeys->Intersection(pcrsKeys);
if (1 == pcrsUsedKeys->CElements() && pcrsUsedKeys->FMember(pcr))
{
pexpr->AddRef();
pdrgpexprResult->Append(pexpr);
(*ppbs)->FExchangeSet(ul);
}
pcrsUsedKeys->Release();
}
return pdrgpexprResult;
}
示例14: DrgPds
//---------------------------------------------------------------------------
// @function:
// CPhysicalHashJoin::CreateHashRedistributeRequests
//
// @doc:
// Create the set of redistribute requests to send to first
// hash join child
//
//---------------------------------------------------------------------------
void
CPhysicalHashJoin::CreateHashRedistributeRequests
(
IMemoryPool *pmp
)
{
GPOS_ASSERT(NULL == m_pdrgpdsRedistributeRequests);
GPOS_ASSERT(NULL != m_pdrgpexprOuterKeys);
GPOS_ASSERT(NULL != m_pdrgpexprInnerKeys);
DrgPexpr *pdrgpexpr = NULL;
if (EceoRightToLeft == Eceo())
{
pdrgpexpr = m_pdrgpexprInnerKeys;
}
else
{
pdrgpexpr = m_pdrgpexprOuterKeys;
}
m_pdrgpdsRedistributeRequests = GPOS_NEW(pmp) DrgPds(pmp);
const ULONG ulExprs = std::min((ULONG) GPOPT_MAX_HASH_DIST_REQUESTS, pdrgpexpr->UlLength());
if (1 < ulExprs)
{
for (ULONG ul = 0; ul < ulExprs; ul++)
{
DrgPexpr *pdrgpexprCurrent = GPOS_NEW(pmp) DrgPexpr(pmp);
CExpression *pexpr = (*pdrgpexpr)[ul];
pexpr->AddRef();
pdrgpexprCurrent->Append(pexpr);
// add a separate request for each hash join key
// TODO: - Dec 30, 2011; change fNullsColocated to false when our
// distribution matching can handle differences in NULL colocation
CDistributionSpecHashed *pdshashedCurrent = GPOS_NEW(pmp) CDistributionSpecHashed(pdrgpexprCurrent, true /* fNullsCollocated */);
m_pdrgpdsRedistributeRequests->Append(pdshashedCurrent);
}
}
// add a request that contains all hash join keys
pdrgpexpr->AddRef();
CDistributionSpecHashed *pdshashed = GPOS_NEW(pmp) CDistributionSpecHashed(pdrgpexpr, true /* fNullsCollocated */);
m_pdrgpdsRedistributeRequests->Append(pdshashed);
}
示例15: jo
//---------------------------------------------------------------------------
// @function:
// CXformExpandNAryJoin::Transform
//
// @doc:
// Actual transformation of n-ary join to cluster of inner joins
//
//---------------------------------------------------------------------------
void
CXformExpandNAryJoin::Transform
(
CXformContext *pxfctxt,
CXformResult *pxfres,
CExpression *pexpr
)
const
{
GPOS_ASSERT(NULL != pxfctxt);
GPOS_ASSERT(NULL != pxfres);
GPOS_ASSERT(FPromising(pxfctxt->Pmp(), this, pexpr));
GPOS_ASSERT(FCheckPattern(pexpr));
IMemoryPool *pmp = pxfctxt->Pmp();
const ULONG ulArity = pexpr->UlArity();
GPOS_ASSERT(ulArity >= 3);
DrgPexpr *pdrgpexpr = GPOS_NEW(pmp) DrgPexpr(pmp);
for (ULONG ul = 0; ul < ulArity - 1; ul++)
{
CExpression *pexprChild = (*pexpr)[ul];
pexprChild->AddRef();
pdrgpexpr->Append(pexprChild);
}
CExpression *pexprScalar = (*pexpr)[ulArity - 1];
DrgPexpr *pdrgpexprPreds = CPredicateUtils::PdrgpexprConjuncts(pmp, pexprScalar);
// create a join order based on query-specified order of joins
CJoinOrder jo(pmp, pdrgpexpr, pdrgpexprPreds);
CExpression *pexprResult = jo.PexprExpand();
// normalize resulting expression
CExpression *pexprNormalized = CNormalizer::PexprNormalize(pmp, pexprResult);
pexprResult->Release();
pxfres->Add(pexprNormalized);
AddSpecifiedJoinOrder(pmp, pexpr, pxfres);
}