//---------------------------------------------------------------------------
//	@function:
//		CColRefSetIterTest::EresUnittest_Basics
//
//	@doc:
//		Testing ctors/dtor; and pcr decoding;
//		Other functionality already tested in vanilla CBitSetIter;
//
//---------------------------------------------------------------------------
GPOS_RESULT
CColRefSetIterTest::EresUnittest_Basics()
{
	CAutoMemoryPool amp;
	IMemoryPool *pmp = amp.Pmp();

	// Setup an MD cache with a file-based provider
	CMDProviderMemory *pmdp = CTestUtils::m_pmdpf;
	pmdp->AddRef();
	CMDAccessor mda(pmp, CMDCache::Pcache());
	mda.RegisterProvider(CTestUtils::m_sysidDefault, pmdp);

	// install opt context in TLS
	CAutoOptCtxt aoc
				(
				pmp,
				&mda,
				NULL /* pceeval */,
				CTestUtils::Pcm(pmp)
				);

	// get column factory from optimizer context object
	CColumnFactory *pcf = COptCtxt::PoctxtFromTLS()->Pcf();

	CColRefSet *pcrs = GPOS_NEW(pmp) CColRefSet(pmp);
	CWStringConst strName(GPOS_WSZ_LIT("Test Column"));
	CName name(&strName);

	// create a int4 datum
	const IMDTypeInt4 *pmdtypeint4 = mda.PtMDType<IMDTypeInt4>();


	ULONG ulCols = 10;
	for(ULONG i = 0; i < ulCols; i++)
	{
		CColRef *pcr = pcf->PcrCreate(pmdtypeint4, name);
		pcrs->Include(pcr);

		GPOS_ASSERT(pcrs->FMember(pcr));
	}

	GPOS_ASSERT(pcrs->CElements() == ulCols);

	ULONG ulCount = 0;
	CColRefSetIter crsi(*pcrs);
	while(crsi.FAdvance())
	{
		GPOS_ASSERT((BOOL)crsi);

		CColRef *pcr = crsi.Pcr();
		GPOS_ASSERT(pcr->Name().FEquals(name));

		// to avoid unused variable warnings
		(void) pcr->UlId();

		ulCount++;
	}

	GPOS_ASSERT(ulCols == ulCount);
	GPOS_ASSERT(!((BOOL)crsi));

	pcrs->Release();

	return GPOS_OK;
}
//---------------------------------------------------------------------------
//	@function:
//		CContradictionTest::EresUnittest_Constraint
//
//	@doc:
//		Tests for constraint property derivation and constraint push down
//
//---------------------------------------------------------------------------
GPOS_RESULT
CContradictionTest::EresUnittest_Constraint()
{
	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::PexprLogicalApplyWithOuterRef<CLogicalInnerApply>,
		CTestUtils::PexprLogicalApply<CLogicalLeftSemiApply>,
		CTestUtils::PexprLogicalApply<CLogicalLeftAntiSemiApply>,
		CTestUtils::PexprLogicalApplyWithOuterRef<CLogicalLeftOuterApply>,
		CTestUtils::PexprLogicalGet,
		CTestUtils::PexprLogicalGetPartitioned,
		CTestUtils::PexprLogicalSelect,
		CTestUtils::PexprLogicalSelectCmpToConst,
		CTestUtils::PexprLogicalSelectPartitioned,
		CTestUtils::PexprLogicalSelectWithContradiction,
		CTestUtils::PexprLogicalJoin<CLogicalInnerJoin>,
		CTestUtils::PexprLogicalJoin<CLogicalLeftOuterJoin>,
		CTestUtils::PexprLogicalJoin<CLogicalLeftSemiJoin>,
		CTestUtils::PexprLogicalJoin<CLogicalLeftAntiSemiJoin>,
		CTestUtils::PexprLogicalGbAgg,
		CTestUtils::PexprLogicalGbAggOverJoin,
		CTestUtils::PexprLogicalGbAggWithSum,
		CTestUtils::PexprLogicalLimit,
		CTestUtils::PexprLogicalNAryJoin,
		CTestUtils::PexprLogicalProject,
		CTestUtils::PexprConstTableGet5,
		CTestUtils::PexprLogicalDynamicGet,
		CTestUtils::PexprLogicalSequence,
		CTestUtils::PexprLogicalTVFTwoArgs,
		};

	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 simple expression
		CExpression *pexpr = rgpf[i](pmp);

		// self-match
		GPOS_ASSERT(pexpr->FMatchDebug(pexpr));

		// debug print
		CWStringDynamic str(pmp, GPOS_WSZ_LIT("\n"));
		COstreamString oss(&str);

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


#ifdef GPOS_DEBUG
		// derive properties on expression
		(void) pexpr->PdpDerive();

		oss << std::endl << "DERIVED PROPS:" << std::endl;
		GPOS_TRACE(str.Wsz());
		str.Reset();
		pexpr->DbgPrint();
#endif // GPOS_DEBUG

 		CExpression *pexprPreprocessed = CExpressionPreprocessor::PexprPreprocess(pmp, pexpr);
		oss	<< std::endl << "PREPROCESSED EXPR:" << std::endl << *pexprPreprocessed << std::endl;
		GPOS_TRACE(str.Wsz());
		str.Reset();

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

	return GPOS_OK;
}
Example #3
0
//---------------------------------------------------------------------------
//	@function:
//		CCNFConverterTest::EresUnittest_AvoidCNFConversion
//
//	@doc:
//		Unit test to check whether CNF conversion is done only when necessary
//
//---------------------------------------------------------------------------
GPOS_RESULT
CCNFConverterTest::EresUnittest_AvoidCNFConversion()
{
	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);

	SCNConverterSTestCase rgpf[] =
	{
		{PexprScIdentCmpConst, NULL, false},
		{PexprOr, NULL, false},
		{PexprAnd1, NULL, false},
		{PexprAnd2, NULL, true},
		{PexprAnd3, NULL, false},
		{PexprAnd4, NULL, true},
		{PexprAnd5, NULL, false},
		{PexprAnd6, NULL, true},

		{PexprAnd1, PexprAnd1, false},
		{PexprAnd1, PexprAnd2, false},
		{PexprAnd1, PexprAnd3, false},
		{PexprAnd1, PexprAnd4, false},
		{PexprAnd1, PexprAnd5, false},
		{PexprAnd1, PexprAnd6, false},


		{PexprAnd2, PexprAnd1, false},
		{PexprAnd2, PexprAnd2, true},
		{PexprAnd2, PexprAnd3, false},
		{PexprAnd2, PexprAnd4, true},
		{PexprAnd2, PexprAnd5, false},
		{PexprAnd2, PexprAnd6, true},

		{PexprAnd3, PexprAnd1, false},
		{PexprAnd3, PexprAnd2, false},
		{PexprAnd3, PexprAnd3, false},
		{PexprAnd3, PexprAnd4, false},
		{PexprAnd3, PexprAnd5, false},
		{PexprAnd3, PexprAnd6, false},

		{PexprAnd4, PexprAnd1, false},
		{PexprAnd4, PexprAnd2, true},
		{PexprAnd4, PexprAnd3, false},
		{PexprAnd4, PexprAnd4, true},
		{PexprAnd4, PexprAnd5, false},
		{PexprAnd4, PexprAnd6, true},

		{PexprAnd5, PexprAnd1, false},
		{PexprAnd5, PexprAnd2, false},
		{PexprAnd5, PexprAnd3, false},
		{PexprAnd5, PexprAnd4, false},
		{PexprAnd5, PexprAnd5, false},
		{PexprAnd5, PexprAnd6, false},


		{PexprAnd6, PexprAnd1, false},
		{PexprAnd6, PexprAnd2, true},
		{PexprAnd6, PexprAnd3, false},
		{PexprAnd6, PexprAnd4, true},
		{PexprAnd6, PexprAnd5, false},
		{PexprAnd6, PexprAnd6, true},

		{PexprAnd7, PexprAnd7, true},

	};

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

		SCNConverterSTestCase elem = rgpf[ul];
		PexprTestCase *pfFst = elem.m_pfFst;
		PexprTestCase *pfSnd = elem.m_pfSnd;

		CExpression *pexprLeft = CTestUtils::PexprLogicalGet(pmp);
		CExpression *pexprRight = CTestUtils::PexprLogicalGet(pmp);

		pexprLeft->PdpDerive();
		pexprRight->PdpDerive();

		GPOS_ASSERT(NULL != pfFst);
		CExpression *pexprScalar = NULL;
		if (NULL != pfSnd)
		{
			pexprScalar = CTestUtils::PexprOr(pmp, pfFst(pmp, pexprLeft, pexprRight), pfSnd(pmp, pexprLeft, pexprRight));
		}
		else
		{
			pexprScalar = pfFst(pmp, pexprLeft, pexprRight);
		}

		CExpression *pexprCNF = CXformUtils::Pexpr2CNFWhenBeneficial(pmp, pexprLeft, pexprRight, pexprScalar);

		{
			CAutoTrace at(pmp);
			at.Os() <<  std::endl << "SCALAR EXPR:" <<  std::endl <<  *pexprScalar << std::endl;
			at.Os() <<  std::endl << "CNF EXPR:" << std::endl << *pexprCNF << std::endl;
		}

		eres = GPOS_OK;
		if (elem.m_fCNFConversion && pexprScalar == pexprCNF)
		{
			eres = GPOS_FAILED;
		}

		if (!elem.m_fCNFConversion && pexprScalar != pexprCNF)
		{
			eres = GPOS_FAILED;
		}

		// clean up
		pexprLeft->Release();
		pexprRight->Release();
		pexprScalar->Release();
		pexprCNF->Release();
	}

	return eres;
}
Example #4
0
//---------------------------------------------------------------------------
//	@function:
//		CParseHandlerTest::EresParseAndSerializeStatistics
//
//	@doc:
//		Verifies that after parsing the given DXL file containing statistics
//		into a list of statistics objects, which should be serialized back
//		to the same string.
//
//---------------------------------------------------------------------------
GPOS_RESULT
CParseHandlerTest::EresParseAndSerializeStatistics
	(
	IMemoryPool *pmp,
	const CHAR *szDXLFileName,
	BOOL fValidate
	)
{
	// setup a file-based provider
	CMDProviderMemory *pmdp = CTestUtils::m_pmdpf;
	pmdp->AddRef();
	CMDAccessor mda(pmp, CMDCache::Pcache(), CTestUtils::m_sysidDefault, pmdp);

	// install opt context in TLS
	CAutoOptCtxt aoc
					(
					pmp,
					&mda,
					NULL /* pceeval */,
					CTestUtils::Pcm(pmp)
					);

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

	// read DXL file
	CHAR *szDXL = CDXLUtils::SzRead(pmp, szDXLFileName);

	GPOS_CHECK_ABORT;

	// parse the metadata objects into a dynamic array
	const CHAR *szValidationPath = NULL;
	if (fValidate)
	{
	   szValidationPath = CTestUtils::m_szXSDPath;
	}

	// parse the statistics objects
	DrgPdxlstatsderrel *pdrgpdxlstatsderrel = CDXLUtils::PdrgpdxlstatsderrelParseDXL(pmp, szDXL, szValidationPath);
	DrgPstats *pdrgpstat = CDXLUtils::PdrgpstatsTranslateStats
								(
								pmp,
								&mda,
								pdrgpdxlstatsderrel
								);

	pdrgpdxlstatsderrel->Release();


	GPOS_ASSERT(NULL != pdrgpstat);

	CStatistics *pstats = (* pdrgpstat)[0];
	GPOS_ASSERT(pstats);

	pstats->DRows();
	oss << "Statistics:" << std::endl;
	CStatisticsTest::Print(pmp, pstats);

	GPOS_CHECK_ABORT;

	oss << "Serializing Statistics Objects" << std::endl;
	CWStringDynamic *pstr = CDXLUtils::PstrSerializeStatistics
											(
											pmp,
											&mda,
											pdrgpstat,
											true /*fSerializeHeaderFooter*/,
											true /*fIndent*/
											);

	CWStringDynamic dstrExpected(pmp);
	dstrExpected.AppendFormat(GPOS_WSZ_LIT("%s"), szDXL);

	GPOS_ASSERT(dstrExpected.FEquals(pstr));

	pdrgpstat->Release();

	GPOS_DELETE_ARRAY(szDXL);
	GPOS_DELETE(pstr);
	return GPOS_OK;
}
//---------------------------------------------------------------------------
//	@function:
//		CPredicateUtilsTest::EresUnittest_Implication
//
//	@doc:
//		Test removal of implied predicates
//
//---------------------------------------------------------------------------
GPOS_RESULT
CPredicateUtilsTest::EresUnittest_Implication()
{
	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);

	// install opt context in TLS
	CAutoOptCtxt aoc
					(
					pmp,
					&mda,
					NULL,  /* pceeval */
					CTestUtils::Pcm(pmp)
					);

	// generate a two cascaded joins
	CWStringConst strName1(GPOS_WSZ_LIT("Rel1"));
	CMDIdGPDB *pmdid1 = GPOS_NEW(pmp) CMDIdGPDB(GPOPT_TEST_REL_OID1, 1, 1);
	CTableDescriptor *ptabdesc1 = CTestUtils::PtabdescCreate(pmp, 3, pmdid1, CName(&strName1));
	CWStringConst strAlias1(GPOS_WSZ_LIT("Rel1"));
	CExpression *pexprRel1 = CTestUtils::PexprLogicalGet(pmp, ptabdesc1, &strAlias1);

	CWStringConst strName2(GPOS_WSZ_LIT("Rel2"));
	CMDIdGPDB *pmdid2 = GPOS_NEW(pmp) CMDIdGPDB(GPOPT_TEST_REL_OID2, 1, 1);
	CTableDescriptor *ptabdesc2 = CTestUtils::PtabdescCreate(pmp, 3, pmdid2, CName(&strName2));
	CWStringConst strAlias2(GPOS_WSZ_LIT("Rel2"));
	CExpression *pexprRel2 = CTestUtils::PexprLogicalGet(pmp, ptabdesc2, &strAlias2);

	CWStringConst strName3(GPOS_WSZ_LIT("Rel3"));
	CMDIdGPDB *pmdid3 = GPOS_NEW(pmp) CMDIdGPDB(GPOPT_TEST_REL_OID3, 1, 1);
	CTableDescriptor *ptabdesc3 = CTestUtils::PtabdescCreate(pmp, 3, pmdid3, CName(&strName3));
	CWStringConst strAlias3(GPOS_WSZ_LIT("Rel3"));
	CExpression *pexprRel3 = CTestUtils::PexprLogicalGet(pmp, ptabdesc3, &strAlias3);

	CExpression *pexprJoin1 = CTestUtils::PexprLogicalJoin<CLogicalInnerJoin>(pmp, pexprRel1, pexprRel2);
	CExpression *pexprJoin2 = CTestUtils::PexprLogicalJoin<CLogicalInnerJoin>(pmp, pexprJoin1, pexprRel3);

	{
		CAutoTrace at(pmp);
		at.Os() << "Original expression:" << std::endl << *pexprJoin2 <<std::endl;
	}

	// imply new predicates by deriving constraints
	CExpression *pexprConstraints = CExpressionPreprocessor::PexprAddPredicatesFromConstraints(pmp, pexprJoin2);

	{
		CAutoTrace at(pmp);
		at.Os() << "Expression with implied predicates:" << std::endl << *pexprConstraints <<std::endl;;
	}

	// minimize join predicates by removing implied conjuncts
	CExpressionHandle exprhdl(pmp);
	exprhdl.Attach(pexprConstraints);
	CExpression *pexprMinimizedPred = CPredicateUtils::PexprRemoveImpliedConjuncts(pmp, (*pexprConstraints)[2], exprhdl);

	{
		CAutoTrace at(pmp);
		at.Os() << "Minimized join predicate:" << std::endl << *pexprMinimizedPred <<std::endl;
	}

	DrgPexpr *pdrgpexprOriginalConjuncts = CPredicateUtils::PdrgpexprConjuncts(pmp,  (*pexprConstraints)[2]);
	DrgPexpr *pdrgpexprNewConjuncts = CPredicateUtils::PdrgpexprConjuncts(pmp, pexprMinimizedPred);

	GPOS_ASSERT(pdrgpexprNewConjuncts->UlLength() < pdrgpexprOriginalConjuncts->UlLength());

	// clean up
	pdrgpexprOriginalConjuncts->Release();
	pdrgpexprNewConjuncts->Release();
	pexprJoin2->Release();
	pexprConstraints->Release();
	pexprMinimizedPred->Release();

	return GPOS_OK;
}
//---------------------------------------------------------------------------
//	@function:
//		CPredicateUtilsTest::EresUnittest_Conjunctions
//
//	@doc:
//		Test extraction and construction of conjuncts
//
//---------------------------------------------------------------------------
GPOS_RESULT
CPredicateUtilsTest::EresUnittest_Conjunctions()
{
	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);

	// install opt context in TLS
	CAutoOptCtxt aoc
					(
					pmp,
					&mda,
					NULL,  /* pceeval */
					CTestUtils::Pcm(pmp)
					);

	// build conjunction
	DrgPexpr *pdrgpexpr = GPOS_NEW(pmp) DrgPexpr(pmp);
	const ULONG ulConjs = 3;
	for (ULONG ul = 0; ul < ulConjs; ul++)
	{
		pdrgpexpr->Append(CUtils::PexprScalarConstBool(pmp, true /*fValue*/));
	}
	CExpression *pexprConjunction = CUtils::PexprScalarBoolOp(pmp, CScalarBoolOp::EboolopAnd, pdrgpexpr);
	
	// break into conjuncts
	DrgPexpr *pdrgpexprExtract = CPredicateUtils::PdrgpexprConjuncts(pmp, pexprConjunction);
	GPOS_ASSERT(pdrgpexprExtract->UlLength() == ulConjs);
	
	// collapse into single conjunct
	CExpression *pexpr = CPredicateUtils::PexprConjunction(pmp, pdrgpexprExtract);
	GPOS_ASSERT(NULL != pexpr);
	GPOS_ASSERT(CUtils::FScalarConstTrue(pexpr));
	pexpr->Release();
	
	// collapse empty input array to conjunct
	CExpression *pexprSingleton = CPredicateUtils::PexprConjunction(pmp, NULL /*pdrgpexpr*/);
	GPOS_ASSERT(NULL != pexprSingleton);
	pexprSingleton->Release();

	pexprConjunction->Release();

	// conjunction on scalar comparisons
	CExpression *pexprGet = CTestUtils::PexprLogicalGet(pmp);
	CColRefSet *pcrs = CDrvdPropRelational::Pdprel(pexprGet->PdpDerive())->PcrsOutput();
	CColRef *pcr1 = pcrs->PcrAny();
	CColRef *pcr2 = pcrs->PcrFirst();
	CExpression *pexprCmp1 = CUtils::PexprScalarCmp(pmp, pcr1, pcr2, IMDType::EcmptEq);
	CExpression *pexprCmp2 = CUtils::PexprScalarCmp(pmp, pcr1, CUtils::PexprScalarConstInt4(pmp, 1 /*iVal*/), IMDType::EcmptEq);

	CExpression *pexprConj = CPredicateUtils::PexprConjunction(pmp, pexprCmp1, pexprCmp2);
	pdrgpexprExtract = CPredicateUtils::PdrgpexprConjuncts(pmp, pexprConj);
	GPOS_ASSERT(2 == pdrgpexprExtract->UlLength());
	pdrgpexprExtract->Release();

	pexprCmp1->Release();
	pexprCmp2->Release();
	pexprConj->Release();
	pexprGet->Release();

	return GPOS_OK;
}
//---------------------------------------------------------------------------
//	@function:
//		CPredicateUtilsTest::EresUnittest_PlainEqualities
//
//	@doc:
//		Test the extraction of equality predicates between scalar identifiers
//
//---------------------------------------------------------------------------
GPOS_RESULT
CPredicateUtilsTest::EresUnittest_PlainEqualities()
{
	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);

	// install opt context in TLS
	CAutoOptCtxt aoc
					(
					pmp,
					&mda,
					NULL,  /* pceeval */
					CTestUtils::Pcm(pmp)
					);

	CExpression *pexprLeft = CTestUtils::PexprLogicalGet(pmp);
	CExpression *pexprRight = CTestUtils::PexprLogicalGet(pmp);

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

	CColRefSet *pcrsLeft = CDrvdPropRelational::Pdprel(pexprLeft->PdpDerive())->PcrsOutput();
	CColRefSet *pcrsRight = CDrvdPropRelational::Pdprel(pexprRight->PdpDerive())->PcrsOutput();

	CColRef *pcrLeft = pcrsLeft->PcrAny();
	CColRef *pcrRight = pcrsRight->PcrAny();

	// generate an equality predicate between two column reference
	CExpression *pexprScIdentEquality =
		CUtils::PexprScalarEqCmp(pmp, pcrLeft, pcrRight);

	pexprScIdentEquality->AddRef();
	pdrgpexprOriginal->Append(pexprScIdentEquality);

	// generate a non-equality predicate between two column reference
	CExpression *pexprScIdentInequality =
		CUtils::PexprScalarCmp(pmp, pcrLeft, pcrRight, CWStringConst(GPOS_WSZ_LIT("<")), GPOS_NEW(pmp) CMDIdGPDB(GPDB_INT4_LT_OP));

	pexprScIdentInequality->AddRef();
	pdrgpexprOriginal->Append(pexprScIdentInequality);

	// generate an equality predicate between a column reference and a constant value
	CExpression *pexprScalarConstInt4 = CUtils::PexprScalarConstInt4(pmp, 10 /*fValue*/);
	CExpression *pexprScIdentConstEquality = CUtils::PexprScalarEqCmp(pmp, pexprScalarConstInt4, pcrRight);

	pdrgpexprOriginal->Append(pexprScIdentConstEquality);

	GPOS_ASSERT(3 == pdrgpexprOriginal->UlLength());

	DrgPexpr *pdrgpexprResult = CPredicateUtils::PdrgpexprPlainEqualities(pmp, pdrgpexprOriginal);

	GPOS_ASSERT(1 == pdrgpexprResult->UlLength());

	// clean up
	pdrgpexprOriginal->Release();
	pdrgpexprResult->Release();
	pexprLeft->Release();
	pexprRight->Release();
	pexprScIdentEquality->Release();
	pexprScIdentInequality->Release();

	return GPOS_OK;
}
//---------------------------------------------------------------------------
//	@function:
//		CPredicateUtilsTest::EresUnittest_Disjunctions
//
//	@doc:
//		Test extraction and construction of disjuncts
//
//---------------------------------------------------------------------------
GPOS_RESULT
CPredicateUtilsTest::EresUnittest_Disjunctions()
{
	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);

	// install opt context in TLS
	CAutoOptCtxt aoc
					(
					pmp,
					&mda,
					NULL,  /* pceeval */
					CTestUtils::Pcm(pmp)
					);

	// build disjunction
	DrgPexpr *pdrgpexpr = GPOS_NEW(pmp) DrgPexpr(pmp);
	const ULONG ulDisjs = 3;
	for (ULONG ul = 0; ul < ulDisjs; ul++)
	{
		pdrgpexpr->Append(CUtils::PexprScalarConstBool(pmp, false /*fValue*/));
	}
	CExpression *pexprDisjunction = CUtils::PexprScalarBoolOp(pmp, CScalarBoolOp::EboolopOr, pdrgpexpr);

	// break into disjuncts
	DrgPexpr *pdrgpexprExtract = CPredicateUtils::PdrgpexprDisjuncts(pmp, pexprDisjunction);
	GPOS_ASSERT(pdrgpexprExtract->UlLength() == ulDisjs);

	// collapse into single disjunct
	CExpression *pexpr = CPredicateUtils::PexprDisjunction(pmp, pdrgpexprExtract);
	GPOS_ASSERT(NULL != pexpr);
	GPOS_ASSERT(CUtils::FScalarConstFalse(pexpr));
	pexpr->Release();

	// collapse empty input array to disjunct
	CExpression *pexprSingleton = CPredicateUtils::PexprDisjunction(pmp, NULL /*pdrgpexpr*/);
	GPOS_ASSERT(NULL != pexprSingleton);
	pexprSingleton->Release();

	pexprDisjunction->Release();

	// disjunction on scalar comparisons
	CExpression *pexprGet = CTestUtils::PexprLogicalGet(pmp);
	CColRefSet *pcrs = CDrvdPropRelational::Pdprel(pexprGet->PdpDerive())->PcrsOutput();
	CColRefSetIter crsi(*pcrs);

#ifdef GPOS_DEBUG
	BOOL fAdvance =
#endif
	crsi.FAdvance();
	GPOS_ASSERT(fAdvance);
	CColRef *pcr1 = crsi.Pcr();

#ifdef GPOS_DEBUG
	fAdvance =
#endif
	crsi.FAdvance();
	GPOS_ASSERT(fAdvance);
	CColRef *pcr2 = crsi.Pcr();

#ifdef GPOS_DEBUG
	fAdvance =
#endif
	crsi.FAdvance();
	GPOS_ASSERT(fAdvance);
	CColRef *pcr3 = crsi.Pcr();

	CExpression *pexprCmp1 = CUtils::PexprScalarCmp(pmp, pcr1, pcr2, IMDType::EcmptEq);
	CExpression *pexprCmp2 = CUtils::PexprScalarCmp(pmp, pcr1, CUtils::PexprScalarConstInt4(pmp, 1 /*iVal*/), IMDType::EcmptEq);

	{
		CExpression *pexprDisj = CPredicateUtils::PexprDisjunction(pmp, pexprCmp1, pexprCmp2);
		pdrgpexprExtract = CPredicateUtils::PdrgpexprDisjuncts(pmp, pexprDisj);
		GPOS_ASSERT(2 == pdrgpexprExtract->UlLength());
		pdrgpexprExtract->Release();
		pexprDisj->Release();
	}


	{
		DrgPexpr *pdrgpexpr = GPOS_NEW(pmp) DrgPexpr(pmp);
		CExpression *pexprCmp3 = CUtils::PexprScalarCmp(pmp, pcr2, pcr1, IMDType::EcmptG);
		CExpression *pexprCmp4 = CUtils::PexprScalarCmp(pmp, CUtils::PexprScalarConstInt4(pmp, 200 /*iVal*/), pcr3, IMDType::EcmptL);
		pexprCmp1->AddRef();
		pexprCmp2->AddRef();

		pdrgpexpr->Append(pexprCmp3);
		pdrgpexpr->Append(pexprCmp4);
		pdrgpexpr->Append(pexprCmp1);
		pdrgpexpr->Append(pexprCmp2);

		CExpression *pexprDisj = CPredicateUtils::PexprDisjunction(pmp, pdrgpexpr);
		pdrgpexprExtract = CPredicateUtils::PdrgpexprDisjuncts(pmp, pexprDisj);
		GPOS_ASSERT(4 == pdrgpexprExtract->UlLength());
		pdrgpexprExtract->Release();
		pexprDisj->Release();
	}

	pexprCmp1->Release();
	pexprCmp2->Release();
	pexprGet->Release();

	return GPOS_OK;
}
Example #9
0
//---------------------------------------------------------------------------
//	@function:
//		CTreeMapTest::EresUnittest_Memo
//
//	@doc:
//		Test loading map from actual memo
//
//---------------------------------------------------------------------------
GPOS_RESULT
CTreeMapTest::EresUnittest_Memo()
{
	GPOS_SET_TRACE(EtraceDisablePrintMemoryLeak);

	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);

	CEngine *peng = NULL;
	CExpression *pexpr = NULL;
	CQueryContext *pqc = NULL;
	CExpression *pexprPlan = NULL;
	{
		// install opt context in TLS
		CAutoOptCtxt aoc
				(
				pmp,
				&mda,
				NULL,  /* pceeval */
				CTestUtils::Pcm(pmp)
				);

		CAutoTraceFlag atf(EopttraceEnumeratePlans, true);

		peng = GPOS_NEW(pmp) CEngine(pmp);

		// generate join expression
		pexpr = CTestUtils::PexprLogicalJoin<CLogicalInnerJoin>(pmp);

		// generate query context
		pqc = CTestUtils::PqcGenerate(pmp, pexpr);

		// Initialize engine
		peng->Init(pqc, NULL /*pdrgpss*/);

		// optimize query
		peng->Optimize();

		// extract plan
		pexprPlan = peng->PexprExtractPlan();
		GPOS_ASSERT(NULL != pexprPlan);

		peng->Trace();
		{
			CAutoTrace at(pmp);
			ULLONG ullCount = peng->Pmemotmap()->UllCount();
#ifdef GPOS_DEBUG
			// test resetting map and re-creating it
			peng->ResetTreeMap();
			ULLONG ullCount2 = peng->Pmemotmap()->UllCount();
			GPOS_ASSERT(ullCount == ullCount2);
#endif // GPOS_DEBUG

			for (ULONG ulRank = 0; ulRank < ullCount; ulRank++)
			{
				CDrvdPropCtxtPlan *pdpctxtplan = GPOS_NEW(pmp) CDrvdPropCtxtPlan(pmp, false /*fUpdateCTEMap*/);
				CExpression *pexprAlt = NULL;
				GPOS_TRY
				{
					pexprAlt = peng->Pmemotmap()->PrUnrank(pmp, pdpctxtplan, ulRank);
					at.Os() << std::endl << "ALTERNATIVE ["<< ulRank <<"]:" << std::endl << *pexprAlt << std::endl;
				}
				GPOS_CATCH_EX(ex)
				{
					if (!GPOS_MATCH_EX(ex, gpopt::ExmaGPOPT, gpopt::ExmiUnsatisfiedRequiredProperties))
					{
						GPOS_RETHROW(ex);
					}
					IErrorContext *perrctxt = CTask::PtskSelf()->Perrctxt();
					at.Os() << perrctxt->WszMsg() << std::endl;
					GPOS_RESET_EX;
				}
				GPOS_CATCH_END;
				CRefCount::SafeRelease(pexprAlt);
				CRefCount::SafeRelease(pdpctxtplan);
			}
		}
	}

	// clean up
	CRefCount::SafeRelease(pexprPlan);
	GPOS_DELETE(pqc);
	CRefCount::SafeRelease(pexpr);
	GPOS_DELETE(peng);

	return GPOS_OK;
}
	// test cardinality for predicates of the form: a + 1 < b
	// for such predicates, NDV based cardinality estimation is not applicable
	// note: any symbol other than = is not supported for NDV based cardinality estimation
	GPOS_RESULT
	CJoinCardinalityNDVBasedEqPredTest::EresUnittest_NDVCardEstimationNotApplicableInequalityRange()
	{
		// 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 *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::PexprScalarCmp(mp,
														 pexprScOp,
														 pexprScalarIdentRight,
														 IMDType::EcmptLEq
		);

		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;
	}
Example #11
0
//---------------------------------------------------------------------------
//	@function:
//		CParseHandlerTest::EresParseAndSerializeStatistics
//
//	@doc:
//		Verifies that after parsing the given DXL file containing statistics
//		into a list of statistics objects, which should be serialized back
//		to the same string.
//
//---------------------------------------------------------------------------
GPOS_RESULT
CParseHandlerTest::EresParseAndSerializeStatistics
	(
	IMemoryPool *mp,
	const CHAR *dxl_filename,
	BOOL fValidate
	)
{
	// setup a file-based provider
	CMDProviderMemory *pmdp = CTestUtils::m_pmdpf;
	pmdp->AddRef();
	CMDAccessor mda(mp, CMDCache::Pcache(), CTestUtils::m_sysidDefault, pmdp);

	// install opt context in TLS
	CAutoOptCtxt aoc
					(
					mp,
					&mda,
					NULL /* pceeval */,
					CTestUtils::GetCostModel(mp)
					);

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

	// read DXL file
	CHAR *dxl_string = CDXLUtils::Read(mp, dxl_filename);

	GPOS_CHECK_ABORT;

	// parse the metadata objects into a dynamic array
	const CHAR *szValidationPath = NULL;
	if (fValidate)
	{
	   szValidationPath = CTestUtils::m_szXSDPath;
	}

	// parse the statistics objects
	CDXLStatsDerivedRelationArray *dxl_derived_rel_stats_array = CDXLUtils::ParseDXLToStatsDerivedRelArray(mp, dxl_string, szValidationPath);
	CStatisticsArray *statistics_array = CDXLUtils::ParseDXLToOptimizerStatisticObjArray
								(
								mp,
								&mda,
								dxl_derived_rel_stats_array
								);

	dxl_derived_rel_stats_array->Release();


	GPOS_ASSERT(NULL != statistics_array);

	CStatistics *stats = (* statistics_array)[0];
	GPOS_ASSERT(stats);

	stats->Rows();
	oss << "Statistics:" << std::endl;
	CCardinalityTestUtils::PrintStats(mp, stats);

	GPOS_CHECK_ABORT;

	oss << "Serializing Statistics Objects" << std::endl;
	CWStringDynamic *statistics_str = CDXLUtils::SerializeStatistics
											(
											mp,
											&mda,
											statistics_array,
											true /*serialize_header_footer*/,
											true /*indentation*/
											);

	CWStringDynamic dstrExpected(mp);
	dstrExpected.AppendFormat(GPOS_WSZ_LIT("%s"), dxl_string);

	GPOS_ASSERT(dstrExpected.Equals(statistics_str));

	statistics_array->Release();

	GPOS_DELETE_ARRAY(dxl_string);
	GPOS_DELETE(statistics_str);
	return GPOS_OK;
}