Example #1
0
//---------------------------------------------------------------------------
//	@function:
//		CICGTest::EresUnittest_NegativeIndexApplyTests
//
//	@doc:
//		Negative IndexApply tests;
//		optimizer should not be able to generate a plan
//
//---------------------------------------------------------------------------
GPOS_RESULT
CICGTest::EresUnittest_NegativeIndexApplyTests()
{
	// enable (Redistribute, Broadcast) hash join plans
	CAutoTraceFlag atf(EopttraceEnableRedistributeBroadcastHashJoin, true /*fVal*/);

	// disable physical scans and NLJ to force using index-apply
	CAutoTraceFlag atfDTS(EopttraceDisableXformBase + CXform::ExfDynamicGet2DynamicTableScan, true);
	CAutoTraceFlag atfTS(EopttraceDisableXformBase + CXform::ExfGet2TableScan, true);
	CAutoTraceFlag atfNLJ(EopttraceDisableXformBase + CXform::ExfInnerJoin2NLJoin, true);

	CAutoMemoryPool amp(CAutoMemoryPool::ElcNone);
	IMemoryPool *pmp = amp.Pmp();

	GPOS_RESULT eres = GPOS_OK;
	const ULONG ulTests = GPOS_ARRAY_SIZE(rgszNegativeIndexApplyFileNames);
	for (ULONG ul = m_ulNegativeIndexApplyTestCounter; ul < ulTests; ul++)
	{
		GPOS_TRY
		{
			ICostModel *pcm = CTestUtils::Pcm(pmp);

			COptimizerConfig *poconf = GPOS_NEW(pmp) COptimizerConfig
						(
						CEnumeratorConfig::Pec(pmp, 0 /*ullPlanId*/),
						CStatisticsConfig::PstatsconfDefault(pmp),
						CCTEConfig::PcteconfDefault(pmp),
						pcm,
						CHint::PhintDefault(pmp)
						);
			CDXLNode *pdxlnPlan = CMinidumperUtils::PdxlnExecuteMinidump
									(
									pmp,
									rgszNegativeIndexApplyFileNames[ul],
									GPOPT_TEST_SEGMENTS /*ulSegments*/,
									1 /*ulSessionId*/,
									1, /*ulCmdId*/
									poconf,
									NULL /*pceeval*/
									);
			GPOS_CHECK_ABORT;
			poconf->Release();
			pdxlnPlan->Release();
			pcm->Release();

			// test should have thrown
			eres = GPOS_FAILED;
			break;
		}
		GPOS_CATCH_EX(ex)
		{
			if (GPOS_MATCH_EX(ex, gpopt::ExmaGPOPT, gpopt::ExmiNoPlanFound))
			{
				GPOS_RESET_EX;
			}
			else
			{
				GPOS_RETHROW(ex);
			}
		}
		GPOS_CATCH_END;
		m_ulNegativeIndexApplyTestCounter++;
	}

	if (GPOS_OK == eres)
	{
		m_ulNegativeIndexApplyTestCounter = 0;
	}

	return eres;
}
Example #2
0
//---------------------------------------------------------------------------
//	@function:
//		CICGTest::EresUnittest_RunUnsupportedMinidumpTests
//
//	@doc:
//		Run all unsupported Minidump-based tests
//
//---------------------------------------------------------------------------
GPOS_RESULT
CICGTest::EresUnittest_RunUnsupportedMinidumpTests()
{

	// enable (Redistribute, Broadcast) hash join plans
	CAutoTraceFlag atf1(EopttraceEnableRedistributeBroadcastHashJoin, true /*fVal*/);

	CAutoTraceFlag atf2(EopttraceDisableXformBase + CXform::ExfDynamicGet2DynamicTableScan, true);
	
	CAutoMemoryPool amp(CAutoMemoryPool::ElcNone);
	IMemoryPool *pmp = amp.Pmp();
	
	GPOS_RESULT eres = GPOS_OK;
	const ULONG ulTests = GPOS_ARRAY_SIZE(unSupportedTestCases);
	for (ULONG ul = m_ulUnsupportedTestCounter; ul < ulTests; ul++)
	{
		const CHAR *szFilename = unSupportedTestCases[ul].szFilename;
		CDXLMinidump *pdxlmd = CMinidumperUtils::PdxlmdLoad(pmp, szFilename);
		bool unmatchedException = false;
		ULONG unmatchedExceptionMajor = 0;
		ULONG unmatchedExceptionMinor = 0;

		GPOS_TRY
		{
			ICostModel *pcm = CTestUtils::Pcm(pmp);

			COptimizerConfig *poconf = pdxlmd->Poconf();
			CDXLNode *pdxlnPlan = CMinidumperUtils::PdxlnExecuteMinidump
									(
									pmp, 
									szFilename,
									poconf->Pcm()->UlHosts() /*ulSegments*/,
									1 /*ulSessionId*/, 
									1, /*ulCmdId*/
									poconf,
									NULL /*pceeval*/
									);


			GPOS_CHECK_ABORT;
			pdxlnPlan->Release();
			pcm->Release();

			// test should have thrown
			eres = GPOS_FAILED;
			break;
		}
		GPOS_CATCH_EX(ex)
		{
			unmatchedExceptionMajor = ex.UlMajor();
			unmatchedExceptionMinor = ex.UlMinor();

			// verify expected exception
			if (unSupportedTestCases[ul].ulMajor == unmatchedExceptionMajor
					&& unSupportedTestCases[ul].ulMinor == unmatchedExceptionMinor)
			{
				eres = GPOS_OK;
			}
			else
			{
				unmatchedException = true;
				eres = GPOS_FAILED;
			}
			GPOS_RESET_EX;
		}
		GPOS_CATCH_END;

		GPOS_DELETE(pdxlmd);
		m_ulUnsupportedTestCounter++;

		if (GPOS_FAILED == eres && unmatchedException)
		{
			CAutoTrace at(pmp);
			at.Os() << "Test failed due to unmatched exceptions." << std::endl;
			at.Os() << " Expected result: " << unSupportedTestCases[ul].ulMajor << "." << unSupportedTestCases[ul].ulMinor << std::endl;
			at.Os() << " Actual result: " << unmatchedExceptionMajor << "." << unmatchedExceptionMinor << std::endl;
		}
	}
	
	if (GPOS_OK == eres)
	{
		m_ulUnsupportedTestCounter = 0;
	}

	return eres;
}
Example #3
0
//---------------------------------------------------------------------------
//	@function:
//		CCostContext::ComputeCost
//
//	@doc:
//		Compute cost of current context,
//
//		the function extracts cardinality and row width of owner operator
//		and child operators, and then adjusts row estimate obtained from
//		statistics based on data distribution obtained from plan properties,
//
//		statistics row estimate is computed on logical expressions by
//		estimating the size of the whole relation regardless data
//		distribution, on the other hand, optimizer's cost model computes
//		the cost of a plan instance on some segment,
//
//		when a plan produces tuples distributed to multiple segments, we
//		need to divide statistics row estimate by the number segments to
//		provide a per-segment row estimate for cost computation,
//
//		Note that this scaling of row estimate cannot happen during
//		statistics derivation since plans are not created yet at this point
//
// 		this function also extracts number of rebinds of owner operator child
//		operators, if statistics are computed using predicates with external
//		parameters (outer references), number of rebinds is the total number
//		of external parameters' values
//
//---------------------------------------------------------------------------
CCost
CCostContext::CostCompute
	(
	IMemoryPool *pmp,
	DrgPcost *pdrgpcostChildren
	)
{
	// derive context stats
	DeriveStats();

	ULONG ulArity = 0;
	if (NULL != m_pdrgpoc)
	{
		ulArity = Pdrgpoc()->UlLength();
	}

	m_pstats->AddRef();
	ICostModel::SCostingInfo ci(pmp, ulArity, GPOS_NEW(pmp) ICostModel::CCostingStats(m_pstats));

	ICostModel *pcm = COptCtxt::PoctxtFromTLS()->Pcm();

	CExpressionHandle exprhdl(pmp);
	exprhdl.Attach(this);

	// extract local costing info
	DOUBLE dRows = m_pstats->DRows().DVal();
	if (CDistributionSpec::EdptPartitioned == Pdpplan()->Pds()->Edpt())
	{
		// scale statistics row estimate by number of segments
		dRows = DRowsPerHost().DVal();
	}
	ci.SetRows(dRows);

	DOUBLE dWidth = m_pstats->DWidth(pmp, m_poc->Prpp()->PcrsRequired()).DVal();
	ci.SetWidth(dWidth);

	DOUBLE dRebinds = m_pstats->DRebinds().DVal();
	ci.SetRebinds(dRebinds);
	GPOS_ASSERT_IMP(!exprhdl.FHasOuterRefs(), GPOPT_DEFAULT_REBINDS == (ULONG) (dRebinds) && "invalid number of rebinds when there are no outer references");

	// extract children costing info
	for (ULONG ul = 0; ul < ulArity; ul++)
	{
		COptimizationContext *pocChild = (*m_pdrgpoc)[ul];
		CCostContext *pccChild = pocChild->PccBest();
		GPOS_ASSERT(NULL != pccChild);

		IStatistics *pstatsChild = pccChild->Pstats();
		DOUBLE dRowsChild = pstatsChild->DRows().DVal();
		if (CDistributionSpec::EdptPartitioned == pccChild->Pdpplan()->Pds()->Edpt())
		{
			// scale statistics row estimate by number of segments
			dRowsChild = pccChild->DRowsPerHost().DVal();
		}
		ci.SetChildRows(ul, dRowsChild);

		DOUBLE dWidthChild = pstatsChild->DWidth(pmp, pocChild->Prpp()->PcrsRequired()).DVal();
		ci.SetChildWidth(ul, dWidthChild);

		DOUBLE dRebindsChild = pstatsChild->DRebinds().DVal();
		ci.SetChildRebinds(ul, dRebindsChild);
		GPOS_ASSERT_IMP(!exprhdl.FHasOuterRefs(ul), GPOPT_DEFAULT_REBINDS == (ULONG) (dRebindsChild) && "invalid number of rebinds when there are no outer references");

		DOUBLE dCostChild =  (*pdrgpcostChildren)[ul]->DVal();
		ci.SetChildCost(ul, dCostChild);
	}

	// compute cost using the underlying cost model
	return pcm->Cost(exprhdl, &ci);
}
Example #4
0
//---------------------------------------------------------------------------
//	@function:
//		CCostTest::EresUnittest_SetParams
//
//	@doc:
//		Test of setting cost model params
//
//---------------------------------------------------------------------------
GPOS_RESULT
CCostTest::EresUnittest_SetParams()
{
	CAutoMemoryPool amp;
	IMemoryPool *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, NULL, /* pceeval */ pcm);

	// generate in-equality join expression
	CExpression *pexprOuter = CTestUtils::PexprLogicalGet(mp);
	const CColRef *pcrOuter = CDrvdPropRelational::GetRelationalProperties(pexprOuter->PdpDerive())->PcrsOutput()->PcrAny();
	CExpression *pexprInner = CTestUtils::PexprLogicalGet(mp);
	const CColRef *pcrInner = CDrvdPropRelational::GetRelationalProperties(pexprInner->PdpDerive())->PcrsOutput()->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 = NULL;
	{
		CEngine eng(mp);

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

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

		// optimize query
		eng.Optimize();

		// extract plan
		pexprPlan1 = eng.PexprExtractPlan();
		GPOS_ASSERT(NULL != 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 = NULL;
	{
		CEngine eng(mp);

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

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

		// optimize query
		eng.Optimize();

		// extract plan
		pexprPlan2 = eng.PexprExtractPlan();
		GPOS_ASSERT(NULL != 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;
}
Example #5
0
//---------------------------------------------------------------------------
//	@function:
//		CCostTest::EresUnittest_CalibratedCostModel
//
//	@doc:
//		GPDB's calibrated cost model test
//
//---------------------------------------------------------------------------
GPOS_RESULT
CCostTest::EresUnittest_CalibratedCostModel()
{
	CAutoTraceFlag atf1(EtraceSimulateOOM, false);
	CAutoTraceFlag atf2(EtraceSimulateAbort, false);
	CAutoTraceFlag atf3(EtraceSimulateIOError, false);
	CAutoTraceFlag atf4(EtraceSimulateNetError, false);

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

	ICostModel *pcm = GPOS_NEW(pmp) CCostModelGPDB(pmp, GPOPT_TEST_SEGMENTS);
	pcm->AddRef();

	{
		// install opt context in TLS
		CAutoOptCtxt aoc
						(
						pmp,
						&mda,
						NULL, /* pceeval */
						pcm
						);


		TestParams(pmp, true /*fCalibrated*/);
	}

	// minidump files
	const CHAR *rgszFileNamesCalibratedCostModel[] =
	{
		"../data/dxl/minidump/PartTbl-MultiWayJoinWithDPE.mdp",
		"../data/dxl/tpch/q2.mdp",
		"../data/dxl/minidump/CTE-4.mdp",
		"../data/dxl/minidump/Lead-Lag-WinFuncs.mdp",
	};

	COptimizerConfig* poconf = COptimizerConfig::PoconfDefault(pmp, pcm);

	for (ULONG ul = 0; ul < GPOS_ARRAY_SIZE(rgszFileNamesCalibratedCostModel); ul++)
	{
		CDXLNode *pdxlnPlan = CMinidumperUtils::PdxlnExecuteMinidump
							(
							pmp,
							rgszFileNamesCalibratedCostModel[ul],
							GPOPT_TEST_SEGMENTS,
							1 /*ulSessionId*/,
							1 /*ulCmdId*/,
							poconf,
							NULL /*pceeval*/
							);
		pdxlnPlan->Release();
	}

	poconf->Release();

	return GPOS_OK;
}
//---------------------------------------------------------------------------
//	@function:
//		CParseHandlerOptimizerConfig::EndElement
//
//	@doc:
//		Invoked by Xerces to process a closing tag
//
//---------------------------------------------------------------------------
void
CParseHandlerOptimizerConfig::EndElement
	(
	const XMLCh* const, // element_uri,
	const XMLCh* const element_local_name,
	const XMLCh* const // element_qname
	)
{
	if (0 != XMLString::compareString(CDXLTokens::XmlstrToken(EdxltokenOptimizerConfig), element_local_name))
	{
		CWStringDynamic *str = CDXLUtils::CreateDynamicStringFromXMLChArray(m_parse_handler_mgr->GetDXLMemoryManager(), element_local_name);
		GPOS_RAISE( gpdxl::ExmaDXL, gpdxl::ExmiDXLUnexpectedTag, str->GetBuffer());
	}
	
	GPOS_ASSERT(NULL == m_optimizer_config);
	GPOS_ASSERT(7 >= this->Length());

	CParseHandlerEnumeratorConfig *pphEnumeratorConfig = dynamic_cast<CParseHandlerEnumeratorConfig *>((*this)[0]);
	CEnumeratorConfig *pec = pphEnumeratorConfig->GetEnumeratorCfg();
	pec->AddRef();

	CParseHandlerStatisticsConfig *pphStatisticsConfig = dynamic_cast<CParseHandlerStatisticsConfig *>((*this)[1]);
	CStatisticsConfig *stats_config = pphStatisticsConfig->GetStatsConf();
	stats_config->AddRef();

	CParseHandlerCTEConfig *pphCTEConfig = dynamic_cast<CParseHandlerCTEConfig *>((*this)[2]);
	CCTEConfig *pcteconfig = pphCTEConfig->GetCteConf();
	pcteconfig->AddRef();
	
	CParseHandlerWindowOids *pphDefoidsGPDB = dynamic_cast<CParseHandlerWindowOids *>((*this)[3]);
	CWindowOids *pwindowoidsGPDB = pphDefoidsGPDB->GetWindowOids();
	GPOS_ASSERT(NULL != pwindowoidsGPDB);
	pwindowoidsGPDB->AddRef();

	ICostModel *pcm = NULL;
	CHint *phint = NULL;
	if (5 == this->Length())
	{
		// no cost model: use default one
		pcm = ICostModel::PcmDefault(m_mp);
		phint = CHint::PhintDefault(m_mp);
	}
	else
	{
		CParseHandlerCostModel *pphCostModelConfig = dynamic_cast<CParseHandlerCostModel *>((*this)[4]);
		pcm = pphCostModelConfig->GetCostModel();
		GPOS_ASSERT(NULL != pcm);
		pcm->AddRef();

		if (6 == this->Length())
		{
			phint = CHint::PhintDefault(m_mp);
		}
		else
		{
			CParseHandlerHint *pphHint = dynamic_cast<CParseHandlerHint *>((*this)[5]);
			phint = pphHint->GetHint();
			GPOS_ASSERT(NULL != phint);
			phint->AddRef();
		}
	}

	m_optimizer_config = GPOS_NEW(m_mp) COptimizerConfig(pec, stats_config, pcteconfig, pcm, phint, pwindowoidsGPDB);

	CParseHandlerTraceFlags *pphTraceFlags = dynamic_cast<CParseHandlerTraceFlags *>((*this)[this->Length() - 1]);
	pphTraceFlags->GetTraceFlagBitSet()->AddRef();
	m_pbs = pphTraceFlags->GetTraceFlagBitSet();
	
	// deactivate handler
	m_parse_handler_mgr->DeactivateHandler();
}