Exemplo n.º 1
0
//---------------------------------------------------------------------------
//	@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;
}
Exemplo n.º 2
0
//---------------------------------------------------------------------------
//	@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);
}
Exemplo n.º 3
0
//---------------------------------------------------------------------------
//	@function:
//		CCNFConverterTest::EresUnittest_Basic
//
//	@doc:
//		Basic test
//
//---------------------------------------------------------------------------
GPOS_RESULT
CCNFConverterTest::EresUnittest_Basic()
{
	CAutoMemoryPool amp;
	IMemoryPool *pmp = amp.Pmp();

	// setup a file-based provider
	CMDProviderMemory *pmdp = CTestUtils::m_pmdpf;
	pmdp->AddRef();
	CMDAccessor mda(pmp, CMDCache::Pcache(), CTestUtils::m_sysidDefault, pmdp);

	typedef CExpression *(*Pfpexpr)(IMemoryPool*);
	Pfpexpr rgpf[] =
		{
		CTestUtils::PexprLogicalSelectWithNestedAnd,
		CTestUtils::PexprLogicalSelectWithNestedOr,
		CTestUtils::PexprLogicalSelectWithEvenNestedNot,
		CTestUtils::PexprLogicalSelectWithOddNestedNot,
		CTestUtils::PexprLogicalSelectWithNestedAndOrNot
		};

	for (ULONG i = 0; i < GPOS_ARRAY_SIZE(rgpf); i++)
	{
		// install opt context in TLS
		CAutoOptCtxt aoc
						(
						pmp,
						&mda,
						NULL,  /* pceeval */
						CTestUtils::Pcm(pmp)
						);

		// generate expression
		CExpression *pexpr = rgpf[i](pmp);
		CExpression *pexprPreprocessed = CExpressionPreprocessor::PexprPreprocess(pmp, pexpr);

		CWStringDynamic str(pmp);
		COstreamString oss(&str);

		oss	<< std::endl << "SCALAR EXPR:" << std::endl << *(*pexpr)[1] << std::endl;
		GPOS_TRACE(str.Wsz());
		str.Reset();

		if (1 < pexprPreprocessed->UlArity())
		{
			CExpression *pexprCNF = CCNFConverter::Pexpr2CNF(pmp, (*pexprPreprocessed)[1]);
			oss	<< std::endl << "CNF REPRESENTATION:" << std::endl << *pexprCNF << std::endl;
			GPOS_TRACE(str.Wsz());
			str.Reset();
			pexprCNF->Release();
		}

		pexpr->Release();
		pexprPreprocessed->Release();
	}

	return GPOS_OK;
}
	// test cardinality for predicates of the form: a + c = b
	// for such predicates, NDV based cardinality estimation is not applicable
	GPOS_RESULT
	CJoinCardinalityNDVBasedEqPredTest::EresUnittest_NDVCardEstimationNotApplicableMultipleIdents()
	{
		// cartesian product / 2.5
		// 2.5 = 1/.4 -- where .4 is default selectivity
		CDouble dRowsExpected(76004000);

		Fixture f(file_name);
		IMemoryPool *mp = f.Pmp();
		IStatisticsArray *statistics_array = f.PdrgPstat();

		CExpression *pexprLgGet = CTestUtils::PexprLogicalGet(mp);
		CLogicalGet *popGet = CLogicalGet::PopConvert(pexprLgGet->Pop());
		CColRefArray *colref_array = popGet->PdrgpcrOutput();

		// use the colid available in the input xml file
		CColRef *pcrLeft1 = (*colref_array)[2];
		CColRef *pcrLeft2 = (*colref_array)[1];
		CColRef *pcrRight = (*colref_array)[0];

		// create a scalar ident
		// CScalarIdent "column_0000" (0)
		CExpression *pexprScalarIdentRight = CUtils::PexprScalarIdent(mp, pcrRight);
		CExpression *pexprScalarIdentLeft2 = CUtils::PexprScalarIdent(mp, pcrLeft2);

		// create a scalar op expression column_0002 + column_0001
		//  CScalarOp (+)
		//	|--CScalarIdent "column_0002" (2)
		//	+--CScalarIdent "column_0001" (1)
		CExpression *pexprScOp = CUtils::PexprScalarOp(mp, pcrLeft1, pexprScalarIdentLeft2,
													   CWStringConst(GPOS_WSZ_LIT("+")),
													   GPOS_NEW(mp) CMDIdGPDB(GPDB_INT4_ADD_OP));

		// create a scalar comparision operator
		//	+--CScalarCmp (=)
		//	|--CScalarOp (+)
		//	|  |--CScalarIdent "column_0002" (2)
		//	|  +--CScalarIdent "column_0001" (1)
		//	+--CScalarIdent "column_0000" (0)
		CExpression *pScalarCmp = CUtils::PexprScalarEqCmp(mp, pexprScOp, pexprScalarIdentRight);
		IStatistics *join_stats = CJoinStatsProcessor::CalcAllJoinStats(mp, statistics_array, pScalarCmp,
																	   IStatistics::EsjtInnerJoin);

		GPOS_ASSERT(NULL != join_stats);
		CDouble dRowsActual(join_stats->Rows());

		GPOS_RESULT eres = GPOS_OK;
		if (floor(dRowsActual.Get()) != dRowsExpected)
		{
			eres = GPOS_FAILED;
		}

		join_stats->Release();
		pexprLgGet->Release();
		pScalarCmp->Release();

		return eres;
	}
Exemplo n.º 5
0
//---------------------------------------------------------------------------
//	@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();
}
	// test cardinality for predicates of the form: a + 1 = b
	// for such predicates, NDV based cardinality estimation is applicable
	GPOS_RESULT
	CJoinCardinalityNDVBasedEqPredTest::EresUnittest_NDVEqCardEstimation()
	{
		CDouble dRowsExpected(10000); // the minimum cardinality is min(NDV a, NDV b)

		Fixture f(file_name);
		IMemoryPool *mp = f.Pmp();
		IStatisticsArray *statistics_array = f.PdrgPstat();

		CExpression *pexprLgGet = CTestUtils::PexprLogicalGet(mp);
		CLogicalGet *popGet = CLogicalGet::PopConvert(pexprLgGet->Pop());
		CColRefArray *colref_array = popGet->PdrgpcrOutput();

		// use the colid available in the input xml file
		CColRef *pcrLeft = (*colref_array)[2];
		CColRef *pcrRight = (*colref_array)[0];

		// create a scalar ident
		// CScalarIdent "column_0000" (0)
		CExpression *pexprScalarIdentRight = CUtils::PexprScalarIdent(mp, pcrRight);

		// create a scalar op expression column_0002 + 10
		//  CScalarOp (+)
		//	|--CScalarIdent "column_0002" (2)
		//	+--CScalarConst (10)
		CExpression *pexprScConst = CUtils::PexprScalarConstInt4(mp, 10 /* val */);
		CExpression *pexprScOp = CUtils::PexprScalarOp(mp, pcrLeft, pexprScConst, CWStringConst(GPOS_WSZ_LIT("+")),
													   GPOS_NEW(mp) CMDIdGPDB(GPDB_INT4_ADD_OP));

		// create a scalar comparision operator
		//	+--CScalarCmp (=)
		//	|--CScalarOp (+)
		//	|  |--CScalarIdent "column_0002" (2)
		//	|  +--CScalarConst (10)
		//	+--CScalarIdent "column_0000" (0)
		CExpression *pScalarCmp = CUtils::PexprScalarEqCmp(mp, pexprScOp, pexprScalarIdentRight);

		IStatistics *join_stats = CJoinStatsProcessor::CalcAllJoinStats(mp, statistics_array, pScalarCmp,
																	   IStatistics::EsjtInnerJoin);

		GPOS_ASSERT(NULL != join_stats);
		CDouble dRowsActual(join_stats->Rows());
		GPOS_RESULT eres = GPOS_OK;

		if (std::floor(dRowsActual.Get()) != dRowsExpected)
		{
			eres = GPOS_FAILED;
		}

		join_stats->Release();
		pexprLgGet->Release();
		pScalarCmp->Release();

		return eres;
	}
Exemplo n.º 7
0
//---------------------------------------------------------------------------
//	@function:
//		CNormalizer::PexprSelect
//
//	@doc:
//		Return a Select expression, if needed, with a scalar condition made of
//		given array of conjuncts
//
//---------------------------------------------------------------------------
CExpression *
CNormalizer::PexprSelect
	(
	IMemoryPool *pmp,
	CExpression *pexpr,
	DrgPexpr *pdrgpexpr
	)
{
	GPOS_ASSERT(NULL != pexpr);
	GPOS_ASSERT(NULL != pdrgpexpr);

	if (0 == pdrgpexpr->UlLength())
	{
		// no predicate, return given expression
		pdrgpexpr->Release();
		return pexpr;
	}

	// result expression is a select over predicates
	CExpression *pexprConjunction = CPredicateUtils::PexprConjunction(pmp, pdrgpexpr);
	CExpression *pexprSelect = CUtils::PexprSafeSelect(pmp, pexpr, pexprConjunction);
	if (COperator::EopLogicalSelect != pexprSelect->Pop()->Eopid())
	{
		// Select node was pruned, return created expression
		return pexprSelect;
	}

	CExpression *pexprLogicalChild = (*pexprSelect)[0];
	COperator::EOperatorId eopidChild = pexprLogicalChild->Pop()->Eopid();
	if (COperator::EopLogicalLeftOuterJoin != eopidChild)
	{
		// child of Select is not an outer join, return created Select expression
		return pexprSelect;
	}

	// we have a Select on top of Outer Join expression, attempt simplifying expression into InnerJoin
	CExpression *pexprSimplified = NULL;
	if (FSimplifySelectOnOuterJoin(pmp, pexprLogicalChild, (*pexprSelect)[1], &pexprSimplified))
	{
		// simplification succeeded, normalize resulting expression
		pexprSelect->Release();
		CExpression *pexprResult = PexprNormalize(pmp, pexprSimplified);
		pexprSimplified->Release();

		return pexprResult;
	}

	// simplification failed, return created Select expression
	return pexprSelect;
}
Exemplo n.º 8
0
//---------------------------------------------------------------------------
//	@function:
//		CXformExpandNAryJoin::AddSpecifiedJoinOrder
//
//	@doc:
//		Expand NAry join in the specified order of inputs
//
//---------------------------------------------------------------------------
void
CXformExpandNAryJoin::AddSpecifiedJoinOrder
(
    IMemoryPool *pmp,
    CExpression *pexpr,
    CXformResult *pxfres
)
{
    GPOS_ASSERT(COperator::EopLogicalNAryJoin == pexpr->Pop()->Eopid());

    const ULONG ulArity = pexpr->UlArity();
    if (4 > ulArity)
    {
        return;
    }

    // create a join order with same order of given relations
    (*pexpr)[0]->AddRef();
    (*pexpr)[1]->AddRef();
    CExpression *pexprJoin = CUtils::PexprLogicalJoin<CLogicalInnerJoin>(pmp, (*pexpr)[0], (*pexpr)[1], CPredicateUtils::PexprConjunction(pmp, NULL));
    for (ULONG ul = 2; ul < ulArity - 1; ul++)
    {
        (*pexpr)[ul]->AddRef();
        pexprJoin = CUtils::PexprLogicalJoin<CLogicalInnerJoin>(pmp, pexprJoin, (*pexpr)[ul], CPredicateUtils::PexprConjunction(pmp, NULL));
    }
    CExpression *pexprScalar = (*pexpr)[ulArity - 1];
    pexprScalar->AddRef();
    CExpression *pexprSelect = CUtils::PexprLogicalSelect(pmp, pexprJoin, pexprScalar);
    CExpression *pexprNormalized = CNormalizer::PexprNormalize(pmp, pexprSelect);
    pexprSelect->Release();
    pxfres->Add(pexprNormalized);
}
//---------------------------------------------------------------------------
//	@function:
//		CXformGbAggWithMDQA2Join::PexprExpandMDQAs
//
//	@doc:
//		Expand GbAgg with multiple distinct aggregates into a join of single
//		distinct aggregates,
//		return NULL if expansion is not done
//
//---------------------------------------------------------------------------
CExpression *
CXformGbAggWithMDQA2Join::PexprExpandMDQAs
	(
	IMemoryPool *pmp,
	CExpression *pexpr
	)
{
	GPOS_ASSERT(NULL != pexpr);
	GPOS_ASSERT(COperator::EopLogicalGbAgg == pexpr->Pop()->Eopid());

	COperator *pop = pexpr->Pop();
	if (CLogicalGbAgg::PopConvert(pop)->FGlobal())
	{
		BOOL fHasMultipleDistinctAggs = CDrvdPropScalar::Pdpscalar((*pexpr)[1]->PdpDerive())->FHasMultipleDistinctAggs();
		if (fHasMultipleDistinctAggs)
		{
			CExpression *pexprExpanded = PexprMDQAs2Join(pmp, pexpr);

			// recursively process the resulting expression
			CExpression *pexprResult = PexprTransform(pmp, pexprExpanded);
			pexprExpanded->Release();

			return pexprResult;
		}
	}

	return NULL;
}
Exemplo n.º 10
0
CValue* CParser::GetValue(STR_String& txt, bool bFallbackToText)
{
	// returns parsed text into a value,
	// empty string returns NULL value !
	// if bFallbackToText then unparsed stuff is put into text

	CValue* result=NULL;
	CExpression* expr = ProcessText(txt);
	if (expr) {
		result = expr->Calculate();
		expr->Release();
	}
	if (result)
	{
		// if the parsed stuff lead to an errorvalue, don't return errors, just NULL
		if (result->IsError()) {
			result->Release();
			result=NULL;
			if (bFallbackToText) {
				if (txt.Length()>0)
				{
					result = new CStringValue(txt,"");
				}
			}
		}
	}
	return result;
}
Exemplo n.º 11
0
//---------------------------------------------------------------------------
//	@function:
//		CNormalizer::PexprPullUpProjections
//
//	@doc:
//		Pulls up logical projects as far as possible, and combines consecutive
//		projects if possible
//
//---------------------------------------------------------------------------
CExpression *
CNormalizer::PexprPullUpProjections
	(
	IMemoryPool *pmp,
	CExpression *pexpr
	)
{
	GPOS_ASSERT(NULL != pexpr);

	BOOL fPullUp = true;
	pexpr->AddRef();
	CExpression *pexprOutput = pexpr;

	while (fPullUp)
	{
		fPullUp = false;

		CExpression *pexprOutputNew = PexprPullUpAndCombineProjects(pmp, pexprOutput, &fPullUp);
		pexprOutput->Release();
		pexprOutput = pexprOutputNew;
	}

	GPOS_ASSERT(FLocalColsSubsetOfInputCols(pmp, pexprOutput));

	return pexprOutput;
}
Exemplo n.º 12
0
//---------------------------------------------------------------------------
//	@function:
//		CStatsPredUtils::Pdrgpstatsjoin
//
//	@doc:
//		Helper function to extract array of statistics join filter from
//		an expression
//---------------------------------------------------------------------------
DrgPstatsjoin *
CStatsPredUtils::Pdrgpstatsjoin
	(
	IMemoryPool *pmp,
	CExpressionHandle &exprhdl,
	CExpression *pexprScalarInput,
	DrgPcrs *pdrgpcrsOutput, // array of output columns of join's relational inputs
	CColRefSet *pcrsOuterRefs
	)
{
	GPOS_ASSERT(NULL != pdrgpcrsOutput);

	// remove implied predicates from join condition to avoid cardinality under-estimation
	CExpression *pexprScalar = CPredicateUtils::PexprRemoveImpliedConjuncts(pmp, pexprScalarInput, exprhdl);

	// extract all the conjuncts
	CStatsPred *pstatspredUnsupported = NULL;
	DrgPstatsjoin *pdrgpstatsjoin = PdrgpstatsjoinExtract
										(
										pmp,
										pexprScalar,
										pdrgpcrsOutput,
										pcrsOuterRefs,
										&pstatspredUnsupported
										);

	// TODO:  May 15 2014, handle unsupported predicates for LASJ, LOJ and LS joins
	// clean up
	CRefCount::SafeRelease(pstatspredUnsupported);
	pexprScalar->Release();

	return pdrgpstatsjoin;
}
Exemplo n.º 13
0
//---------------------------------------------------------------------------
//	@function:
//		CStatsPredUtils::PdrgpstatsjoinExtract
//
//	@doc:
//		Helper function to extract array of statistics join filter
//		from an array of join predicates
//
//---------------------------------------------------------------------------
DrgPstatsjoin *
CStatsPredUtils::PdrgpstatsjoinExtract
	(
	IMemoryPool *pmp,
	CExpression *pexprScalar,
	DrgPcrs *pdrgpcrsOutput, // array of output columns of join's relational inputs
	CColRefSet *pcrsOuterRefs,
	CStatsPred **ppstatspredUnsupported
	)
{
	GPOS_ASSERT(NULL != pexprScalar);
	GPOS_ASSERT(NULL != pdrgpcrsOutput);

	DrgPstatsjoin *pdrgpstatsjoin = GPOS_NEW(pmp) DrgPstatsjoin(pmp);

	DrgPexpr *pdrgpexprUnsupported = GPOS_NEW(pmp) DrgPexpr(pmp);

	// extract all the conjuncts
	DrgPexpr *pdrgpexprConjuncts = CPredicateUtils::PdrgpexprConjuncts(pmp, pexprScalar);
	const ULONG ulSize = pdrgpexprConjuncts->UlLength();
	for (ULONG ul = 0; ul < ulSize; ul++)
	{
		CExpression *pexprPred = (*pdrgpexprConjuncts) [ul];
		CStatisticsJoin *pstatsjoin = PstatsjoinExtract
										(
										pmp,
										pexprPred,
										pdrgpcrsOutput,
										pcrsOuterRefs,
										pdrgpexprUnsupported
										);
		if (NULL != pstatsjoin)
		{
			pdrgpstatsjoin->Append(pstatsjoin);
		}
	}

	const ULONG ulUnsupported = pdrgpexprUnsupported->UlLength();
	if (1 == ulUnsupported)
	{
		*ppstatspredUnsupported = CStatsPredUtils::PstatspredExtract(pmp, (*pdrgpexprUnsupported)[0], pcrsOuterRefs);
	}
	else if (1 < ulUnsupported)
	{
		pdrgpexprUnsupported->AddRef();
		CExpression *pexprConj = CPredicateUtils::PexprConjDisj(pmp, pdrgpexprUnsupported, true /* fConjunction */);
		*ppstatspredUnsupported = CStatsPredUtils::PstatspredExtract(pmp, pexprConj, pcrsOuterRefs);
		pexprConj->Release();
	}

	// clean up
	pdrgpexprUnsupported->Release();
	pdrgpexprConjuncts->Release();

	return pdrgpstatsjoin;
}
Exemplo n.º 14
0
//---------------------------------------------------------------------------
//	@function:
//		CDecorrelator::FProcessGbAgg
//
//	@doc:
//		Decorrelate GbAgg operator
//
//---------------------------------------------------------------------------
BOOL
CDecorrelator::FProcessGbAgg
	(
	IMemoryPool *pmp,
	CExpression *pexpr,
	BOOL, // fEqualityOnly
	CExpression **ppexprDecorrelated,
	DrgPexpr *pdrgpexprCorrelations
	)
{
	CLogicalGbAgg *popAggOriginal = CLogicalGbAgg::PopConvert(pexpr->Pop());
	
	// fail if agg has outer references
	if (CUtils::FHasOuterRefs(pexpr) && !CUtils::FHasOuterRefs((*pexpr)[0]))
	{
		return false;
	}

	// TODO: 12/20/2012 - ; check for strictness of agg function

	// decorrelate relational child
	CExpression *pexprRelational = NULL;
	if (!FProcess(pmp, (*pexpr)[0], true /*fEqualityOnly*/, &pexprRelational, pdrgpexprCorrelations))
	{
		GPOS_ASSERT(NULL == pexprRelational);
		return false;
	}
	
	// get the output columns of decorrelated child
	CColRefSet *pcrsOutput = CDrvdPropRelational::Pdprel(pexprRelational->PdpDerive())->PcrsOutput();

	// create temp expression of correlations to determine inner columns
	pdrgpexprCorrelations->AddRef();
	CExpression *pexprTemp = CPredicateUtils::PexprConjunction(pmp, pdrgpexprCorrelations);
	CColRefSet *pcrs = 
		GPOS_NEW(pmp) CColRefSet(pmp,
			*(CDrvdPropScalar::Pdpscalar(pexprTemp->PdpDerive())->PcrsUsed()));
		
	pcrs->Intersection(pcrsOutput);
	pexprTemp->Release();

	// add grouping columns from original agg
	pcrs->Include(popAggOriginal->Pdrgpcr());

	// assemble grouping columns
	DrgPcr *pdrgpcr = pcrs->Pdrgpcr(pmp);
	pcrs->Release();
	
	// assemble agg
	CExpression *pexprProjList = (*pexpr)[1];
	pexprProjList->AddRef();
	CLogicalGbAgg *popAgg = GPOS_NEW(pmp) CLogicalGbAgg(pmp, pdrgpcr, popAggOriginal->Egbaggtype());
	*ppexprDecorrelated = GPOS_NEW(pmp) CExpression(pmp, popAgg, pexprRelational, pexprProjList);
	
	return true;
}
Exemplo n.º 15
0
//---------------------------------------------------------------------------
//	@function:
//		CLogicalSelect::PstatsDerive
//
//	@doc:
//		Derive statistics based on filter predicates
//
//---------------------------------------------------------------------------
IStatistics *
CLogicalSelect::PstatsDerive
	(
	IMemoryPool *pmp,
	CExpressionHandle &exprhdl,
	DrgPstat *pdrgpstatCtxt
	)
	const
{
	GPOS_ASSERT(Esp(exprhdl) > EspNone);
	IStatistics *pstatsChild = exprhdl.Pstats(0);

	if (exprhdl.Pdpscalar(1 /*ulChildIndex*/)->FHasSubquery())
	{
		// in case of subquery in select predicate, we return child stats
		pstatsChild->AddRef();
		return pstatsChild;
	}

	// remove implied predicates from selection condition to avoid cardinality under-estimation
	CExpression *pexprScalar = exprhdl.PexprScalarChild(1 /*ulChildIndex*/);
	CExpression *pexprPredicate = CPredicateUtils::PexprRemoveImpliedConjuncts(pmp, pexprScalar, exprhdl);


	// split selection predicate into local predicate and predicate involving outer references
	CExpression *pexprLocal = NULL;
	CExpression *pexprOuterRefs = NULL;

	// get outer references from expression handle
	CColRefSet *pcrsOuter = exprhdl.Pdprel()->PcrsOuter();

	CPredicateUtils::SeparateOuterRefs(pmp, pexprPredicate, pcrsOuter, &pexprLocal, &pexprOuterRefs);
	pexprPredicate->Release();

	IStatistics *pstats = CStatisticsUtils::PstatsFilter(pmp, exprhdl, pstatsChild, pexprLocal, pexprOuterRefs, pdrgpstatCtxt);
	pexprLocal->Release();
	pexprOuterRefs->Release();

	return pstats;
}
Exemplo n.º 16
0
//---------------------------------------------------------------------------
//	@function:
//		CLogicalDifferenceAll::PstatsDerive
//
//	@doc:
//		Derive statistics
//
//---------------------------------------------------------------------------
IStatistics *
CLogicalDifferenceAll::PstatsDerive
	(
	IMemoryPool *pmp,
	CExpressionHandle &exprhdl,
	DrgPstat * // not used
	)
	const
{
	GPOS_ASSERT(Esp(exprhdl) > EspNone);

	// difference all is transformed into a LASJ,
	// we follow the same route to compute statistics
	DrgPcrs *pdrgpcrsOutput = GPOS_NEW(pmp) DrgPcrs(pmp);
	const ULONG ulSize = m_pdrgpdrgpcrInput->UlLength();
	for (ULONG ul = 0; ul < ulSize; ul++)
	{
		CColRefSet *pcrs = GPOS_NEW(pmp) CColRefSet(pmp, (*m_pdrgpdrgpcrInput)[ul]);
		pdrgpcrsOutput->Append(pcrs);
	}

	IStatistics *pstatsOuter = exprhdl.Pstats(0);
	IStatistics *pstatsInner = exprhdl.Pstats(1);

	// construct the scalar condition for the LASJ
	CExpression *pexprScCond = CUtils::PexprConjINDFCond(pmp, m_pdrgpdrgpcrInput);

	// compute the statistics for LASJ
	CColRefSet *pcrsOuterRefs = exprhdl.Pdprel()->PcrsOuter();
	DrgPstatsjoin *pdrgpstatsjoin = CStatsPredUtils::Pdrgpstatsjoin
														(
														pmp, 
														exprhdl, 
														pexprScCond, 
														pdrgpcrsOutput, 
														pcrsOuterRefs
														);
	IStatistics *pstatsLASJ = pstatsOuter->PstatsLASJoin
											(
											pmp,
											pstatsInner,
											pdrgpstatsjoin,
											true /* fIgnoreLasjHistComputation*/
											);

	// clean up
	pexprScCond->Release();
	pdrgpstatsjoin->Release();
	pdrgpcrsOutput->Release();

	return pstatsLASJ;
}
Exemplo n.º 17
0
//---------------------------------------------------------------------------
//	@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;
}
Exemplo n.º 18
0
//---------------------------------------------------------------------------
//	@function:
//		CXformGbAggWithMDQA2Join::PexprMDQAs2Join
//
//	@doc:
//		Converts GbAgg with multiple distinct aggregates into a join of single
//		distinct aggregates,
//
//		distinct aggregates that share the same argument are grouped together
//		in one leaf of the generated join expression,
//
//		non-distinct aggregates are also grouped together in one leaf of the
//		generated join expression
//
//---------------------------------------------------------------------------
CExpression *
CXformGbAggWithMDQA2Join::PexprMDQAs2Join
	(
	IMemoryPool *pmp,
	CExpression *pexpr
	)
{
	GPOS_ASSERT(NULL != pexpr);
	GPOS_ASSERT(COperator::EopLogicalGbAgg == pexpr->Pop()->Eopid());
	GPOS_ASSERT(CDrvdPropScalar::Pdpscalar((*pexpr)[1]->PdpDerive())->FHasMultipleDistinctAggs());

	// extract components
	CExpression *pexprChild = (*pexpr)[0];

	CColRefSet *pcrsChildOutput = CDrvdPropRelational::Pdprel(pexprChild->PdpDerive())->PcrsOutput();
	DrgPcr *pdrgpcrChildOutput = pcrsChildOutput->Pdrgpcr(pmp);

	// create a CTE producer based on child expression
	CCTEInfo *pcteinfo = COptCtxt::PoctxtFromTLS()->Pcteinfo();
	const ULONG ulCTEId = pcteinfo->UlNextId();
	(void) CXformUtils::PexprAddCTEProducer(pmp, ulCTEId, pdrgpcrChildOutput, pexprChild);

	// create a CTE consumer with child output columns
	CExpression *pexprConsumer =
			GPOS_NEW(pmp) CExpression
				(
				pmp,
				GPOS_NEW(pmp) CLogicalCTEConsumer(pmp, ulCTEId, pdrgpcrChildOutput)
				);
	pcteinfo->IncrementConsumers(ulCTEId);

	// finalize GbAgg expression by replacing its child with CTE consumer
	pexpr->Pop()->AddRef();
	(*pexpr)[1]->AddRef();
	CExpression *pexprGbAggWithConsumer = GPOS_NEW(pmp) CExpression(pmp, pexpr->Pop(), pexprConsumer, (*pexpr)[1]);

	CExpression *pexprJoinDQAs = CXformUtils::PexprGbAggOnCTEConsumer2Join(pmp, pexprGbAggWithConsumer);
	GPOS_ASSERT(NULL != pexprJoinDQAs);

	pexprGbAggWithConsumer->Release();

	return GPOS_NEW(pmp) CExpression
					(
					pmp,
					GPOS_NEW(pmp) CLogicalCTEAnchor(pmp, ulCTEId),
					pexprJoinDQAs
					);
}
Exemplo n.º 19
0
//---------------------------------------------------------------------------
//	@function:
//		CDecorrelator::FProcessSelect
//
//	@doc:
//		Decorrelate select operator
//
//---------------------------------------------------------------------------
BOOL
CDecorrelator::FProcessSelect
	(
	IMemoryPool *pmp,
	CExpression *pexpr,
	BOOL fEqualityOnly,
	CExpression **ppexprDecorrelated,
	DrgPexpr *pdrgpexprCorrelations
	)
{
	GPOS_ASSERT(COperator::EopLogicalSelect == pexpr->Pop()->Eopid());

	// decorrelate relational child
	CExpression *pexprRelational = NULL;
	if (!FProcess(pmp, (*pexpr)[0], fEqualityOnly, &pexprRelational, pdrgpexprCorrelations))
	{
		GPOS_ASSERT(NULL == pexprRelational);
		return false;
	}

	// process predicate
	CExpression *pexprPredicate = NULL;
	CColRefSet *pcrsOutput = CDrvdPropRelational::Pdprel(pexpr->PdpDerive())->PcrsOutput();
	BOOL fSuccess  = FProcessPredicate(pmp, pexpr, (*pexpr)[1], fEqualityOnly, pcrsOutput, &pexprPredicate, pdrgpexprCorrelations);
	
	// build substitute
	if (fSuccess)
	{
		if (NULL != pexprPredicate)
		{
			CLogicalSelect *popSelect = CLogicalSelect::PopConvert(pexpr->Pop());
			popSelect->AddRef();
			
			*ppexprDecorrelated = GPOS_NEW(pmp) CExpression(pmp, popSelect, pexprRelational, pexprPredicate);
		}
		else 
		{
			*ppexprDecorrelated = pexprRelational;
		}

	}
	else
	{
		pexprRelational->Release();
	}
	
	return fSuccess;
}
Exemplo n.º 20
0
//---------------------------------------------------------------------------
//	@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);
}
Exemplo n.º 21
0
//---------------------------------------------------------------------------
//	@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;
}
Exemplo n.º 22
0
/* calculate expression from inputtext */
EXP_ValueHandle EXP_ParseInput(const char* inputtext)
{
	CValue* resultval=NULL;
	CParser parser;
	CExpression* expr = parser.ProcessText(inputtext);
	if (expr)
	{
		resultval = expr->Calculate();
		expr->Release();
	}
	else
	{
		resultval = new CErrorValue("couldn't parsetext");
	}

	return (EXP_ValueHandle) resultval;
}
Exemplo n.º 23
0
//---------------------------------------------------------------------------
//	@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;
}
Exemplo n.º 24
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);
}
//---------------------------------------------------------------------------
//	@function:
//		CXformInnerJoinWithInnerSelect2IndexGetApply::Transform
//
//	@doc:
//		Actual transformation
//
//---------------------------------------------------------------------------
void
CXformInnerJoinWithInnerSelect2IndexGetApply::Transform
	(
	CXformContext *pxfctxt,
	CXformResult *pxfres,
	CExpression *pexpr
	)
	const
{
	GPOS_ASSERT(NULL != pxfctxt);
	GPOS_ASSERT(FPromising(pxfctxt->Pmp(), this, pexpr));
	GPOS_ASSERT(FCheckPattern(pexpr));

	IMemoryPool *pmp = pxfctxt->Pmp();

	// extract components
	CExpression *pexprOuter = (*pexpr)[0];
	CExpression *pexprInner = (*pexpr)[1];
	CExpression *pexprScalar = (*pexpr)[2];

	GPOS_ASSERT(COperator::EopLogicalSelect == pexprInner->Pop()->Eopid());
	CExpression *pexprGet = (*pexprInner)[0];
	GPOS_ASSERT(COperator::EopLogicalGet == pexprGet->Pop()->Eopid());

	CTableDescriptor *ptabdescInner = CLogicalGet::PopConvert (pexprGet->Pop ())->Ptabdesc();
	CExpression *pexprAllPredicates = CPredicateUtils::PexprConjunction(pmp, pexprScalar, (*pexprInner)[1]);
	CreateHomogeneousIndexApplyAlternatives
		(
		pmp,
		pexpr->Pop()->UlOpId(),
		pexprOuter,
		pexprGet,
		pexprAllPredicates,
		ptabdescInner,
		NULL, // popDynamicGet
		pxfres,
		IMDIndex::EmdindBtree
		);
	pexprAllPredicates->Release();
}
//---------------------------------------------------------------------------
//	@function:
//		CXformLeftAntiSemiJoin2CrossProduct::Transform
//
//	@doc:
//		Anti semi join whose join predicate does not use columns from
//		join's inner child is equivalent to a Cross Product between outer
//		child (after pushing negated join predicate), and one tuple from
//		inner child
//
//
//---------------------------------------------------------------------------
void
CXformLeftAntiSemiJoin2CrossProduct::Transform
	(
	CXformContext *pxfctxt,
	CXformResult *pxfres,
	CExpression *pexpr
	)
	const
{
	GPOS_ASSERT(NULL != pxfctxt);
	GPOS_ASSERT(FPromising(pxfctxt->Pmp(), this, pexpr));
	GPOS_ASSERT(FCheckPattern(pexpr));

	IMemoryPool *pmp = pxfctxt->Pmp();

	// extract components
	CExpression *pexprOuter = (*pexpr)[0];
	CExpression *pexprInner = (*pexpr)[1];
	CExpression *pexprScalar = (*pexpr)[2];
	pexprOuter->AddRef();
	pexprInner->AddRef();
	pexprScalar->AddRef();

	CExpression *pexprNegatedScalar = CUtils::PexprNegate(pmp, pexprScalar);

	// create a (limit 1) on top of inner child
	CExpression *pexprLimitOffset = CUtils::PexprScalarConstInt8(pmp, 0 /*iVal*/);
	CExpression *pexprLimitCount = CUtils::PexprScalarConstInt8(pmp, 1 /*iVal*/);
	COrderSpec *pos = GPOS_NEW(pmp) COrderSpec(pmp);
	CLogicalLimit *popLimit =
			GPOS_NEW(pmp) CLogicalLimit(pmp, pos, true /*fGlobal*/, true /*fHasCount*/, false /*fNonRemovableLimit*/);
	CExpression *pexprLimit = GPOS_NEW(pmp) CExpression(pmp, popLimit, pexprInner, pexprLimitOffset, pexprLimitCount);

	// create cross product
	CExpression *pexprJoin = CUtils::PexprLogicalJoin<CLogicalInnerJoin>(pmp, pexprOuter, pexprLimit, pexprNegatedScalar);
	CExpression *pexprNormalized = CNormalizer::PexprNormalize(pmp, pexprJoin);
	pexprJoin->Release();

	pxfres->Add(pexprNormalized);
}
Exemplo n.º 27
0
//---------------------------------------------------------------------------
//	@function:
//		CPartitionPropagationSpec::PexprResidualFilter
//
//	@doc:
//		Return a residual filter given an array of predicates and a bitset
//		indicating which predicates have already been used
//
//---------------------------------------------------------------------------
CExpression *
CPartitionPropagationSpec::PexprResidualFilter
	(
	IMemoryPool *mp,
	CExpressionArray *pdrgpexpr,
	CBitSet *pbsUsed
	)
{
	GPOS_ASSERT(NULL != pdrgpexpr);
	GPOS_ASSERT(NULL != pbsUsed);

	CExpressionArray *pdrgpexprUnused = GPOS_NEW(mp) CExpressionArray(mp);

	const ULONG length = pdrgpexpr->Size();
	for (ULONG ul = 0; ul < length; ul++)
	{
		if (pbsUsed->Get(ul))
		{
			// predicate already considered
			continue;
		}

		CExpression *pexpr = (*pdrgpexpr)[ul];
		pexpr->AddRef();
		pdrgpexprUnused->Append(pexpr);
	}

	CExpression *pexprResult = CPredicateUtils::PexprConjunction(mp, pdrgpexprUnused);
	if (CUtils::FScalarConstTrue(pexprResult))
	{
		pexprResult->Release();
		pexprResult = NULL;
	}

	return pexprResult;
}
Exemplo n.º 28
0
float CParser::GetFloat(STR_String& txt)
{
	// returns parsed text into a float
	// empty string returns -1

//	AfxMessageBox("parsed string="+txt);
	CValue* val=NULL;
	float result=-1;
//	String tmpstr;

	CExpression* expr = ProcessText(txt);
	if (expr) {
		val = expr->Calculate();
		result=(float)val->GetNumber();



		val->Release();
		expr->Release();
	}
//	tmpstr.Format("parseresult=%g",result);
//		AfxMessageBox(tmpstr);
	return result;
}
Exemplo n.º 29
0
//---------------------------------------------------------------------------
//	@function:
//		CConstraint::PdrgpcnstrDeduplicate
//
//	@doc:
//		Simplify an array of constraints to be used as children for a conjunction
//		or disjunction. If there are two or more elements that reference only one
//		particular column, these constraints are combined into one
//
//---------------------------------------------------------------------------
DrgPcnstr *
CConstraint::PdrgpcnstrDeduplicate
(
    IMemoryPool *pmp,
    DrgPcnstr *pdrgpcnstr,
    EConstraintType ect
)
const
{
    DrgPcnstr *pdrgpcnstrNew = GPOS_NEW(pmp) DrgPcnstr(pmp);

    CColRefSet *pcrsDeduped = GPOS_NEW(pmp) CColRefSet(pmp);

    const ULONG ulLen = pdrgpcnstr->UlLength();
    for (ULONG ul = 0; ul < ulLen; ul++)
    {
        CConstraint *pcnstrChild = (*pdrgpcnstr)[ul];
        CColRefSet *pcrs = pcnstrChild->PcrsUsed();

        // we only simplify constraints that reference a single column, otherwise
        // we add constraint as is
        if (1 < pcrs->CElements())
        {
            pcnstrChild->AddRef();
            pdrgpcnstrNew->Append(pcnstrChild);
            continue;
        }

        CColRef *pcr = pcrs->PcrFirst();
        if (pcrsDeduped->FMember(pcr))
        {
            // current constraint has already been combined with a previous one
            continue;
        }

        // get all constraints from the input array that reference this column
        DrgPcnstr *pdrgpcnstrCol = PdrgpcnstrOnColumn(pmp, pdrgpcnstr, pcr, true /*fExclusive*/);
        if (1 == pdrgpcnstrCol->UlLength())
        {
            // if there is only one such constraint, then no simplification
            // for this column
            pdrgpcnstrCol->Release();
            pcnstrChild->AddRef();
            pdrgpcnstrNew->Append(pcnstrChild);
            continue;
        }

        CExpression *pexpr = NULL;

        if (EctConjunction == ect)
        {
            pexpr = PexprScalarConjDisj(pmp, pdrgpcnstrCol, true /*fConj*/);
        }
        else
        {
            GPOS_ASSERT(EctDisjunction == ect);
            pexpr = PexprScalarConjDisj(pmp, pdrgpcnstrCol, false /*fConj*/);
        }
        pdrgpcnstrCol->Release();
        GPOS_ASSERT(NULL != pexpr);

        CConstraint *pcnstrNew = CConstraintInterval::PciIntervalFromScalarExpr(pmp, pexpr, pcr);
        GPOS_ASSERT(NULL != pcnstrNew);
        pexpr->Release();
        pdrgpcnstrNew->Append(pcnstrNew);
        pcrsDeduped->Include(pcr);
    }

    pcrsDeduped->Release();
    pdrgpcnstr->Release();
    return pdrgpcnstrNew;
}
Exemplo n.º 30
0
//---------------------------------------------------------------------------
//	@function:
//		COptimizer::PdxlnOptimize
//
//	@doc:
//		Optimize given query
//		the function is oblivious of trace flags setting/resetting which
//		must happen at the caller side if needed
//
//---------------------------------------------------------------------------
CDXLNode *
COptimizer::PdxlnOptimize
	(
	IMemoryPool *pmp, 
	CMDAccessor *pmda,
	const CDXLNode *pdxlnQuery,
	const DrgPdxln *pdrgpdxlnQueryOutput, 
	const DrgPdxln *pdrgpdxlnCTE, 
	IConstExprEvaluator *pceeval,
	ULONG ulHosts,	// actual number of data nodes in the system
	ULONG ulSessionId,
	ULONG ulCmdId,
	DrgPss *pdrgpss,
	COptimizerConfig *poconf,
	const CHAR *szMinidumpFileName 	// name of minidump file to be created
	)
{
	GPOS_ASSERT(NULL != pmda);
	GPOS_ASSERT(NULL != pdxlnQuery);
	GPOS_ASSERT(NULL != pdrgpdxlnQueryOutput);
	GPOS_ASSERT(NULL != poconf);

	BOOL fMinidump = GPOS_FTRACE(EopttraceMinidump);

	CMiniDumperDXL mdmp(pmp);
	if (fMinidump)
	{
		mdmp.Init();
	}

	CDXLNode *pdxlnPlan = NULL;
	CErrorHandlerStandard errhdl;
	GPOS_TRY_HDL(&errhdl)
	{
		CSerializableStackTrace serStack;
		CSerializableOptimizerConfig serOptConfig(poconf);
		CSerializableMDAccessor serMDA(pmda);
		CSerializableQuery serQuery(pdxlnQuery, pdrgpdxlnQueryOutput, pdrgpdxlnCTE);
		
		if (fMinidump)
		{
			// pre-serialize query and optimizer configurations
			serStack.AllocateBuffer(pmp);
			serOptConfig.Serialize(pmp);
			serQuery.Serialize(pmp);
		}

		{			
			poconf->AddRef();
			if (NULL != pceeval)
			{
				pceeval->AddRef();
			}

			// install opt context in TLS
			CAutoOptCtxt aoc(pmp, pmda, pceeval, poconf);

			// translate DXL Tree -> Expr Tree
			CTranslatorDXLToExpr dxltr(pmp, pmda);
			CExpression *pexprTranslated =	dxltr.PexprTranslateQuery(pdxlnQuery, pdrgpdxlnQueryOutput, pdrgpdxlnCTE);
			GPOS_CHECK_ABORT;
			gpdxl::DrgPul *pdrgpul = dxltr.PdrgpulOutputColRefs();
			gpmd::DrgPmdname *pdrgpmdname = dxltr.Pdrgpmdname();

			CQueryContext *pqc = CQueryContext::PqcGenerate(pmp, pexprTranslated, pdrgpul, pdrgpmdname, true /*fDeriveStats*/);
			GPOS_CHECK_ABORT;

			PrintQueryOrPlan(pmp, pexprTranslated, pqc);

			CWStringDynamic strTrace(pmp);
			COstreamString oss(&strTrace);

			// if the number of inlinable CTEs is greater than the cutoff, then
			// disable inlining for this query
			if (!GPOS_FTRACE(EopttraceEnableCTEInlining) ||
				CUtils::UlInlinableCTEs(pexprTranslated) > poconf->Pcteconf()->UlCTEInliningCutoff())
			{
				COptCtxt::PoctxtFromTLS()->Pcteinfo()->DisableInlining();
			}

			GPOS_CHECK_ABORT;
			// optimize logical expression tree into physical expression tree.
			CExpression *pexprPlan = PexprOptimize(pmp, pqc, pdrgpss);
			GPOS_CHECK_ABORT;

			PrintQueryOrPlan(pmp, pexprPlan);

			// translate plan into DXL
			pdxlnPlan = Pdxln(pmp, pmda, pexprPlan, pqc->PdrgPcr(), pdrgpmdname, ulHosts);
			GPOS_CHECK_ABORT;

			if (fMinidump)
			{
				CSerializablePlan serPlan(pdxlnPlan, poconf->Pec()->UllPlanId(), poconf->Pec()->UllPlanSpaceSize());
				serPlan.Serialize(pmp);
				CMinidumperUtils::Finalize(&mdmp, true /* fSerializeErrCtxt*/, ulSessionId, ulCmdId, szMinidumpFileName);
				GPOS_CHECK_ABORT;
			}
			
			if (GPOS_FTRACE(EopttraceSamplePlans))
			{
				DumpSamples(pmp, poconf->Pec(), ulSessionId, ulCmdId);
				GPOS_CHECK_ABORT;
			}

			// cleanup
			pexprTranslated->Release();
			pexprPlan->Release();
			GPOS_DELETE(pqc);
		}
	}
	GPOS_CATCH_EX(ex)
	{
		if (fMinidump)
		{
			CMinidumperUtils::Finalize(&mdmp, false /* fSerializeErrCtxt*/, ulSessionId, ulCmdId, szMinidumpFileName);
			HandleExceptionAfterFinalizingMinidump(ex);
		}

		GPOS_RETHROW(ex);
	}
	GPOS_CATCH_END;

	return pdxlnPlan;
}