//--------------------------------------------------------------------------- // @function: // CParseHandlerTest::EresParseAndSerializePlan // // @doc: // Verifies that after parsing the given DXL file into a DXL tree, // it will be serialized back to the same string. // //--------------------------------------------------------------------------- GPOS_RESULT CParseHandlerTest::EresParseAndSerializePlan ( IMemoryPool *pmp, const CHAR *szDXLFileName, BOOL fValidate ) { CWStringDynamic str(pmp); COstreamString oss(&str); // read DXL file CHAR *szDXL = CDXLUtils::SzRead(pmp, szDXLFileName); GPOS_CHECK_ABORT; const CHAR *szValidationPath = NULL; if (fValidate) { szValidationPath = CTestUtils::m_szXSDPath; } // the root of the parsed DXL tree ULLONG ullPlanId = ULLONG_MAX; ULLONG ullPlanSpaceSize = ULLONG_MAX; CDXLNode *pdxlnRoot = CDXLUtils::PdxlnParsePlan(pmp, szDXL, szValidationPath, &ullPlanId, &ullPlanSpaceSize); GPOS_CHECK_ABORT; oss << "Serializing parsed tree" << std::endl; CWStringDynamic strPlan(pmp); COstreamString osPlan(&strPlan); CDXLUtils::SerializePlan(pmp, osPlan, pdxlnRoot, ullPlanId, ullPlanSpaceSize, true /*fSerializeHeaderFooter*/, true /*fIndent*/); GPOS_CHECK_ABORT; CWStringDynamic dstrExpected(pmp); dstrExpected.AppendFormat(GPOS_WSZ_LIT("%s"), szDXL); if (!dstrExpected.FEquals(&strPlan)) { GPOS_TRACE(dstrExpected.Wsz()); GPOS_TRACE(strPlan.Wsz()); GPOS_ASSERT(!"Not matching"); } // cleanup pdxlnRoot->Release(); GPOS_DELETE_ARRAY(szDXL); return GPOS_OK; }
//--------------------------------------------------------------------------- // @function: // CConstExprEvaluatorDXL::PexprEval // // @doc: // Evaluate the given expression and return the result as a new expression. // Caller takes ownership of returned expression // //--------------------------------------------------------------------------- CExpression * CConstExprEvaluatorDXL::PexprEval ( CExpression *pexpr ) { GPOS_ASSERT(NULL != pexpr); const CHAR *szErrorMsg = ""; if (!FValidInput(pexpr, &szErrorMsg)) { GPOS_RAISE(gpopt::ExmaGPOPT, gpopt::ExmiEvalUnsupportedScalarExpr, szErrorMsg); } CDXLNode *pdxlnExpr = m_trexpr2dxl.PdxlnScalar(pexpr); CDXLNode *pdxlnResult = m_pconstdxleval->PdxlnEvaluateExpr(pdxlnExpr); GPOS_ASSERT(EdxloptypeScalar == pdxlnResult->Pdxlop()->Edxloperatortype()); CExpression *pexprResult = m_trdxl2expr.PexprTranslateScalar(pdxlnResult, NULL /*pdrgpcr*/); pdxlnResult->Release(); pdxlnExpr->Release(); return pexprResult; }
//--------------------------------------------------------------------------- // @function: // CParseHandlerTest::EresParseAndSerializeScalarExpr // // @doc: // Parses a ScalarExpr and verifies that the serialization is identical // to the original input. // //--------------------------------------------------------------------------- GPOS_RESULT CParseHandlerTest::EresParseAndSerializeScalarExpr ( IMemoryPool *pmp, const CHAR *szDXLFileName, BOOL fValidate ) { // read DXL file CHAR *szDXL = CDXLUtils::SzRead(pmp, szDXLFileName); GPOS_CHECK_ABORT; const CHAR *szValidationPath = NULL; if (fValidate) { szValidationPath = CTestUtils::m_szXSDPath; } // the root of the parsed DXL tree CDXLNode *pdxlnRoot = CDXLUtils::PdxlnParseScalarExpr(pmp, szDXL, szValidationPath); GPOS_CHECK_ABORT; CWStringDynamic str(pmp); COstreamString oss(&str); oss << "Serializing parsed tree" << std::endl; CWStringDynamic *pstr = CDXLUtils::PstrSerializeScalarExpr(pmp, pdxlnRoot, true /*fSerializeHeaderFooter*/, true /*fIndent*/); GPOS_CHECK_ABORT; CWStringDynamic dstrExpected(pmp); dstrExpected.AppendFormat(GPOS_WSZ_LIT("%s"), szDXL); GPOS_RESULT eres = GPOS_OK; if (!dstrExpected.FEquals(pstr)) { GPOS_TRACE(dstrExpected.Wsz()); GPOS_TRACE(pstr->Wsz()); GPOS_ASSERT(!"Not matching"); eres = GPOS_FAILED; } // cleanup pdxlnRoot->Release(); GPOS_DELETE(pstr); GPOS_DELETE_ARRAY(szDXL); return eres; }
//--------------------------------------------------------------------------- // @function: // CDXLUtilsTest::EresUnittest_SerializePlan // // @doc: // Testing serialization of plans in DXL // //--------------------------------------------------------------------------- GPOS_RESULT CDXLUtilsTest::EresUnittest_SerializePlan() { // create memory pool CAutoMemoryPool amp; IMemoryPool *pmp = amp.Pmp(); // read DXL file CHAR *szDXL = CDXLUtils::SzRead(pmp, szPlanFile); ULLONG ullPlanId = ULLONG_MAX; ULLONG ullPlanSpaceSize = ULLONG_MAX; CDXLNode *pdxln = CDXLUtils::PdxlnParsePlan(pmp, szDXL, NULL /*szXSDPath*/, &ullPlanId, &ullPlanSpaceSize); // serialize with document header BOOL rgfIndentation[] = {true, false}; BOOL rgfHeaders[] = {true, false}; CWStringDynamic str(pmp); COstreamString oss(&str); for (ULONG ulHeaders = 0; ulHeaders < GPOS_ARRAY_SIZE(rgfHeaders); ulHeaders++) { for (ULONG ulIndent = 0; ulIndent < GPOS_ARRAY_SIZE(rgfIndentation); ulIndent++) { CWStringDynamic *pstr = CDXLUtils::PstrSerializePlan(pmp, pdxln, ullPlanId, ullPlanSpaceSize, rgfHeaders[ulHeaders], rgfIndentation[ulIndent]); oss << "Headers: " << rgfHeaders[ulHeaders] << ", indentation: " << rgfIndentation[ulIndent] << std::endl; oss << pstr->Wsz() << std::endl; GPOS_DELETE(pstr); } } GPOS_TRACE(str.Wsz()); // cleanup pdxln->Release(); GPOS_DELETE_ARRAY(szDXL); return GPOS_OK; }
//--------------------------------------------------------------------------- // @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; }
//--------------------------------------------------------------------------- // @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; }
//--------------------------------------------------------------------------- // @function: // PvExec // // @doc: // Function driving execution. // //--------------------------------------------------------------------------- static void * PvExec ( void *pv ) { CMainArgs *pma = (CMainArgs*) pv; CBitVector bv(ITask::PtskSelf()->Pmp(), CUnittest::UlTests()); CHAR ch = '\0'; CHAR *szFileName = NULL; BOOL fMinidump = false; BOOL fUnittest = false; while (pma->FGetopt(&ch)) { CHAR *szTestName = NULL; switch (ch) { case 'U': szTestName = optarg; // fallthru case 'u': CUnittest::FindTest(bv, CUnittest::EttStandard, szTestName); fUnittest = true; break; case 'x': CUnittest::FindTest(bv, CUnittest::EttExtended, NULL /*szTestName*/); fUnittest = true; break; case 'T': CUnittest::SetTraceFlag(optarg); break; case 'd': fMinidump = true; szFileName = optarg; break; default: // ignore other parameters break; } } if (fMinidump && fUnittest) { GPOS_TRACE(GPOS_WSZ_LIT("Cannot specify -d and -U/-u options at the same time")); return NULL; } if (fMinidump) { // initialize DXL support InitDXL(); CMDCache::Init(); CAutoMemoryPool amp; IMemoryPool *pmp = amp.Pmp(); COptimizerConfig* poconf = COptimizerConfig::PoconfDefault(pmp); CDXLNode *pdxlnPlan = CMinidumperUtils::PdxlnExecuteMinidump ( pmp, szFileName, GPOPT_TEST_SEGMENTS, 1 /*ulSessionId*/, 1 /*ulCmdId*/, poconf, NULL /*pceeval*/ ); poconf->Release(); pdxlnPlan->Release(); CMDCache::Shutdown(); } else { GPOS_ASSERT(fUnittest); tests_failed = CUnittest::Driver(&bv); } return NULL; }
//--------------------------------------------------------------------------- // @function: // CMissingStatsTest::EresUnittest_RunTests // // @doc: // Run all Minidump-based tests with plan matching // //--------------------------------------------------------------------------- GPOS_RESULT CMissingStatsTest::EresUnittest_RunTests() { SMissingStatsTestCase rgtc[] = { {"../data/dxl/minidump/MissingStats.mdp", 2}, {"../data/dxl/minidump/NoMissingStatsAfterDroppedCol.mdp", 0}, {"../data/dxl/minidump/NoMissingStats.mdp", 0}, {"../data/dxl/minidump/NoMissingStatsForEmptyTable.mdp", 0}, {"../data/dxl/minidump/NoMissingStatsAskingForSystemColFOJ.mdp", 0}, }; CAutoMemoryPool amp(CAutoMemoryPool::ElcNone); IMemoryPool *pmp = amp.Pmp(); GPOS_RESULT eres = GPOS_OK; const ULONG ulTests = GPOS_ARRAY_SIZE(rgtc); for (ULONG ul = m_ulMissingStatsTestCounter; ((ul < ulTests) && (GPOS_OK == eres)); ul++) { ICostModel *pcm = CTestUtils::Pcm(pmp); CAutoTraceFlag atf1(EopttracePrintColsWithMissingStats, true /*fVal*/); COptimizerConfig *poconf = GPOS_NEW(pmp) COptimizerConfig ( CEnumeratorConfig::Pec(pmp, 0 /*ullPlanId*/), CStatisticsConfig::PstatsconfDefault(pmp), CCTEConfig::PcteconfDefault(pmp), pcm, CHint::PhintDefault(pmp), CWindowOids::Pwindowoids(pmp) ); SMissingStatsTestCase testCase = rgtc[ul]; CDXLNode *pdxlnPlan = CMinidumperUtils::PdxlnExecuteMinidump ( pmp, testCase.m_szInputFile, GPOPT_TEST_SEGMENTS /*ulSegments*/, 1 /*ulSessionId*/, 1, /*ulCmdId*/ poconf, NULL /*pceeval*/ ); CStatisticsConfig *pstatsconf = poconf->Pstatsconf(); DrgPmdid *pdrgmdidCol = GPOS_NEW(pmp) DrgPmdid(pmp); pstatsconf->CollectMissingStatsColumns(pdrgmdidCol); ULONG ulMissingStats = pdrgmdidCol->UlLength(); if (ulMissingStats != testCase.m_ulExpectedMissingStats) { // for debug traces CWStringDynamic str(pmp); COstreamString oss(&str); // print objects oss << std::endl; oss << "Expected Number of Missing Columns: " << testCase.m_ulExpectedMissingStats; oss << std::endl; oss << "Number of Missing Columns: " << ulMissingStats; oss << std::endl; GPOS_TRACE(str.Wsz()); eres = GPOS_FAILED; } GPOS_CHECK_ABORT; poconf->Release(); pdxlnPlan->Release(); m_ulMissingStatsTestCounter++; } if (GPOS_OK == eres) { m_ulMissingStatsTestCounter = 0; } return eres; }
//--------------------------------------------------------------------------- // @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: // PvExec // // @doc: // Function driving execution. // //--------------------------------------------------------------------------- static void * PvExec ( void *pv ) { CMainArgs *pma = (CMainArgs*) pv; CBitVector bv(ITask::Self()->Pmp(), CUnittest::UlTests()); CHAR ch = '\0'; CHAR *file_name = NULL; BOOL fMinidump = false; BOOL fUnittest = false; ULLONG ullPlanId = 0; while (pma->Getopt(&ch)) { CHAR *szTestName = NULL; switch (ch) { case 'U': szTestName = optarg; // fallthru case 'u': CUnittest::FindTest(bv, CUnittest::EttStandard, szTestName); fUnittest = true; break; case 'x': CUnittest::FindTest(bv, CUnittest::EttExtended, NULL /*szTestName*/); fUnittest = true; break; case 'T': CUnittest::SetTraceFlag(optarg); break; case 'i': ullPlanId = CUnittest::UllParsePlanId(optarg); GPOS_SET_TRACE(EopttraceEnumeratePlans); break; case 'd': fMinidump = true; file_name = optarg; break; default: // ignore other parameters break; } } if (fMinidump && fUnittest) { GPOS_TRACE(GPOS_WSZ_LIT("Cannot specify -d and -U/-u options at the same time")); return NULL; } if (fMinidump) { // initialize DXL support InitDXL(); CMDCache::Init(); CAutoMemoryPool amp; IMemoryPool *mp = amp.Pmp(); // load dump file CDXLMinidump *pdxlmd = CMinidumperUtils::PdxlmdLoad(mp, file_name); GPOS_CHECK_ABORT; COptimizerConfig *optimizer_config = pdxlmd->GetOptimizerConfig(); if (NULL == optimizer_config) { optimizer_config = COptimizerConfig::PoconfDefault(mp); } else { optimizer_config -> AddRef(); } if (ullPlanId != 0) { optimizer_config->GetEnumeratorCfg()->SetPlanId(ullPlanId); } ULONG ulSegments = CTestUtils::UlSegments(optimizer_config); CDXLNode *pdxlnPlan = CMinidumperUtils::PdxlnExecuteMinidump ( mp, file_name, ulSegments, 1 /*ulSessionId*/, 1 /*ulCmdId*/, optimizer_config, NULL /*pceeval*/ ); GPOS_DELETE(pdxlmd); optimizer_config->Release(); pdxlnPlan->Release(); CMDCache::Shutdown(); } else { GPOS_ASSERT(fUnittest); tests_failed = CUnittest::Driver(&bv); } return NULL; }