コード例 #1
0
ファイル: CConstraint.cpp プロジェクト: hsyuan/gporca
//---------------------------------------------------------------------------
//	@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);
}
コード例 #2
0
//---------------------------------------------------------------------------
//	@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);
}
コード例 #3
0
//---------------------------------------------------------------------------
//	@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*/);
}
コード例 #4
0
ファイル: CCNFConverter.cpp プロジェクト: HanumathRao/gporca
//---------------------------------------------------------------------------
//	@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;
}
コード例 #5
0
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);
	}
}
コード例 #6
0
ファイル: CNormalizer.cpp プロジェクト: godouxm/gporca
//---------------------------------------------------------------------------
//	@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
0
//---------------------------------------------------------------------------
//	@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);
}
コード例 #8
0
ファイル: CNormalizer.cpp プロジェクト: godouxm/gporca
//---------------------------------------------------------------------------
//	@function:
//		CNormalizer::SplitConjunctForSeqPrj
//
//	@doc:
//		Split the given conjunct into pushable and unpushable predicates
//		for a sequence project expression
//
//---------------------------------------------------------------------------
void
CNormalizer::SplitConjunctForSeqPrj
	(
	IMemoryPool *pmp,
	CExpression *pexprSeqPrj,
	CExpression *pexprConj,
	DrgPexpr **ppdrgpexprPushable,
	DrgPexpr **ppdrgpexprUnpushable
	)
{
	GPOS_ASSERT(NULL != pexprSeqPrj);
	GPOS_ASSERT(NULL != pexprConj);
	GPOS_ASSERT(NULL != ppdrgpexprPushable);
	GPOS_ASSERT(NULL != ppdrgpexprUnpushable);

	*ppdrgpexprPushable =  GPOS_NEW(pmp) DrgPexpr(pmp);
	*ppdrgpexprUnpushable = GPOS_NEW(pmp) DrgPexpr(pmp);
	DrgPexpr *pdrgpexprPreds = CPredicateUtils::PdrgpexprConjuncts(pmp, pexprConj);
	const ULONG ulPreds = pdrgpexprPreds->UlLength();
	for (ULONG ul = 0; ul < ulPreds; ul++)
	{
		CExpression *pexprPred = (*pdrgpexprPreds)[ul];
		pexprPred->AddRef();
		if (FPushableThruSeqPrjChild(pexprSeqPrj, pexprPred))
		{
			(*ppdrgpexprPushable)->Append(pexprPred);
		}
		else
		{
			(*ppdrgpexprUnpushable)->Append(pexprPred);
		}
	}
	pdrgpexprPreds->Release();
}
コード例 #9
0
ファイル: COptimizer.cpp プロジェクト: d/gporca
//---------------------------------------------------------------------------
//	@function:
//		COptimizer::PrintQuery
//
//	@doc:
//		Helper function to print query expression
//
//---------------------------------------------------------------------------
void
COptimizer::PrintQuery
	(
	IMemoryPool *pmp,
	CExpression *pexprTranslated,
	CQueryContext *pqc
	)
{
	CAutoTrace at(pmp);
	at.Os() << std::endl << "Algebrized query: " << std::endl << *pexprTranslated;

	DrgPexpr *pdrgpexpr = COptCtxt::PoctxtFromTLS()->Pcteinfo()->PdrgPexpr(pmp);
	const ULONG ulCTEs = pdrgpexpr->UlLength();
	if (0 < ulCTEs)
	{
		at.Os() << std::endl << "Common Table Expressions: ";
		for (ULONG ul = 0; ul < ulCTEs; ul++)
		{
			at.Os() << std::endl << *(*pdrgpexpr)[ul];
		}
	}
	pdrgpexpr->Release();

	CExpression *pexprPreprocessed = pqc->Pexpr();
	(void) pexprPreprocessed->PdpDerive();
	at.Os() << std::endl << "Algebrized preprocessed query: " << std::endl << *pexprPreprocessed;
}
コード例 #10
0
ファイル: CNormalizer.cpp プロジェクト: godouxm/gporca
//---------------------------------------------------------------------------
//	@function:
//		CNormalizer::SplitConjunct
//
//	@doc:
//		Split the given conjunct into pushable and unpushable predicates
//
//
//---------------------------------------------------------------------------
void
CNormalizer::SplitConjunct
	(
	IMemoryPool *pmp,
	CExpression *pexpr,
	CExpression *pexprConj,
	DrgPexpr **ppdrgpexprPushable,
	DrgPexpr **ppdrgpexprUnpushable
	)
{
	GPOS_ASSERT(pexpr->Pop()->FLogical());
	GPOS_ASSERT(pexprConj->Pop()->FScalar());
	GPOS_ASSERT(NULL != ppdrgpexprPushable);
	GPOS_ASSERT(NULL != ppdrgpexprUnpushable);

	// collect pushable predicates from given conjunct
	*ppdrgpexprPushable =  GPOS_NEW(pmp) DrgPexpr(pmp);
	*ppdrgpexprUnpushable =  GPOS_NEW(pmp) DrgPexpr(pmp);
	DrgPexpr *pdrgpexprConjuncts = CPredicateUtils::PdrgpexprConjuncts(pmp, pexprConj);
	const ULONG ulSize = pdrgpexprConjuncts->UlLength();
	for (ULONG ul = 0; ul < ulSize; ul++)
	{
		CExpression *pexprScalar = (*pdrgpexprConjuncts)[ul];
		pexprScalar->AddRef();
		if (FPushable(pexpr, pexprScalar))
		{
			(*ppdrgpexprPushable)->Append(pexprScalar);
		}
		else
		{
			(*ppdrgpexprUnpushable)->Append(pexprScalar);
		}
	}
	pdrgpexprConjuncts->Release();
}
コード例 #11
0
ファイル: CNormalizer.cpp プロジェクト: godouxm/gporca
//---------------------------------------------------------------------------
//	@function:
//		CNormalizer::PushThruUnaryWithScalarChild
//
//	@doc:
//		Push a conjunct through a unary operator with scalar child
//
//---------------------------------------------------------------------------
void
CNormalizer::PushThruUnaryWithScalarChild
	(
	IMemoryPool *pmp,
	CExpression *pexprLogical,
	CExpression *pexprConj,
	CExpression **ppexprResult
	)
{
	GPOS_ASSERT(NULL != pexprLogical);
	GPOS_ASSERT(2 == pexprLogical->UlArity());
	GPOS_ASSERT(NULL != pexprConj);
	GPOS_ASSERT(NULL != ppexprResult);

	// get logical and scalar children
	CExpression *pexprLogicalChild = (*pexprLogical)[0];
	CExpression *pexprScalarChild = (*pexprLogical)[1];

	// push conjuncts through the logical child
	CExpression *pexprNewLogicalChild = NULL;
	DrgPexpr *pdrgpexprUnpushable = NULL;

	// break scalar expression to conjuncts
	DrgPexpr *pdrgpexprConjuncts = CPredicateUtils::PdrgpexprConjuncts(pmp, pexprConj);

	PushThru(pmp, pexprLogicalChild, pdrgpexprConjuncts, &pexprNewLogicalChild, &pdrgpexprUnpushable);
	pdrgpexprConjuncts->Release();

	// create a new logical expression based on recursion results
	COperator *pop = pexprLogical->Pop();
	pop->AddRef();
	pexprScalarChild->AddRef();
	CExpression *pexprNewLogical = GPOS_NEW(pmp) CExpression(pmp, pop, pexprNewLogicalChild, pexprScalarChild);
	*ppexprResult = PexprSelect(pmp, pexprNewLogical, pdrgpexprUnpushable);
}
コード例 #12
0
ファイル: CNormalizer.cpp プロジェクト: godouxm/gporca
//---------------------------------------------------------------------------
//	@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;
}
コード例 #13
0
void
CDistributionSpecHashedNoOp::AppendEnforcers
	(
	IMemoryPool *pmp,
	CExpressionHandle &exprhdl,
	CReqdPropPlan *,
	DrgPexpr *pdrgpexpr,
	CExpression *pexpr
	)
{
	CDrvdProp *pdp = exprhdl.Pdp();
	CDistributionSpec *pdsChild = CDrvdPropPlan::Pdpplan(pdp)->Pds();
	CDistributionSpecHashed *pdsChildHashed = dynamic_cast<CDistributionSpecHashed *>(pdsChild);
	if (NULL == pdsChildHashed)
	{
		return;
	}
	
	DrgPexpr *pdrgpexprNoOpRedistributionColumns = pdsChildHashed->Pdrgpexpr();
	pdrgpexprNoOpRedistributionColumns->AddRef();
	CDistributionSpecHashedNoOp* pdsNoOp = GPOS_NEW(pmp) CDistributionSpecHashedNoOp(pdrgpexprNoOpRedistributionColumns);
	pexpr->AddRef();
	CExpression *pexprMotion = GPOS_NEW(pmp) CExpression
			(
					pmp,
					GPOS_NEW(pmp) CPhysicalMotionHashDistribute(pmp, pdsNoOp),
					pexpr
			);
	pdrgpexpr->Append(pexprMotion);
}
コード例 #14
0
//---------------------------------------------------------------------------
//	@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);
}
コード例 #15
0
//---------------------------------------------------------------------------
//	@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);
	}
}
コード例 #16
0
ファイル: CNormalizer.cpp プロジェクト: godouxm/gporca
//---------------------------------------------------------------------------
//	@function:
//		CNormalizer::PushThruSelect
//
//	@doc:
//		Push a conjunct through a select
//
//---------------------------------------------------------------------------
void
CNormalizer::PushThruSelect
	(
	IMemoryPool *pmp,
	CExpression *pexprSelect,
	CExpression *pexprConj,
	CExpression **ppexprResult
	)
{
	GPOS_ASSERT(NULL != pexprConj);
	GPOS_ASSERT(NULL != ppexprResult);

	CExpression *pexprLogicalChild = (*pexprSelect)[0];
	CExpression *pexprScalarChild = (*pexprSelect)[1];
	CExpression *pexprPred =  CPredicateUtils::PexprConjunction(pmp, pexprScalarChild, pexprConj);

	if (CUtils::FScalarConstTrue(pexprPred))
	{
		pexprPred->Release();
		*ppexprResult = PexprNormalize(pmp, pexprLogicalChild);

		return;
	}

	COperator::EOperatorId eopid = pexprLogicalChild->Pop()->Eopid();
	if (COperator::EopLogicalLeftOuterJoin == eopid)
	{
		CExpression *pexprSimplified = NULL;
		if (FSimplifySelectOnOuterJoin(pmp, pexprLogicalChild, pexprPred, &pexprSimplified))
		{
			// simplification succeeded, normalize resulting expression
			*ppexprResult = PexprNormalize(pmp, pexprSimplified);
			pexprPred->Release();
			pexprSimplified->Release();

			return;
		}
	}

	if (FPushThruOuterChild(pexprLogicalChild))
	{
		PushThruOuterChild(pmp, pexprLogicalChild, pexprPred, ppexprResult);
	}
	else
	{
		// logical child may not pass all predicates through, we need to collect
		// unpushable predicates, if any, into a top Select node
		DrgPexpr *pdrgpexprConjuncts = CPredicateUtils::PdrgpexprConjuncts(pmp, pexprPred);
		DrgPexpr *pdrgpexprRemaining = NULL;
		CExpression *pexpr = NULL;
		PushThru(pmp, pexprLogicalChild, pdrgpexprConjuncts, &pexpr, &pdrgpexprRemaining);
		*ppexprResult = PexprSelect(pmp, pexpr, pdrgpexprRemaining);
		pdrgpexprConjuncts->Release();
	}

	pexprPred->Release();
}
コード例 #17
0
ファイル: CCNFConverter.cpp プロジェクト: HanumathRao/gporca
//---------------------------------------------------------------------------
//	@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;
}
コード例 #18
0
ファイル: CBinding.cpp プロジェクト: HanumathRao/gporca
//---------------------------------------------------------------------------
//	@function:
//		CBinding::PexprExtract
//
//	@doc:
//		Extract a binding according to a given pattern;
//		Keep root node fixed;
//
//---------------------------------------------------------------------------
CExpression *
CBinding::PexprExtract
	(
	IMemoryPool *pmp,
	CGroupExpression *pgexpr,
	CExpression *pexprPattern,
	CExpression *pexprLast
	)
{
	GPOS_CHECK_ABORT;

	if (!pexprPattern->FMatchPattern(pgexpr))
	{
		// shallow matching fails
		return NULL;
	}
	
	// the previously extracted pattern must have the same root
	GPOS_ASSERT_IMP(NULL != pexprLast, pexprLast->Pgexpr() == pgexpr);

	COperator *popPattern = pexprPattern->Pop();
	if (popPattern->FPattern() && CPattern::PopConvert(popPattern)->FLeaf())
	{
		// return immediately; no deep extraction for leaf patterns
		pgexpr->Pop()->AddRef();
		return GPOS_NEW(pmp) CExpression(pmp, pgexpr->Pop(), pgexpr);
	}

	DrgPexpr *pdrgpexpr = NULL;
	ULONG ulArity = pgexpr->UlArity();
	if (0 == ulArity && NULL != pexprLast)
	{
		// no more bindings
		return NULL;
	}
	else
	{
		// attempt binding to children
		pdrgpexpr = GPOS_NEW(pmp) DrgPexpr(pmp);
		if (!FExtractChildren(pmp, pgexpr, pexprPattern, pexprLast, pdrgpexpr))
		{
			pdrgpexpr->Release();
			return NULL;
		}
	}					

	CExpression *pexpr = PexprFinalize(pmp, pgexpr, pdrgpexpr);
	GPOS_ASSERT(NULL != pexpr);
	
	return pexpr;
}
コード例 #19
0
ファイル: CStatsPredUtils.cpp プロジェクト: d/gporca
//---------------------------------------------------------------------------
//	@function:
//		CStatsPredUtils::FConjunction
//
//	@doc:
//		Is the condition a conjunctive predicate
//---------------------------------------------------------------------------
BOOL
CStatsPredUtils::FConjunction
	(
	IMemoryPool *pmp,
	CExpression *pexprPred
	)
{
	GPOS_ASSERT(NULL != pexprPred);
	DrgPexpr *pdrgpexprConjuncts = CPredicateUtils::PdrgpexprConjuncts(pmp, pexprPred);
	const ULONG ulLen = pdrgpexprConjuncts->UlLength();
	pdrgpexprConjuncts->Release();

	return (1 < ulLen);
}
コード例 #20
0
ファイル: CJoinOrderDP.cpp プロジェクト: d/gporca
//---------------------------------------------------------------------------
//	@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;
}
コード例 #21
0
ファイル: CStatsPredUtils.cpp プロジェクト: d/gporca
//---------------------------------------------------------------------------
//	@function:
//		CStatsPredUtils::PstatspredConj
//
//	@doc:
//		Create conjunctive statistics filter composed of the extracted
//		components of the conjunction
//---------------------------------------------------------------------------
CStatsPred *
CStatsPredUtils::PstatspredConj
	(
	IMemoryPool *pmp,
	CExpression *pexprScalar,
	CColRefSet *pcrsOuterRefs
	)
{
	GPOS_ASSERT(NULL != pexprScalar);
	DrgPexpr *pdrgpexprConjuncts = CPredicateUtils::PdrgpexprConjuncts(pmp, pexprScalar);
	const ULONG ulLen = pdrgpexprConjuncts->UlLength();

	DrgPstatspred *pdrgpstatspred = GPOS_NEW(pmp) DrgPstatspred(pmp);
	for (ULONG ul = 0; ul < ulLen; ul++)
	{
		CExpression *pexprPred = (*pdrgpexprConjuncts)[ul];
		CColRefSet *pcrsUsed = CDrvdPropScalar::Pdpscalar(pexprPred->PdpDerive())->PcrsUsed();
		if (NULL != pcrsOuterRefs && pcrsOuterRefs->FSubset(pcrsUsed))
		{
			// skip predicate with outer references
			continue;
		}

		if (CPredicateUtils::FOr(pexprPred))
		{
			CStatsPred *pstatspredDisj = PstatspredDisj(pmp, pexprPred, pcrsOuterRefs);
			if (NULL != pstatspredDisj)
			{
				pdrgpstatspred->Append(pstatspredDisj);
			}
		}
		else
		{
			AddSupportedStatsFilters(pmp, pdrgpstatspred, pexprPred, pcrsOuterRefs);
		}
	}

	pdrgpexprConjuncts->Release();

	if (0 < pdrgpstatspred->UlLength())
	{
		return GPOS_NEW(pmp) CStatsPredConj(pdrgpstatspred);
	}

	pdrgpstatspred->Release();

	return NULL;
}
コード例 #22
0
ファイル: CNormalizer.cpp プロジェクト: godouxm/gporca
//---------------------------------------------------------------------------
//	@function:
//		CNormalizer::PushThruSeqPrj
//
//	@doc:
//		Push a conjunct through a sequence project expression
//
//---------------------------------------------------------------------------
void
CNormalizer::PushThruSeqPrj
	(
	IMemoryPool *pmp,
	CExpression *pexprSeqPrj,
	CExpression *pexprConj,
	CExpression **ppexprResult
	)
{
	GPOS_ASSERT(NULL != pexprSeqPrj);
	GPOS_ASSERT(CLogical::EopLogicalSequenceProject == pexprSeqPrj->Pop()->Eopid());
	GPOS_ASSERT(NULL != pexprConj);
	GPOS_ASSERT(NULL != ppexprResult);

	// get logical and scalar children
	CExpression *pexprLogicalChild = (*pexprSeqPrj)[0];
	CExpression *pexprScalarChild = (*pexprSeqPrj)[1];

	// break scalar expression to pushable and unpushable conjuncts
	DrgPexpr *pdrgpexprPushable = NULL;
	DrgPexpr *pdrgpexprUnpushable = NULL;
	SplitConjunctForSeqPrj(pmp, pexprSeqPrj, pexprConj, &pdrgpexprPushable, &pdrgpexprUnpushable);

	CExpression *pexprNewLogicalChild = NULL;
	if (0 < pdrgpexprPushable->UlLength())
	{
		CExpression *pexprPushableConj = CPredicateUtils::PexprConjunction(pmp, pdrgpexprPushable);
		PushThru(pmp, pexprLogicalChild, pexprPushableConj, &pexprNewLogicalChild);
		pexprPushableConj->Release();
	}
	else
	{
		// no pushable predicates on top of sequence project,
		// we still need to process child recursively to push-down child's own predicates
		pdrgpexprPushable->Release();
		pexprNewLogicalChild = PexprNormalize(pmp, pexprLogicalChild);
	}

	// create a new logical expression based on recursion results
	COperator *pop = pexprSeqPrj->Pop();
	pop->AddRef();
	pexprScalarChild->AddRef();
	CExpression *pexprNewLogical = GPOS_NEW(pmp) CExpression(pmp, pop, pexprNewLogicalChild, pexprScalarChild);

	// create a select node for remaining predicates, if any
	*ppexprResult = PexprSelect(pmp, pexprNewLogical, pdrgpexprUnpushable);
}
コード例 #23
0
ファイル: CPhysicalJoin.cpp プロジェクト: d/gporca
//---------------------------------------------------------------------------
//	@function:
//		CPhysicalJoin::FHashJoinPossible
//
//	@doc:
//		Check if predicate is hashjoin-able and extract arrays of hash keys
//
//---------------------------------------------------------------------------
BOOL
CPhysicalJoin::FHashJoinPossible
	(
	IMemoryPool *pmp,
	CExpression *pexpr,
	DrgPexpr *pdrgpexprOuter,
	DrgPexpr *pdrgpexprInner,
	CExpression **ppexprResult // output : join expression to be transformed to hash join
	)
{
	GPOS_ASSERT(COperator::EopLogicalNAryJoin != pexpr->Pop()->Eopid() &&
		CUtils::FLogicalJoin(pexpr->Pop()));

	// we should not be here if there are outer references
	GPOS_ASSERT(!CUtils::FHasOuterRefs(pexpr));
	GPOS_ASSERT(NULL != ppexprResult);

	// introduce explicit casting, if needed
	DrgPexpr *pdrgpexpr = CPredicateUtils::PdrgpexprCastEquality(pmp,  (*pexpr)[2]);

	// identify hashkeys
	ULONG ulPreds = pdrgpexpr->UlLength();
	for (ULONG ul = 0; ul < ulPreds; ul++)
	{
		CExpression *pexprPred = (*pdrgpexpr)[ul];
		if (FHashJoinCompatible(pexprPred, (*pexpr)[0], (*pexpr)[1]))
		{
			AddHashKeys(pexprPred, (*pexpr)[0], (*pexpr)[1], pdrgpexprOuter, pdrgpexprInner);
		}
	}
	
	// construct output join expression
	pexpr->Pop()->AddRef();
	(*pexpr)[0]->AddRef();
	(*pexpr)[1]->AddRef();
	*ppexprResult =
		GPOS_NEW(pmp) CExpression
			(
			pmp,
			pexpr->Pop(),
			(*pexpr)[0],
			(*pexpr)[1],
			CPredicateUtils::PexprConjunction(pmp, pdrgpexpr)
			);

	return (0 != pdrgpexprInner->UlLength());
}
コード例 #24
0
ファイル: CNormalizer.cpp プロジェクト: godouxm/gporca
//---------------------------------------------------------------------------
//	@function:
//		CNormalizer::PushThru
//
//	@doc:
//		Push an array of conjuncts through a logical expression;
//		compute an array of unpushable conjuncts
//
//---------------------------------------------------------------------------
void
CNormalizer::PushThru
	(
	IMemoryPool *pmp,
	CExpression *pexprLogical,
	DrgPexpr *pdrgpexprConjuncts,
	CExpression **ppexprResult,
	DrgPexpr **ppdrgpexprRemaining
	)
{
	GPOS_ASSERT(NULL != pexprLogical);
	GPOS_ASSERT(NULL != pdrgpexprConjuncts);
	GPOS_ASSERT(NULL != ppexprResult);

	DrgPexpr *pdrgpexprPushable =  GPOS_NEW(pmp) DrgPexpr(pmp);
	DrgPexpr *pdrgpexprUnpushable =  GPOS_NEW(pmp) DrgPexpr(pmp);

	const ULONG ulSize = pdrgpexprConjuncts->UlLength();
	for (ULONG ul = 0; ul < ulSize; ul++)
	{
		CExpression *pexprConj = (*pdrgpexprConjuncts)[ul];
		pexprConj->AddRef();
		if (FPushable(pexprLogical, pexprConj))
		{
			pdrgpexprPushable->Append(pexprConj);
		}
		else
		{
			pdrgpexprUnpushable->Append(pexprConj);
		}
	}

	// push through a conjunction of all pushable predicates
	CExpression *pexprPred = CPredicateUtils::PexprConjunction(pmp, pdrgpexprPushable);
	if (FPushThruOuterChild(pexprLogical))
	{
		PushThruOuterChild(pmp, pexprLogical, pexprPred, ppexprResult);
	}
	else
	{
		PushThru(pmp, pexprLogical, pexprPred, ppexprResult);
	}
	pexprPred->Release();

	*ppdrgpexprRemaining = pdrgpexprUnpushable;
}
コード例 #25
0
ファイル: CStatsPredUtils.cpp プロジェクト: d/gporca
//---------------------------------------------------------------------------
//	@function:
//		CStatsPredUtils::PstatspredDisj
//
//	@doc:
//		Create disjunctive statistics filter composed of the extracted
//		components of the disjunction
//---------------------------------------------------------------------------
CStatsPred *
CStatsPredUtils::PstatspredDisj
	(
	IMemoryPool *pmp,
	CExpression *pexprPred,
	CColRefSet *pcrsOuterRefs
	)
{
	GPOS_ASSERT(NULL != pexprPred);
	GPOS_ASSERT(CPredicateUtils::FOr(pexprPred));

	DrgPstatspred *pdrgpstatspredDisjChild = GPOS_NEW(pmp) DrgPstatspred(pmp);

	// remove duplicate components of the OR tree
	CExpression *pexprNew = CExpressionUtils::PexprDedupChildren(pmp, pexprPred);

	// extract the components of the OR tree
	DrgPexpr *pdrgpexpr = CPredicateUtils::PdrgpexprDisjuncts(pmp, pexprNew);
	const ULONG ulLen = pdrgpexpr->UlLength();
	for (ULONG ul = 0; ul < ulLen; ul++)
	{
		CExpression *pexpr = (*pdrgpexpr)[ul];
		CColRefSet *pcrsUsed = CDrvdPropScalar::Pdpscalar(pexpr->PdpDerive())->PcrsUsed();
		if (NULL != pcrsOuterRefs && pcrsOuterRefs->FSubset(pcrsUsed))
		{
			// skip predicate with outer references
			continue;
		}

		AddSupportedStatsFilters(pmp, pdrgpstatspredDisjChild, pexpr, pcrsOuterRefs);
	}

	// clean up
	pexprNew->Release();
	pdrgpexpr->Release();

	if (0 < pdrgpstatspredDisjChild->UlLength())
	{
		return GPOS_NEW(pmp) CStatsPredDisj(pdrgpstatspredDisjChild);
	}

	pdrgpstatspredDisjChild->Release();

	return NULL;
}
コード例 #26
0
//---------------------------------------------------------------------------
//	@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;
}
コード例 #27
0
ファイル: CPhysicalHashJoin.cpp プロジェクト: d/gporca
//---------------------------------------------------------------------------
//	@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);
}
コード例 #28
0
ファイル: CCNFConverter.cpp プロジェクト: HanumathRao/gporca
//---------------------------------------------------------------------------
//	@function:
//		CCNFConverter::Expand
//
//	@doc:
//		Recursively compute cross product over input array of arrays;
//		convert each cross product result to a conjunct and store it in
//		output array
//
//---------------------------------------------------------------------------
void
CCNFConverter::Expand
	(
	IMemoryPool *pmp,
	DrgPdrgPexpr *pdrgpdrgpexprInput, // input array of arrays
	DrgPexpr *pdrgpexprOutput, // output array
	DrgPexpr *pdrgpexprToExpand, // a cross product result to be expanded
	ULONG ulCurrent // index of current array to be used for expanding a cross product result
	)
{
	GPOS_CHECK_STACK_SIZE;
	GPOS_ASSERT(ulCurrent <= pdrgpdrgpexprInput->UlLength());

	if (ulCurrent == pdrgpdrgpexprInput->UlLength())
	{
		// exhausted input, add a new conjunct to output array
		pdrgpexprOutput->Append(CPredicateUtils::PexprDisjunction(pmp, pdrgpexprToExpand));

		return;
	}

	DrgPexpr *pdrgpexprCurrent = (*pdrgpdrgpexprInput)[ulCurrent];
	const ULONG ulArity = pdrgpexprCurrent->UlLength();
	for (ULONG ul = 0; ul < ulArity; ul++)
	{
		// append accumulated expressions to a new array
		DrgPexpr *pdrgpexpr = GPOS_NEW(pmp) DrgPexpr(pmp);
		CUtils::AddRefAppend<CExpression, CleanupRelease>(pdrgpexpr, pdrgpexprToExpand);

		// add an expression from current input array only if it's not equal to an existing one
		if (!CUtils::FEqualAny((*pdrgpexprCurrent)[ul], pdrgpexpr))
		{
			CExpression *pexpr = (*pdrgpexprCurrent)[ul];
			pexpr->AddRef();
			pdrgpexpr->Append(pexpr);
		}

		// recursively expand the resulting array
		Expand(pmp, pdrgpdrgpexprInput, pdrgpexprOutput, pdrgpexpr, ulCurrent + 1);
	}
	pdrgpexprToExpand->Release();
}
コード例 #29
0
//---------------------------------------------------------------------------
//	@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);
}
コード例 #30
0
ファイル: CCNFConverter.cpp プロジェクト: HanumathRao/gporca
//---------------------------------------------------------------------------
//	@function:
//		CCNFConverter::PdrgpexprConvertChildren
//
//	@doc:
//		Call converter recursively on children array
//
//---------------------------------------------------------------------------
DrgPexpr *
CCNFConverter::PdrgpexprConvertChildren
	(
	IMemoryPool *pmp,
	CExpression *pexpr
	)
{
	GPOS_ASSERT(NULL != pmp);
	GPOS_ASSERT(NULL != pexpr);

	const ULONG ulArity = pexpr->UlArity();
	DrgPexpr *pdrgpexpr = GPOS_NEW(pmp) DrgPexpr(pmp);
	for (ULONG ul = 0; ul < ulArity; ul++)
	{
		CExpression *pexprChild = Pexpr2CNF(pmp, (*pexpr)[ul]);
		pdrgpexpr->Append(pexprChild);
	}

	return pdrgpexpr;
}