//--------------------------------------------------------------------------- // @function: // CXformTest::ApplyExprXforms // // @doc: // Apply different xforms for the given expression // //--------------------------------------------------------------------------- void CXformTest::ApplyExprXforms ( IMemoryPool *pmp, IOstream &os, CExpression *pexpr ) { os << std::endl << "EXPR:" << std::endl; (void) pexpr->OsPrint(os); for (ULONG ulXformId = 0; ulXformId < CXform::ExfSentinel; ulXformId++) { CXform *pxform = CXformFactory::Pxff()->Pxf((CXform::EXformId) ulXformId); os << std::endl <<"XFORM " << pxform->SzId() << ":" << std::endl; CXformContext *pxfctxt = GPOS_NEW(pmp) CXformContext(pmp); CXformResult *pxfres = GPOS_NEW(pmp) CXformResult(pmp); #ifdef GPOS_DEBUG if (pxform->FCheckPattern(pexpr) && CXform::FPromising(pmp, pxform, pexpr)) { if (CXform::ExfExpandNAryJoinMinCard == pxform->Exfid()) { GPOS_ASSERT(COperator::EopLogicalNAryJoin == pexpr->Pop()->Eopid()); // derive stats on NAry join expression CExpressionHandle exprhdl(pmp); exprhdl.Attach(pexpr); exprhdl.DeriveStats(pmp, pmp, NULL /*prprel*/, NULL /*pdrgpstatCtxt*/); } pxform->Transform(pxfctxt, pxfres, pexpr); CExpression *pexprResult = pxfres->PexprNext(); while (NULL != pexprResult) { GPOS_ASSERT(pexprResult->FMatchDebug(pexprResult)); pexprResult = pxfres->PexprNext(); } (void) pxfres->OsPrint(os); } #endif // GPOS_DEBUG pxfres->Release(); pxfctxt->Release(); } }
//--------------------------------------------------------------------------- // @function: // CSubqueryHandlerTest::EresUnittest_Subquery2Apply // // @doc: // Test of subquery handler // //--------------------------------------------------------------------------- GPOS_RESULT CSubqueryHandlerTest::EresUnittest_Subquery2Apply() { 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); typedef CExpression *(*Pfpexpr)(IMemoryPool*, BOOL); Pfpexpr rgpf[] = { CSubqueryTestUtils::PexprSelectWithAggSubquery, CSubqueryTestUtils::PexprSelectWithAggSubqueryConstComparison, CSubqueryTestUtils::PexprProjectWithAggSubquery, CSubqueryTestUtils::PexprSelectWithAnySubquery, CSubqueryTestUtils::PexprProjectWithAnySubquery, CSubqueryTestUtils::PexprSelectWithAllSubquery, CSubqueryTestUtils::PexprProjectWithAllSubquery, CSubqueryTestUtils::PexprSelectWithExistsSubquery, CSubqueryTestUtils::PexprProjectWithExistsSubquery, CSubqueryTestUtils::PexprSelectWithNotExistsSubquery, CSubqueryTestUtils::PexprProjectWithNotExistsSubquery, CSubqueryTestUtils::PexprSelectWithNestedCmpSubquery, CSubqueryTestUtils::PexprSelectWithCmpSubqueries, CSubqueryTestUtils::PexprSelectWithSubqueryConjuncts, CSubqueryTestUtils::PexprProjectWithSubqueries, CSubqueryTestUtils::PexprSelectWith2LevelsCorrSubquery, CSubqueryTestUtils::PexprJoinWithAggSubquery, CSubqueryTestUtils::PexprSelectWithAggSubqueryOverJoin, CSubqueryTestUtils::PexprSelectWithNestedSubquery, CSubqueryTestUtils::PexprSubqueriesInNullTestContext, CSubqueryTestUtils::PexprSubqueriesInDifferentContexts, CSubqueryTestUtils::PexprSelectWithSubqueryDisjuncts, CSubqueryTestUtils::PexprSelectWithNestedAnySubqueries, CSubqueryTestUtils::PexprSelectWithNestedAllSubqueries, CSubqueryTestUtils::PexprUndecorrelatableAnySubquery, CSubqueryTestUtils::PexprUndecorrelatableAllSubquery, CSubqueryTestUtils::PexprUndecorrelatableExistsSubquery, CSubqueryTestUtils::PexprUndecorrelatableNotExistsSubquery, CSubqueryTestUtils::PexprUndecorrelatableScalarSubquery, }; // xforms to test CXformSet *xform_set = GPOS_NEW(mp) CXformSet(mp); (void) xform_set->ExchangeSet(CXform::ExfSubqJoin2Apply); (void) xform_set->ExchangeSet(CXform::ExfSelect2Apply); (void) xform_set->ExchangeSet(CXform::ExfProject2Apply); BOOL fCorrelated = true; // we generate two expressions using each generator const ULONG size = 2 * GPOS_ARRAY_SIZE(rgpf); for (ULONG ul = 0; ul < size; ul++) { ULONG ulIndex = ul / 2; // install opt context in TLS CAutoOptCtxt aoc ( mp, &mda, NULL, /* pceeval */ CTestUtils::GetCostModel(mp) ); // generate expression CExpression *pexpr = rgpf[ulIndex](mp, fCorrelated); // check for subq xforms CXformSet *pxfsCand = CLogical::PopConvert(pexpr->Pop())->PxfsCandidates(mp); pxfsCand->Intersection(xform_set); CXformSetIter xsi(*pxfsCand); while (xsi.Advance()) { CXform *pxform = CXformFactory::Pxff()->Pxf(xsi.TBit()); GPOS_ASSERT(NULL != pxform); CWStringDynamic str(mp); COstreamString oss(&str); oss << std::endl << "INPUT:" << std::endl << *pexpr << std::endl; CXformContext *pxfctxt = GPOS_NEW(mp) CXformContext(mp); CXformResult *pxfres = GPOS_NEW(mp) CXformResult(mp); // calling the xform to perform subquery to Apply transformation pxform->Transform(pxfctxt, pxfres, pexpr); CExpression *pexprResult = pxfres->PexprNext(); oss << std::endl << "OUTPUT:" << std::endl; if (NULL != pexprResult) { oss << *pexprResult << std::endl; } else { oss << "\tNo subquery unnesting output" << std::endl; } GPOS_TRACE(str.GetBuffer()); str.Reset(); pxfres->Release(); pxfctxt->Release(); } pxfsCand->Release(); pexpr->Release(); fCorrelated = !fCorrelated; } xform_set->Release(); return GPOS_OK; }
//--------------------------------------------------------------------------- // @function: // CSubqueryHandlerTest::EresUnittest_SubqueryWithDisjunction // // @doc: // Test case of subqueries in a disjunctive tree // //--------------------------------------------------------------------------- GPOS_RESULT CSubqueryHandlerTest::EresUnittest_SubqueryWithDisjunction() { // use own memory pool CAutoMemoryPool amp(CAutoMemoryPool::ElcNone); IMemoryPool *mp = amp.Pmp(); // setup a file-based provider CMDProviderMemory *pmdp = CTestUtils::m_pmdpf; pmdp->AddRef(); CMDAccessor mda(mp, CMDCache::Pcache()); mda.RegisterProvider(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 *pexprOuter = NULL; CExpression *pexprInner = NULL; CSubqueryTestUtils::GenerateGetExpressions(mp, &pexprOuter, &pexprInner); CExpression *pexpr = CSubqueryTestUtils::PexprSelectWithSubqueryBoolOp(mp, pexprOuter, pexprInner, true /*fCorrelated*/, CScalarBoolOp::EboolopOr); 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 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_OK; }
//--------------------------------------------------------------------------- // @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; }