//--------------------------------------------------------------------------- // @function: // CCNFConverter::Pdrgpdrgpexpr // // @doc: // Create an array of arrays each holding the children of an expression // from the given array // // //--------------------------------------------------------------------------- DrgPdrgPexpr * CCNFConverter::Pdrgpdrgpexpr ( IMemoryPool *pmp, DrgPexpr *pdrgpexpr ) { GPOS_ASSERT(NULL != pmp); GPOS_ASSERT(NULL != pdrgpexpr); DrgPdrgPexpr *pdrgpdrgpexpr = GPOS_NEW(pmp) DrgPdrgPexpr(pmp); const ULONG ulArity = pdrgpexpr->UlLength(); for (ULONG ul = 0; ul < ulArity; ul++) { CExpression *pexpr = (*pdrgpexpr)[ul]; DrgPexpr *pdrgpexprChild = NULL; if (CPredicateUtils::FAnd(pexpr)) { pdrgpexprChild = pexpr->PdrgPexpr(); pdrgpexprChild->AddRef(); } else { pdrgpexprChild = GPOS_NEW(pmp) DrgPexpr(pmp); pexpr->AddRef(); pdrgpexprChild->Append(pexpr); } pdrgpdrgpexpr->Append(pdrgpexprChild); } return pdrgpdrgpexpr; }
void CDistributionSpecHashedNoOp::AppendEnforcers ( IMemoryPool *pmp, CExpressionHandle &exprhdl, CReqdPropPlan *, DrgPexpr *pdrgpexpr, CExpression *pexpr ) { CDrvdProp *pdp = exprhdl.Pdp(); CDistributionSpec *pdsChild = CDrvdPropPlan::Pdpplan(pdp)->Pds(); CDistributionSpecHashed *pdsChildHashed = dynamic_cast<CDistributionSpecHashed *>(pdsChild); if (NULL == pdsChildHashed) { return; } DrgPexpr *pdrgpexprNoOpRedistributionColumns = pdsChildHashed->Pdrgpexpr(); pdrgpexprNoOpRedistributionColumns->AddRef(); CDistributionSpecHashedNoOp* pdsNoOp = GPOS_NEW(pmp) CDistributionSpecHashedNoOp(pdrgpexprNoOpRedistributionColumns); pexpr->AddRef(); CExpression *pexprMotion = GPOS_NEW(pmp) CExpression ( pmp, GPOS_NEW(pmp) CPhysicalMotionHashDistribute(pmp, pdsNoOp), pexpr ); pdrgpexpr->Append(pexprMotion); }
//--------------------------------------------------------------------------- // @function: // CStatsPredUtils::PdrgpstatsjoinExtract // // @doc: // Helper function to extract array of statistics join filter // from an array of join predicates // //--------------------------------------------------------------------------- DrgPstatsjoin * CStatsPredUtils::PdrgpstatsjoinExtract ( IMemoryPool *pmp, CExpression *pexprScalar, DrgPcrs *pdrgpcrsOutput, // array of output columns of join's relational inputs CColRefSet *pcrsOuterRefs, CStatsPred **ppstatspredUnsupported ) { GPOS_ASSERT(NULL != pexprScalar); GPOS_ASSERT(NULL != pdrgpcrsOutput); DrgPstatsjoin *pdrgpstatsjoin = GPOS_NEW(pmp) DrgPstatsjoin(pmp); DrgPexpr *pdrgpexprUnsupported = GPOS_NEW(pmp) DrgPexpr(pmp); // extract all the conjuncts DrgPexpr *pdrgpexprConjuncts = CPredicateUtils::PdrgpexprConjuncts(pmp, pexprScalar); const ULONG ulSize = pdrgpexprConjuncts->UlLength(); for (ULONG ul = 0; ul < ulSize; ul++) { CExpression *pexprPred = (*pdrgpexprConjuncts) [ul]; CStatisticsJoin *pstatsjoin = PstatsjoinExtract ( pmp, pexprPred, pdrgpcrsOutput, pcrsOuterRefs, pdrgpexprUnsupported ); if (NULL != pstatsjoin) { pdrgpstatsjoin->Append(pstatsjoin); } } const ULONG ulUnsupported = pdrgpexprUnsupported->UlLength(); if (1 == ulUnsupported) { *ppstatspredUnsupported = CStatsPredUtils::PstatspredExtract(pmp, (*pdrgpexprUnsupported)[0], pcrsOuterRefs); } else if (1 < ulUnsupported) { pdrgpexprUnsupported->AddRef(); CExpression *pexprConj = CPredicateUtils::PexprConjDisj(pmp, pdrgpexprUnsupported, true /* fConjunction */); *ppstatspredUnsupported = CStatsPredUtils::PstatspredExtract(pmp, pexprConj, pcrsOuterRefs); pexprConj->Release(); } // clean up pdrgpexprUnsupported->Release(); pdrgpexprConjuncts->Release(); return pdrgpstatsjoin; }
//--------------------------------------------------------------------------- // @function: // CPhysicalHashJoin::CreateHashRedistributeRequests // // @doc: // Create the set of redistribute requests to send to first // hash join child // //--------------------------------------------------------------------------- void CPhysicalHashJoin::CreateHashRedistributeRequests ( IMemoryPool *pmp ) { GPOS_ASSERT(NULL == m_pdrgpdsRedistributeRequests); GPOS_ASSERT(NULL != m_pdrgpexprOuterKeys); GPOS_ASSERT(NULL != m_pdrgpexprInnerKeys); DrgPexpr *pdrgpexpr = NULL; if (EceoRightToLeft == Eceo()) { pdrgpexpr = m_pdrgpexprInnerKeys; } else { pdrgpexpr = m_pdrgpexprOuterKeys; } m_pdrgpdsRedistributeRequests = GPOS_NEW(pmp) DrgPds(pmp); const ULONG ulExprs = std::min((ULONG) GPOPT_MAX_HASH_DIST_REQUESTS, pdrgpexpr->UlLength()); if (1 < ulExprs) { for (ULONG ul = 0; ul < ulExprs; ul++) { DrgPexpr *pdrgpexprCurrent = GPOS_NEW(pmp) DrgPexpr(pmp); CExpression *pexpr = (*pdrgpexpr)[ul]; pexpr->AddRef(); pdrgpexprCurrent->Append(pexpr); // add a separate request for each hash join key // TODO: - Dec 30, 2011; change fNullsColocated to false when our // distribution matching can handle differences in NULL colocation CDistributionSpecHashed *pdshashedCurrent = GPOS_NEW(pmp) CDistributionSpecHashed(pdrgpexprCurrent, true /* fNullsCollocated */); m_pdrgpdsRedistributeRequests->Append(pdshashedCurrent); } } // add a request that contains all hash join keys pdrgpexpr->AddRef(); CDistributionSpecHashed *pdshashed = GPOS_NEW(pmp) CDistributionSpecHashed(pdrgpexpr, true /* fNullsCollocated */); m_pdrgpdsRedistributeRequests->Append(pdshashed); }
//--------------------------------------------------------------------------- // @function: // CJoinOrderTest::EresUnittest_ExpandMinCard // // @doc: // Expansion expansion based on cardinality of intermediate results // //--------------------------------------------------------------------------- GPOS_RESULT CJoinOrderTest::EresUnittest_ExpandMinCard() { CAutoMemoryPool amp; IMemoryPool *pmp = amp.Pmp(); // array of relation names CWStringConst rgscRel[] = { GPOS_WSZ_LIT("Rel10"), GPOS_WSZ_LIT("Rel3"), GPOS_WSZ_LIT("Rel4"), GPOS_WSZ_LIT("Rel6"), GPOS_WSZ_LIT("Rel7"), GPOS_WSZ_LIT("Rel8"), GPOS_WSZ_LIT("Rel12"), GPOS_WSZ_LIT("Rel13"), GPOS_WSZ_LIT("Rel5"), GPOS_WSZ_LIT("Rel14"), GPOS_WSZ_LIT("Rel15"), GPOS_WSZ_LIT("Rel1"), GPOS_WSZ_LIT("Rel11"), GPOS_WSZ_LIT("Rel2"), GPOS_WSZ_LIT("Rel9"), }; // array of relation IDs ULONG rgulRel[] = { GPOPT_TEST_REL_OID10, GPOPT_TEST_REL_OID3, GPOPT_TEST_REL_OID4, GPOPT_TEST_REL_OID6, GPOPT_TEST_REL_OID7, GPOPT_TEST_REL_OID8, GPOPT_TEST_REL_OID12, GPOPT_TEST_REL_OID13, GPOPT_TEST_REL_OID5, GPOPT_TEST_REL_OID14, GPOPT_TEST_REL_OID15, GPOPT_TEST_REL_OID1, GPOPT_TEST_REL_OID11, GPOPT_TEST_REL_OID2, GPOPT_TEST_REL_OID9, }; const ULONG ulRels = GPOS_ARRAY_SIZE(rgscRel); GPOS_ASSERT(GPOS_ARRAY_SIZE(rgulRel) == ulRels); // setup a file-based provider CMDProviderMemory *pmdp = CTestUtils::m_pmdpf; pmdp->AddRef(); CMDAccessor mda(pmp, CMDCache::Pcache()); mda.RegisterProvider(CTestUtils::m_sysidDefault, pmdp); { // install opt context in TLS CAutoOptCtxt aoc ( pmp, &mda, NULL, /* pceeval */ CTestUtils::Pcm(pmp) ); CExpression *pexprNAryJoin = CTestUtils::PexprLogicalNAryJoin(pmp, rgscRel, rgulRel, ulRels, false /*fCrossProduct*/); // derive stats on input expression CExpressionHandle exprhdl(pmp); exprhdl.Attach(pexprNAryJoin); exprhdl.DeriveStats(pmp, pmp, NULL /*prprel*/, NULL /*pdrgpstatCtxt*/); DrgPexpr *pdrgpexpr = GPOS_NEW(pmp) DrgPexpr(pmp); for (ULONG ul = 0; ul < ulRels; ul++) { CExpression *pexprChild = (*pexprNAryJoin)[ul]; pexprChild->AddRef(); pdrgpexpr->Append(pexprChild); } DrgPexpr *pdrgpexprPred = CPredicateUtils::PdrgpexprConjuncts(pmp, (*pexprNAryJoin)[ulRels]); pdrgpexpr->AddRef(); pdrgpexprPred->AddRef(); CJoinOrderMinCard jomc(pmp, pdrgpexpr, pdrgpexprPred); CExpression *pexprResult = jomc.PexprExpand(); { CAutoTrace at(pmp); at.Os() << std::endl << "INPUT:" << std::endl << *pexprNAryJoin << std::endl; at.Os() << std::endl << "OUTPUT:" << std::endl << *pexprResult << std::endl; } pexprResult->Release(); pexprNAryJoin->Release(); pdrgpexpr->Release(); pdrgpexprPred->Release(); } return GPOS_OK; }
//--------------------------------------------------------------------------- // @function: // CNormalizer::PushThruOuterChild // // @doc: // Push scalar expression through left outer join children; // this only handles the case of a SELECT on top of LEFT OUTER JOIN; // pushing down join predicates is handled in PushThruJoin(); // here, we push predicates of the top SELECT node through LEFT OUTER JOIN's // outer child // //--------------------------------------------------------------------------- void CNormalizer::PushThruOuterChild ( IMemoryPool *pmp, CExpression *pexpr, CExpression *pexprConj, CExpression **ppexprResult ) { GPOS_ASSERT(NULL != pexpr); GPOS_ASSERT(FPushThruOuterChild(pexpr)); GPOS_ASSERT(NULL != pexprConj); GPOS_ASSERT(NULL != ppexprResult); if (0 == pexpr->UlArity()) { // end recursion early for leaf patterns extracted from memo pexpr->AddRef(); pexprConj->AddRef(); *ppexprResult = CUtils::PexprSafeSelect(pmp, pexpr, pexprConj); return; } CExpression *pexprOuter = (*pexpr)[0]; CExpression *pexprInner = (*pexpr)[1]; CExpression *pexprPred = (*pexpr)[2]; DrgPexpr *pdrgpexprPushable = NULL; DrgPexpr *pdrgpexprUnpushable = NULL; SplitConjunct(pmp, pexprOuter, pexprConj, &pdrgpexprPushable, &pdrgpexprUnpushable); if (0 < pdrgpexprPushable->UlLength()) { pdrgpexprPushable->AddRef(); CExpression *pexprNewConj = CPredicateUtils::PexprConjunction(pmp, pdrgpexprPushable); // create a new select node on top of the outer child pexprOuter->AddRef(); CExpression *pexprNewSelect = GPOS_NEW(pmp) CExpression(pmp, GPOS_NEW(pmp) CLogicalSelect(pmp), pexprOuter, pexprNewConj); // push predicate through the new select to create a new outer child CExpression *pexprNewOuter = NULL; PushThru(pmp, pexprNewSelect, pexprNewConj, &pexprNewOuter); pexprNewSelect->Release(); // create a new outer join using the new outer child and the new inner child COperator *pop = pexpr->Pop(); pop->AddRef(); pexprInner->AddRef(); pexprPred->AddRef(); CExpression *pexprNew = GPOS_NEW(pmp) CExpression(pmp, pop, pexprNewOuter, pexprInner, pexprPred); // call push down predicates on the new outer join CExpression *pexprConstTrue = CUtils::PexprScalarConstBool(pmp, true /*fVal*/); PushThru(pmp, pexprNew, pexprConstTrue, ppexprResult); pexprConstTrue->Release(); pexprNew->Release(); } if (0 < pdrgpexprUnpushable->UlLength()) { CExpression *pexprOuterJoin = pexpr; if (0 < pdrgpexprPushable->UlLength()) { pexprOuterJoin = *ppexprResult; GPOS_ASSERT(NULL != pexprOuterJoin); } // call push down on the outer join predicates CExpression *pexprNew = NULL; CExpression *pexprConstTrue = CUtils::PexprScalarConstBool(pmp, true /*fVal*/); PushThru(pmp, pexprOuterJoin, pexprConstTrue, &pexprNew); if (pexprOuterJoin != pexpr) { pexprOuterJoin->Release(); } pexprConstTrue->Release(); // create a SELECT on top of the new outer join pdrgpexprUnpushable->AddRef(); *ppexprResult = PexprSelect(pmp, pexprNew, pdrgpexprUnpushable); } pdrgpexprPushable->Release(); pdrgpexprUnpushable->Release(); }