greenplumn CCostTest 源码

  • 2022-08-18
  • 浏览 (62)

greenplumn CCostTest 代码

文件路径:/src/backend/gporca/server/src/unittest/gpopt/cost/CCostTest.cpp

//---------------------------------------------------------------------------
//	Greenplum Database
//	Copyright (C) 2012 EMC Corp.
//
//	@filename:
//		CCostTest.cpp
//
//	@doc:
//		Tests for basic operations on cost
//---------------------------------------------------------------------------
#include "unittest/gpopt/cost/CCostTest.h"

#include "gpos/error/CAutoTrace.h"
#include "gpos/task/CAutoTraceFlag.h"

#include "gpdbcost/CCostModelGPDB.h"
#include "gpopt/cost/CCost.h"
#include "gpopt/cost/ICostModelParams.h"
#include "gpopt/engine/CEngine.h"
#include "gpopt/eval/CConstExprEvaluatorDefault.h"
#include "gpopt/minidump/CMinidumperUtils.h"
#include "gpopt/operators/CLogicalInnerJoin.h"
#include "gpopt/optimizer/COptimizerConfig.h"
#include "naucrates/dxl/CDXLUtils.h"
#include "naucrates/dxl/parser/CParseHandlerDXL.h"

#include "unittest/base.h"
#include "unittest/gpopt/CTestUtils.h"

//---------------------------------------------------------------------------
//	@function:
//		CCostTest::EresUnittest
//
//	@doc:
//		Driver for unittests
//
//---------------------------------------------------------------------------
GPOS_RESULT
CCostTest::EresUnittest()
{
	CUnittest rgut[] = {
		GPOS_UNITTEST_FUNC(CCostTest::EresUnittest_Bool),
		GPOS_UNITTEST_FUNC(CCostTest::EresUnittest_Arithmetic),
		GPOS_UNITTEST_FUNC(CCostTest::EresUnittest_Params),
		GPOS_UNITTEST_FUNC(CCostTest::EresUnittest_Parsing),
		GPOS_UNITTEST_FUNC(EresUnittest_SetParams),

		// TODO: : re-enable test after resolving exception throwing problem on OSX
		// GPOS_UNITTEST_FUNC_THROW(CCostTest::EresUnittest_ParsingWithException, gpdxl::ExmaDXL, gpdxl::ExmiDXLUnexpectedTag),
	};

	return CUnittest::EresExecute(rgut, GPOS_ARRAY_SIZE(rgut));
}


//---------------------------------------------------------------------------
//	@function:
//		CCostTest::EresUnittest_Arithmetic
//
//	@doc:
//		Test arithmetic operations
//
//---------------------------------------------------------------------------
GPOS_RESULT
CCostTest::EresUnittest_Arithmetic()
{
	CAutoMemoryPool amp;
	CMemoryPool *mp = amp.Pmp();

	CCost cost1(2.5);
	CCost cost2(3.0);
	CCost cost3(5.49);
	CCost cost4(5.51);
	CCost cost5(7.49);
	CCost cost6(7.51);

	CCost costAdd(cost1 + cost2);
	CCost costMultiply(cost1 * cost2);

	GPOS_ASSERT(costAdd > cost3);
	GPOS_ASSERT(costAdd < cost4);

	GPOS_ASSERT(costMultiply > cost5);
	GPOS_ASSERT(costMultiply < cost6);

	CAutoTrace at(mp);
	IOstream &os(at.Os());

	os << "Arithmetic operations: " << std::endl
	   << cost1 << " + " << cost2 << " = " << costAdd << std::endl
	   << cost1 << " * " << cost2 << " = " << costMultiply << std::endl;

	return GPOS_OK;
}


//---------------------------------------------------------------------------
//	@function:
//		CCostTest::EresUnittest_Bool
//
//	@doc:
//		Test comparison operations
//
//---------------------------------------------------------------------------
GPOS_RESULT
CCostTest::EresUnittest_Bool()
{
	CAutoMemoryPool amp;
	CMemoryPool *mp = amp.Pmp();

	CCost cost1(2.5);
	CCost cost2(3.5);

	GPOS_ASSERT(cost1 < cost2);
	GPOS_ASSERT(cost2 > cost1);

	CAutoTrace at(mp);
	IOstream &os(at.Os());

	os << "Boolean operations: " << std::endl
	   << cost1 << " < " << cost2 << " = " << (cost1 < cost2) << std::endl
	   << cost2 << " > " << cost1 << " = " << (cost2 > cost1) << std::endl;

	return GPOS_OK;
}

//---------------------------------------------------------------------------
//	@function:
//		CCostTest::TestParams
//
//	@doc:
//		Test cost model parameters
//
//---------------------------------------------------------------------------
void
CCostTest::TestParams(CMemoryPool *mp)
{
	CAutoTrace at(mp);
	IOstream &os(at.Os());

	ICostModelParams *pcp =
		((CCostModelGPDB *) COptCtxt::PoctxtFromTLS()->GetCostModel())
			->GetCostModelParams();

	CDouble dSeqIOBandwidth =
		pcp->PcpLookup(CCostModelParamsGPDB::EcpSeqIOBandwidth)->Get();
	CDouble dRandomIOBandwidth =
		pcp->PcpLookup(CCostModelParamsGPDB::EcpRandomIOBandwidth)->Get();
	CDouble dTupProcBandwidth =
		pcp->PcpLookup(CCostModelParamsGPDB::EcpTupProcBandwidth)->Get();
	CDouble dNetBandwidth =
		pcp->PcpLookup(CCostModelParamsGPDB::EcpNetBandwidth)->Get();
	CDouble dSegments =
		pcp->PcpLookup(CCostModelParamsGPDB::EcpSegments)->Get();
	CDouble dNLJFactor =
		pcp->PcpLookup(CCostModelParamsGPDB::EcpNLJFactor)->Get();
	CDouble dHashFactor =
		pcp->PcpLookup(CCostModelParamsGPDB::EcpHashFactor)->Get();
	CDouble dDefaultCost =
		pcp->PcpLookup(CCostModelParamsGPDB::EcpDefaultCost)->Get();

	os << std::endl << "Lookup cost model params by id: " << std::endl;
	os << "Seq I/O bandwidth: " << dSeqIOBandwidth << std::endl;
	os << "Random I/O bandwidth: " << dRandomIOBandwidth << std::endl;
	os << "Tuple proc bandwidth: " << dTupProcBandwidth << std::endl;
	os << "Network bandwidth: " << dNetBandwidth << std::endl;
	os << "Segments: " << dSegments << std::endl;
	os << "NLJ Factor: " << dNLJFactor << std::endl;
	os << "Hash Factor: " << dHashFactor << std::endl;
	os << "Default Cost: " << dDefaultCost << std::endl;

	CDouble dSeqIOBandwidth1 = pcp->PcpLookup("SeqIOBandwidth")->Get();
	CDouble dRandomIOBandwidth1 = pcp->PcpLookup("RandomIOBandwidth")->Get();
	CDouble dTupProcBandwidth1 = pcp->PcpLookup("TupProcBandwidth")->Get();
	CDouble dNetBandwidth1 = pcp->PcpLookup("NetworkBandwidth")->Get();
	CDouble dSegments1 = pcp->PcpLookup("Segments")->Get();
	CDouble dNLJFactor1 = pcp->PcpLookup("NLJFactor")->Get();
	CDouble dHashFactor1 = pcp->PcpLookup("HashFactor")->Get();
	CDouble dDefaultCost1 = pcp->PcpLookup("DefaultCost")->Get();

	os << std::endl << "Lookup cost model params by name: " << std::endl;
	os << "Seq I/O bandwidth: " << dSeqIOBandwidth1 << std::endl;
	os << "Random I/O bandwidth: " << dRandomIOBandwidth1 << std::endl;
	os << "Tuple proc bandwidth: " << dTupProcBandwidth1 << std::endl;
	os << "Network bandwidth: " << dNetBandwidth1 << std::endl;
	os << "Segments: " << dSegments1 << std::endl;
	os << "NLJ Factor: " << dNLJFactor1 << std::endl;
	os << "Hash Factor: " << dHashFactor1 << std::endl;
	os << "Default Cost: " << dDefaultCost1 << std::endl;

	GPOS_ASSERT(dSeqIOBandwidth == dSeqIOBandwidth1);
	GPOS_ASSERT(dRandomIOBandwidth == dRandomIOBandwidth1);
	GPOS_ASSERT(dTupProcBandwidth == dTupProcBandwidth1);
	GPOS_ASSERT(dNetBandwidth == dNetBandwidth1);
	GPOS_ASSERT(dSegments == dSegments1);
	GPOS_ASSERT(dNLJFactor == dNLJFactor1);
	GPOS_ASSERT(dHashFactor == dHashFactor1);
	GPOS_ASSERT(dDefaultCost == dDefaultCost1);
}


//---------------------------------------------------------------------------
//	@function:
//		CCostTest::EresUnittest_Params
//
//	@doc:
//		Cost model parameters
//
//---------------------------------------------------------------------------
GPOS_RESULT
CCostTest::EresUnittest_Params()
{
	CAutoMemoryPool amp;
	CMemoryPool *mp = amp.Pmp();

	// 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, nullptr, /* pceeval */
					 GPOS_NEW(mp) CCostModelGPDB(mp, GPOPT_TEST_SEGMENTS));

	TestParams(mp);

	return GPOS_OK;
}


//---------------------------------------------------------------------------
//	@function:
//		CCostTest::EresUnittest_Parsing
//
//	@doc:
//		Test parsing cost params from external file
//
//---------------------------------------------------------------------------
GPOS_RESULT
CCostTest::EresUnittest_Parsing()
{
	CAutoMemoryPool amp;
	CMemoryPool *mp = amp.Pmp();
	CParseHandlerDXL *pphDXL = CDXLUtils::GetParseHandlerForDXLFile(
		mp, "../data/dxl/cost/cost0.xml", nullptr);
	ICostModelParams *pcp = pphDXL->GetCostModelParams();

	{
		CAutoTrace at(mp);
		at.Os() << " Parsed cost params: " << std::endl;
		pcp->OsPrint(at.Os());
	}
	GPOS_DELETE(pphDXL);

	return GPOS_OK;
}


//---------------------------------------------------------------------------
//	@function:
//		CSearchStrategyTest::EresUnittest_ParsingWithException
//
//	@doc:
//		Test exception handling when parsing cost params
//
//---------------------------------------------------------------------------
GPOS_RESULT
CCostTest::EresUnittest_ParsingWithException()
{
	CAutoMemoryPool amp;
	CMemoryPool *mp = amp.Pmp();
	CParseHandlerDXL *pphDXL = CDXLUtils::GetParseHandlerForDXLFile(
		mp, "../data/dxl/cost/wrong-cost.xml", nullptr);
	GPOS_DELETE(pphDXL);

	return GPOS_OK;
}


//---------------------------------------------------------------------------
//	@function:
//		CCostTest::EresUnittest_SetParams
//
//	@doc:
//		Test of setting cost model params
//
//---------------------------------------------------------------------------
GPOS_RESULT
CCostTest::EresUnittest_SetParams()
{
	CAutoMemoryPool amp;
	CMemoryPool *mp = amp.Pmp();

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

	ICostModel *pcm = GPOS_NEW(mp) CCostModelGPDB(mp, GPOPT_TEST_SEGMENTS);

	// install opt context in TLS
	CAutoOptCtxt aoc(mp, &mda, nullptr, /* pceeval */ pcm);

	// generate in-equality join expression
	CExpression *pexprOuter = CTestUtils::PexprLogicalGet(mp);
	const CColRef *pcrOuter = pexprOuter->DeriveOutputColumns()->PcrAny();
	CExpression *pexprInner = CTestUtils::PexprLogicalGet(mp);
	const CColRef *pcrInner = pexprInner->DeriveOutputColumns()->PcrAny();
	CExpression *pexprPred =
		CUtils::PexprScalarCmp(mp, pcrOuter, pcrInner, IMDType::EcmptNEq);
	CExpression *pexpr = CUtils::PexprLogicalJoin<CLogicalInnerJoin>(
		mp, pexprOuter, pexprInner, pexprPred);

	// optimize in-equality join based on default cost model params
	CExpression *pexprPlan1 = nullptr;
	{
		CEngine eng(mp);

		// generate query context
		CQueryContext *pqc = CTestUtils::PqcGenerate(mp, pexpr);

		// Initialize engine
		eng.Init(pqc, nullptr /*search_stage_array*/);

		// optimize query
		eng.Optimize();

		// extract plan
		pexprPlan1 = eng.PexprExtractPlan();
		GPOS_ASSERT(nullptr != pexprPlan1);

		GPOS_DELETE(pqc);
	}

	// change NLJ cost factor
	ICostModelParams::SCostParam *pcp = pcm->GetCostModelParams()->PcpLookup(
		CCostModelParamsGPDB::EcpNLJFactor);
	CDouble dNLJFactor = CDouble(2.0);
	CDouble dVal = pcp->Get() * dNLJFactor;
	pcm->GetCostModelParams()->SetParam(pcp->Id(), dVal, dVal - 0.5,
										dVal + 0.5);

	// optimize again after updating NLJ cost factor
	CExpression *pexprPlan2 = nullptr;
	{
		CEngine eng(mp);

		// generate query context
		CQueryContext *pqc = CTestUtils::PqcGenerate(mp, pexpr);

		// Initialize engine
		eng.Init(pqc, nullptr /*search_stage_array*/);

		// optimize query
		eng.Optimize();

		// extract plan
		pexprPlan2 = eng.PexprExtractPlan();
		GPOS_ASSERT(nullptr != pexprPlan2);

		GPOS_DELETE(pqc);
	}

	{
		CAutoTrace at(mp);
		at.Os() << "\nPLAN1: \n" << *pexprPlan1;
		at.Os() << "\nNLJ Cost1: " << (*pexprPlan1)[0]->Cost();
		at.Os() << "\n\nPLAN2: \n" << *pexprPlan2;
		at.Os() << "\nNLJ Cost2: " << (*pexprPlan2)[0]->Cost();
	}
	GPOS_ASSERT(
		(*pexprPlan2)[0]->Cost() >= (*pexprPlan1)[0]->Cost() * dNLJFactor &&
		"expected NLJ cost in PLAN2 to be larger than NLJ cost in PLAN1");

	// clean up
	pexpr->Release();
	pexprPlan1->Release();
	pexprPlan2->Release();

	return GPOS_OK;
}

// EOF

相关信息

greenplumn 源码目录

相关文章

greenplumn adminpack 源码

greenplumn verify_nbtree 源码

greenplumn auth_delay 源码

greenplumn auto_explain 源码

greenplumn blcost 源码

greenplumn blinsert 源码

greenplumn bloom 源码

greenplumn blscan 源码

greenplumn blutils 源码

greenplumn blvacuum 源码

0  赞