//--------------------------------------------------------------------------- // @function: // CTreeMapTest::EresUnittest_FailedPlanEnumerationTests // // @doc: // Run Minidump-based tests that fail during plan enumeration because // of large plan space // //--------------------------------------------------------------------------- GPOS_RESULT CTreeMapTest::EresUnittest_FailedPlanEnumerationTests() { CAutoMemoryPool amp; IMemoryPool *pmp = amp.Pmp(); BOOL fMatchPlans = false; BOOL fTestSpacePruning = false; #if defined(GPOS_Darwin) || defined(GPOS_Linux) // restrict plan matching to OsX and Linux to avoid arithmetic operations differences // across systems fMatchPlans = true; fTestSpacePruning = true; #endif // GPOS_Darwin || GPOS_Linux // enable plan enumeration only if we match plans CAutoTraceFlag atf1(EopttraceEnumeratePlans, fMatchPlans); // enable stats derivation for DPE CAutoTraceFlag atf2(EopttraceDeriveStatsForDPE, true /*fVal*/); const ULONG ulTests = GPOS_ARRAY_SIZE(rgszFailedPlanEnumerationTests); GPOS_RESULT eres = GPOS_OK; for (ULONG ul = 0; eres == GPOS_OK && ul < ulTests; ul++) { GPOS_TRY { eres = CTestUtils::EresRunMinidumps ( pmp, &rgszFailedPlanEnumerationTests[ul], 1, // ulTests &m_ulTestCounter, 1, // ulSessionId 1, // ulCmdId fMatchPlans, fTestSpacePruning ); } GPOS_CATCH_EX(ex) { if (GPOS_MATCH_EX(ex, CException::ExmaSystem, CException::ExmiOverflow)) { eres = GPOS_OK; GPOS_RESET_EX; } else { GPOS_RETHROW(ex); eres = GPOS_FAILED; } } GPOS_CATCH_END; } return eres; }
//--------------------------------------------------------------------------- // @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; }
//--------------------------------------------------------------------------- // @function: // CGPOptimizer::PlstmtOptimize // // @doc: // Optimize given query using GP optimizer // //--------------------------------------------------------------------------- PlannedStmt * CGPOptimizer::PplstmtOptimize ( Query *pquery, bool *pfUnexpectedFailure // output : set to true if optimizer unexpectedly failed to produce plan ) { SOptContext octx; PlannedStmt* plStmt = NULL; GPOS_TRY { plStmt = COptTasks::PplstmtOptimize(pquery, &octx, pfUnexpectedFailure); // clean up context octx.Free(octx.epinQuery, octx.epinPlStmt); } GPOS_CATCH_EX(ex) { // clone the error message before context free. CHAR* szErrorMsg = octx.CloneErrorMsg(MessageContext); // clean up context octx.Free(octx.epinQuery, octx.epinPlStmt); // Special handler for a few common user-facing errors. In particular, // we want to use the correct error code for these, in case an application // tries to do something smart with them. Also, ERRCODE_INTERNAL_ERROR // is handled specially in elog.c, and we don't want that for "normal" // application errors. if (GPOS_MATCH_EX(ex, gpdxl::ExmaDXL, gpdxl::ExmiQuery2DXLNotNullViolation)) { errstart(ERROR, ex.SzFilename(), ex.UlLine(), NULL, TEXTDOMAIN); errfinish(errcode(ERRCODE_NOT_NULL_VIOLATION), errmsg("%s", szErrorMsg)); } else if (GPOS_MATCH_EX(ex, gpdxl::ExmaDXL, gpdxl::ExmiOptimizerError) || NULL != szErrorMsg) { Assert(NULL != szErrorMsg); errstart(ERROR, ex.SzFilename(), ex.UlLine(), NULL, TEXTDOMAIN); errfinish(errcode(ERRCODE_INTERNAL_ERROR), errmsg("%s", szErrorMsg)); } else if (GPOS_MATCH_EX(ex, gpdxl::ExmaGPDB, gpdxl::ExmiGPDBError)) { PG_RE_THROW(); } else if (GPOS_MATCH_EX(ex, gpdxl::ExmaDXL, gpdxl::ExmiNoAvailableMemory)) { errstart(ERROR, ex.SzFilename(), ex.UlLine(), NULL, TEXTDOMAIN); errfinish(errcode(ERRCODE_INTERNAL_ERROR), errmsg("No available memory to allocate string buffer.")); } else if (GPOS_MATCH_EX(ex, gpdxl::ExmaDXL, gpdxl::ExmiInvalidComparisonTypeCode)) { errstart(ERROR, ex.SzFilename(), ex.UlLine(), NULL, TEXTDOMAIN); errfinish(errcode(ERRCODE_INTERNAL_ERROR), errmsg("Invalid comparison type code. Valid values are Eq, NEq, LT, LEq, GT, GEq.")); } } GPOS_CATCH_END; return plStmt; }