//--------------------------------------------------------------------------- // @function: // CMDProviderTest::EresUnittest_Negative // // @doc: // Test fetching non-exiting metadata objects from a file-based provider // //--------------------------------------------------------------------------- GPOS_RESULT CMDProviderTest::EresUnittest_Negative() { CAutoMemoryPool amp(CAutoMemoryPool::ElcNone); IMemoryPool *mp = amp.Pmp(); CMDProviderMemory *pmdpFile = GPOS_NEW(mp) CMDProviderMemory(mp, file_name); pmdpFile->AddRef(); // we need to use an auto pointer for the cache here to ensure // deleting memory of cached objects when we throw CAutoP<CMDAccessor::MDCache> apcache; apcache = CCacheFactory::CreateCache<gpopt::IMDCacheObject*, gpopt::CMDKey*> ( true, // fUnique 0 /* unlimited cache quota */, CMDKey::UlHashMDKey, CMDKey::FEqualMDKey ); CMDAccessor::MDCache *pcache = apcache.Value(); { CAutoMDAccessor amda(mp, pmdpFile, CTestUtils::m_sysidDefault, pcache); // lookup a non-existing objects CMDIdGPDB *mdid = GPOS_NEW(mp) CMDIdGPDB(GPOPT_MDCACHE_TEST_OID, 15 /* major version */, 1 /* minor version */); // call should result in an exception (void) pmdpFile->GetMDObjDXLStr(mp, amda.Pmda(), mdid); } return GPOS_FAILED; }
//--------------------------------------------------------------------------- // @function: // CMiniDumperDXLTest::EresUnittest_Basic // // @doc: // Test minidumps in case of an exception // //--------------------------------------------------------------------------- GPOS_RESULT CMiniDumperDXLTest::EresUnittest_Basic() { CAutoMemoryPool amp(CAutoMemoryPool::ElcNone); IMemoryPool *mp = amp.Pmp(); CWStringDynamic minidumpstr(mp); COstreamString oss(&minidumpstr); CMiniDumperDXL mdrs(mp); mdrs.Init(&oss); CHAR file_name[GPOS_FILE_NAME_BUF_SIZE]; GPOS_TRY { CSerializableStackTrace serStackTrace; // read the dxl document CHAR *szQueryDXL = CDXLUtils::Read(mp, szQueryFile); // parse the DXL query tree from the given DXL document CQueryToDXLResult *ptroutput = CDXLUtils::ParseQueryToQueryDXLTree(mp, szQueryDXL, NULL); GPOS_CHECK_ABORT; CSerializableQuery serQuery(mp, ptroutput->CreateDXLNode(), ptroutput->GetOutputColumnsDXLArray(), ptroutput->GetCTEProducerDXLArray()); // setup a file-based provider CMDProviderMemory *pmdp = CTestUtils::m_pmdpf; pmdp->AddRef(); // we need to use an auto pointer for the cache here to ensure // deleting memory of cached objects when we throw CAutoP<CMDAccessor::MDCache> apcache; apcache = CCacheFactory::CreateCache<gpopt::IMDCacheObject*, gpopt::CMDKey*> ( true, // fUnique 0 /* unlimited cache quota */, CMDKey::UlHashMDKey, CMDKey::FEqualMDKey ); CMDAccessor::MDCache *pcache = apcache.Value(); CMDAccessor mda(mp, pcache, CTestUtils::m_sysidDefault, pmdp); CSerializableMDAccessor serMDA(&mda); CAutoTraceFlag atfPrintQuery(EopttracePrintQuery, true); CAutoTraceFlag atfPrintPlan(EopttracePrintPlan, true); CAutoTraceFlag atfTest(EtraceTest, true); COptimizerConfig *optimizer_config = GPOS_NEW(mp) COptimizerConfig ( CEnumeratorConfig::GetEnumeratorCfg(mp, 0 /*plan_id*/), CStatisticsConfig::PstatsconfDefault(mp), CCTEConfig::PcteconfDefault(mp), ICostModel::PcmDefault(mp), CHint::PhintDefault(mp), CWindowOids::GetWindowOids(mp) ); // setup opt ctx CAutoOptCtxt aoc ( mp, &mda, NULL, /* pceeval */ CTestUtils::GetCostModel(mp) ); // translate DXL Tree -> Expr Tree CTranslatorDXLToExpr *pdxltr = GPOS_NEW(mp) CTranslatorDXLToExpr(mp, &mda); CExpression *pexprTranslated = pdxltr->PexprTranslateQuery ( ptroutput->CreateDXLNode(), ptroutput->GetOutputColumnsDXLArray(), ptroutput->GetCTEProducerDXLArray() ); gpdxl::ULongPtrArray *pdrgul = pdxltr->PdrgpulOutputColRefs(); gpmd::CMDNameArray *pdrgpmdname = pdxltr->Pdrgpmdname(); ULONG ulSegments = GPOPT_TEST_SEGMENTS; CQueryContext *pqc = CQueryContext::PqcGenerate(mp, pexprTranslated, pdrgul, pdrgpmdname, true /*fDeriveStats*/); // optimize logical expression tree into physical expression tree. CEngine eng(mp); CSerializableOptimizerConfig serOptConfig(mp, optimizer_config); eng.Init(pqc, NULL /*search_stage_array*/); eng.Optimize(); CExpression *pexprPlan = eng.PexprExtractPlan(); (void) pexprPlan->PrppCompute(mp, pqc->Prpp()); // translate plan into DXL IntPtrArray *pdrgpiSegments = GPOS_NEW(mp) IntPtrArray(mp); GPOS_ASSERT(0 < ulSegments); for (ULONG ul = 0; ul < ulSegments; ul++) { pdrgpiSegments->Append(GPOS_NEW(mp) INT(ul)); } CTranslatorExprToDXL ptrexprtodxl(mp, &mda, pdrgpiSegments); CDXLNode *pdxlnPlan = ptrexprtodxl.PdxlnTranslate(pexprPlan, pqc->PdrgPcr(), pqc->Pdrgpmdname()); GPOS_ASSERT(NULL != pdxlnPlan); CSerializablePlan serPlan(mp, pdxlnPlan, optimizer_config->GetEnumeratorCfg()->GetPlanId(), optimizer_config->GetEnumeratorCfg()->GetPlanSpaceSize()); GPOS_CHECK_ABORT; // simulate an exception GPOS_OOM_CHECK(NULL); } GPOS_CATCH_EX(ex) { // unless we're simulating faults, the exception must be OOM GPOS_ASSERT_IMP ( !GPOS_FTRACE(EtraceSimulateAbort) && !GPOS_FTRACE(EtraceSimulateIOError) && !IWorker::m_enforce_time_slices, CException::ExmaSystem == ex.Major() && CException::ExmiOOM == ex.Minor() ); mdrs.Finalize(); GPOS_RESET_EX; CWStringDynamic str(mp); COstreamString oss(&str); oss << std::endl << "Minidump" << std::endl; oss << minidumpstr.GetBuffer(); oss << std::endl; // dump the same to a temp file ULONG ulSessionId = 1; ULONG ulCommandId = 1; CMinidumperUtils::GenerateMinidumpFileName(file_name, GPOS_FILE_NAME_BUF_SIZE, ulSessionId, ulCommandId, NULL /*szMinidumpFileName*/); std::wofstream osMinidump(file_name); osMinidump << minidumpstr.GetBuffer(); oss << "Minidump file: " << file_name << std::endl; GPOS_TRACE(str.GetBuffer()); } GPOS_CATCH_END; // TODO: - Feb 11, 2013; enable after fixing problems with serializing // XML special characters (OPT-2996) // // try to load minidump file // CDXLMinidump *pdxlmd = CMinidumperUtils::PdxlmdLoad(mp, file_name); // GPOS_ASSERT(NULL != pdxlmd); // delete pdxlmd; // delete temp file ioutils::Unlink(file_name); return GPOS_OK; }
//--------------------------------------------------------------------------- // @function: // CAutoTaskProxy::PtskCreate // // @doc: // Create new task; // Bind task to function and argument and associate with task and error context; // If caller is a task, its task context is cloned and used by the new task; // //--------------------------------------------------------------------------- CTask * CAutoTaskProxy::PtskCreate ( void *(*pfunc)(void*), void *pvArg, volatile BOOL *pfCancel ) { // create memory pool for task CAutoMemoryPool amp(CAutoMemoryPool::ElcStrict); IMemoryPool *pmp = amp.Pmp(); // auto pointer to hold new task context CAutoP<CTaskContext> aptc; // check if caller is a task ITask *ptskParent = CWorker::PwrkrSelf()->Ptsk(); if (NULL == ptskParent) { // create new task context aptc = GPOS_NEW(pmp) CTaskContext(pmp); } else { // clone parent task's context aptc = GPOS_NEW(pmp) CTaskContext(pmp, *ptskParent->Ptskctxt()); } // auto pointer to hold error context CAutoP<CErrorContext> apec; apec = GPOS_NEW(pmp) CErrorContext(); CTask *ptsk = CTask::PtskSelf(); if (NULL != ptsk) { apec.Pt()->Register(ptsk->PerrctxtConvert()->Pmdr()); } // auto pointer to hold new task // task is created inside ATP's memory pool CAutoP<CTask> apt; apt = GPOS_NEW(m_pmp) CTask(pmp, aptc.Pt(), apec.Pt(), &m_event, pfCancel); // reset auto pointers - task now handles task and error context (void) aptc.PtReset(); (void) apec.PtReset(); // detach task's memory pool from auto memory pool amp.PmpDetach(); // bind function and argument ptsk = apt.Pt(); ptsk->Bind(pfunc, pvArg); // add to task list m_list.Append(ptsk); // reset auto pointer - ATP now handles task apt.PtReset(); // register task to worker pool m_pwpm->RegisterTask(ptsk); return ptsk; }
//--------------------------------------------------------------------------- // @function: // CSubqueryHandlerTest::EresUnittest_SubqueryWithConstSubqueries // // @doc: // Test of subquery handler for ALL subquery over const table get // //--------------------------------------------------------------------------- GPOS_RESULT CSubqueryHandlerTest::EresUnittest_SubqueryWithConstSubqueries() { CAutoMemoryPool amp; IMemoryPool *mp = amp.Pmp(); // setup a file-based provider CMDProviderMemory *pmdp = CTestUtils::m_pmdpf; pmdp->AddRef(); // we need to use an auto pointer for the cache here to ensure // deleting memory of cached objects when we throw CAutoP<CMDAccessor::MDCache> apcache; apcache = CCacheFactory::CreateCache<gpopt::IMDCacheObject*, gpopt::CMDKey*> ( true, // fUnique 0 /* unlimited cache quota */, CMDKey::UlHashMDKey, CMDKey::FEqualMDKey ); CMDAccessor::MDCache *pcache = apcache.Value(); { CMDAccessor mda(mp, pcache, CTestUtils::m_sysidDefault, pmdp); // install opt context in TLS CAutoOptCtxt aoc ( mp, &mda, NULL, /* pceeval */ CTestUtils::GetCostModel(mp) ); // create a subquery with const table get expression CExpression *pexpr = CSubqueryTestUtils::PexprSubqueryWithDisjunction(mp); CXform *pxform = CXformFactory::Pxff()->Pxf(CXform::ExfSelect2Apply); CWStringDynamic str(mp); COstreamString oss(&str); oss << std::endl << "EXPRESSION:" << std::endl << *pexpr << std::endl; CExpression *pexprLogical = (*pexpr)[0]; CExpression *pexprScalar = (*pexpr)[1]; oss << std::endl << "LOGICAL:" << std::endl << *pexprLogical << std::endl; oss << std::endl << "SCALAR:" << std::endl << *pexprScalar << std::endl; GPOS_TRACE(str.GetBuffer()); str.Reset(); CXformContext *pxfctxt = GPOS_NEW(mp) CXformContext(mp); CXformResult *pxfres = GPOS_NEW(mp) CXformResult(mp); // calling the xform to perform subquery to Apply transformation; // xform must fail since we do not expect constant subqueries pxform->Transform(pxfctxt, pxfres, pexpr); CExpression *pexprResult = pxfres->PexprNext(); oss << std::endl << "NEW LOGICAL:" << std::endl << *((*pexprResult)[0]) << std::endl; oss << std::endl << "RESIDUAL SCALAR:" << std::endl << *((*pexprResult)[1]) << std::endl; GPOS_TRACE(str.GetBuffer()); str.Reset(); pxfres->Release(); pxfctxt->Release(); pexpr->Release(); } return GPOS_FAILED; }
//--------------------------------------------------------------------------- // @function: // gpos_exec // // @doc: // Execute function as a GPOS task using current thread; // return 0 for successful completion, 1 for error; // //--------------------------------------------------------------------------- int gpos_exec ( gpos_exec_params *params ) { // check if passed parameters are valid if (NULL == params || NULL == params->func) { return 1; } try { CWorkerPoolManager *pwpm = CWorkerPoolManager::Pwpm(); // check if worker pool is initialized if (NULL == pwpm) { return 1; } // if no stack start address is passed, use address in current stack frame void *pvStackStart = params->stack_start; if (NULL == pvStackStart) { pvStackStart = &pwpm; } // put worker to stack - main thread has id '0' CWorker wrkr(0, GPOS_WORKER_STACK_SIZE, (ULONG_PTR) pvStackStart); // scope for memory pool { // setup task memory CAutoMemoryPool amp(CAutoMemoryPool::ElcStrict); IMemoryPool *pmp = amp.Pmp(); // scope for ATP { // task handler for this process CAutoTaskProxy atp(pmp, pwpm, false/*fPropagateError*/); CTask *ptsk = atp.PtskCreate(params->func, params->arg, params->abort_requested); // init TLS ptsk->Tls().Reset(pmp); CAutoP<CWStringStatic> apwstr; CAutoP<COstreamString> aposs; CAutoP<CLoggerStream> aplogger; // use passed buffer for logging if (NULL != params->error_buffer) { GPOS_ASSERT(0 < params->error_buffer_size); apwstr = GPOS_NEW(pmp) CWStringStatic ( (WCHAR *) params->error_buffer, params->error_buffer_size / GPOS_SIZEOF(WCHAR) ); aposs = GPOS_NEW(pmp) COstreamString(apwstr.Pt()); aplogger = GPOS_NEW(pmp) CLoggerStream(*aposs.Pt()); CTaskContext *ptskctxt = ptsk->Ptskctxt(); ptskctxt->SetLogOut(aplogger.Pt()); ptskctxt->SetLogErr(aplogger.Pt()); } // execute function atp.Execute(ptsk); // export task result params->result = ptsk->PvRes(); // check for errors during execution if (CTask::EtsError == ptsk->Ets()) { return 1; } } } } catch(CException ex) { std::cerr << "Unexpected exception reached top of execution stack:" << " major=" << ex.UlMajor() << " minor=" << ex.UlMinor() << " file=" << ex.SzFilename() << " line=" << ex.UlLine() << std::endl; // unexpected failure return 1; } catch (...) { // unexpected failure return 1; } return 0; }