//--------------------------------------------------------------------------- // @function: // CLogical::PkcCombineKeys // // @doc: // Common case of combining keys from first n - 1 children // //--------------------------------------------------------------------------- CKeyCollection * CLogical::PkcCombineKeys ( IMemoryPool *pmp, CExpressionHandle &exprhdl ) { CColRefSet *pcrs = GPOS_NEW(pmp) CColRefSet(pmp); const ULONG ulArity = exprhdl.UlArity(); for (ULONG ul = 0; ul < ulArity - 1; ul++) { CKeyCollection *pkc = exprhdl.Pdprel(ul)->Pkc(); if (NULL == pkc) { // if a child has no key, the operator has no key pcrs->Release(); return NULL; } DrgPcr *pdrgpcr = pkc->PdrgpcrKey(pmp); pcrs->Include(pdrgpcr); pdrgpcr->Release(); } return GPOS_NEW(pmp) CKeyCollection(pmp, pcrs); }
//--------------------------------------------------------------------------- // @function: // CPhysicalAgg::PdsRequiredIntermediateAgg // // @doc: // Compute required distribution of the n-th child of an intermediate // aggregate operator // //--------------------------------------------------------------------------- CDistributionSpec * CPhysicalAgg::PdsRequiredIntermediateAgg ( IMemoryPool *pmp, ULONG ulOptReq ) const { GPOS_ASSERT(COperator::EgbaggtypeIntermediate == m_egbaggtype); if (0 == ulOptReq) { return PdsMaximalHashed(pmp, m_pdrgpcr); } DrgPcr *pdrgpcr = GPOS_NEW(pmp) DrgPcr(pmp); const ULONG ulLen = m_pdrgpcr->UlLength() - m_pdrgpcrArgDQA->UlLength(); for (ULONG ul = 0; ul < ulLen; ul++) { CColRef *pcr = (*m_pdrgpcr)[ul]; pdrgpcr->Append(pcr); } CDistributionSpec *pds = PdsMaximalHashed(pmp, pdrgpcr); pdrgpcr->Release(); return pds; }
//--------------------------------------------------------------------------- // @function: // CXformSimplifyGbAgg::FDropGbAgg // // @doc: // Return true if GbAgg operator can be dropped because grouping // columns include a key // //--------------------------------------------------------------------------- BOOL CXformSimplifyGbAgg::FDropGbAgg ( IMemoryPool *pmp, CExpression *pexpr, CXformResult *pxfres ) { CLogicalGbAgg *popAgg = CLogicalGbAgg::PopConvert(pexpr->Pop()); CExpression *pexprRelational = (*pexpr)[0]; CExpression *pexprProjectList = (*pexpr)[1]; if (0 < pexprProjectList->UlArity()) { // GbAgg cannot be dropped if Agg functions are computed return false; } CKeyCollection *pkc = CDrvdPropRelational::Pdprel(pexprRelational->PdpDerive())->Pkc(); if (NULL == pkc) { // relational child does not have key return false; } const ULONG ulKeys = pkc->UlKeys(); BOOL fDrop = false; for (ULONG ul = 0; !fDrop && ul < ulKeys; ul++) { DrgPcr *pdrgpcrKey = pkc->PdrgpcrKey(pmp, ul); CColRefSet *pcrs = GPOS_NEW(pmp) CColRefSet(pmp, pdrgpcrKey); pdrgpcrKey->Release(); CColRefSet *pcrsGrpCols = GPOS_NEW(pmp) CColRefSet(pmp); pcrsGrpCols->Include(popAgg->Pdrgpcr()); BOOL fGrpColsHasKey = pcrsGrpCols->FSubset(pcrs); pcrs->Release(); pcrsGrpCols->Release(); if (fGrpColsHasKey) { // Gb operator can be dropped pexprRelational->AddRef(); CExpression *pexprResult = CUtils::PexprLogicalSelect(pmp, pexprRelational, CPredicateUtils::PexprConjunction(pmp, NULL)); pxfres->Add(pexprResult); fDrop = true; } } return fDrop; }
//--------------------------------------------------------------------------- // @function: // CKeyCollection::PdrgpcrHashableKey // // @doc: // Extract a hashable key // //--------------------------------------------------------------------------- DrgPcr * CKeyCollection::PdrgpcrHashableKey ( IMemoryPool *pmp ) const { const ULONG ulSets = m_pdrgpcrs->UlLength(); for(ULONG ul = 0; ul < ulSets; ul++) { DrgPcr *pdrgpcrKey = (*m_pdrgpcrs)[ul]->Pdrgpcr(pmp); if (CUtils::FHashable(pdrgpcrKey)) { return pdrgpcrKey; } pdrgpcrKey->Release(); } // no hashable key is found return NULL; }
//--------------------------------------------------------------------------- // @function: // CDistributionSpecHashed::PdshashedMaximal // // @doc: // Return a hashed distribution on the maximal hashable subset of // given columns, // if all columns are not hashable, return NULL // //--------------------------------------------------------------------------- CDistributionSpecHashed * CDistributionSpecHashed::PdshashedMaximal ( IMemoryPool *pmp, DrgPcr *pdrgpcr, BOOL fNullsColocated ) { GPOS_ASSERT(NULL != pdrgpcr); GPOS_ASSERT(0 < pdrgpcr->UlLength()); DrgPcr *pdrgpcrHashable = CUtils::PdrgpcrHashableSubset(pmp, pdrgpcr); CDistributionSpecHashed *pdshashed = NULL; if (0 < pdrgpcrHashable->UlLength()) { DrgPexpr *pdrgpexpr = CUtils::PdrgpexprScalarIdents(pmp, pdrgpcrHashable); pdshashed = GPOS_NEW(pmp) CDistributionSpecHashed(pdrgpexpr, fNullsColocated); } pdrgpcrHashable->Release(); return pdshashed; }
//--------------------------------------------------------------------------- // @function: // CXformInnerApplyWithOuterKey2InnerJoin::Transform // // @doc: // Actual transformation // //--------------------------------------------------------------------------- void CXformInnerApplyWithOuterKey2InnerJoin::Transform ( CXformContext *pxfctxt, CXformResult *pxfres, CExpression *pexpr ) const { GPOS_ASSERT(NULL != pxfctxt); GPOS_ASSERT(FPromising(pxfctxt->Pmp(), this, pexpr)); GPOS_ASSERT(FCheckPattern(pexpr)); IMemoryPool *pmp = pxfctxt->Pmp(); // extract components CExpression *pexprOuter = (*pexpr)[0]; CExpression *pexprGb = (*pexpr)[1]; CExpression *pexprScalar = (*pexpr)[2]; if (0 < CLogicalGbAgg::PopConvert(pexprGb->Pop())->Pdrgpcr()->UlLength()) { // xform is not applicable if inner Gb has grouping columns return; } if (CUtils::FHasSubqueryOrApply((*pexprGb)[0])) { // Subquery/Apply must be unnested before reaching here return; } // decorrelate Gb's relational child (*pexprGb)[0]->ResetDerivedProperties(); CExpression *pexprInner = NULL; DrgPexpr *pdrgpexpr = GPOS_NEW(pmp) DrgPexpr(pmp); if (!CDecorrelator::FProcess(pmp, (*pexprGb)[0], false /*fEqualityOnly*/, &pexprInner, pdrgpexpr)) { pdrgpexpr->Release(); return; } GPOS_ASSERT(NULL != pexprInner); CExpression *pexprPredicate = CPredicateUtils::PexprConjunction(pmp, pdrgpexpr); // join outer child with Gb's decorrelated child pexprOuter->AddRef(); CExpression *pexprInnerJoin = GPOS_NEW(pmp) CExpression ( pmp, GPOS_NEW(pmp) CLogicalInnerJoin(pmp), pexprOuter, pexprInner, pexprPredicate ); // create grouping columns from the output of outer child DrgPcr *pdrgpcrKey = NULL; DrgPcr *pdrgpcr = CUtils::PdrgpcrGroupingKey(pmp, pexprOuter, &pdrgpcrKey); pdrgpcrKey->Release(); // key is not used here CLogicalGbAgg *popGbAgg = GPOS_NEW(pmp) CLogicalGbAgg(pmp, pdrgpcr, COperator::EgbaggtypeGlobal /*egbaggtype*/); CExpression *pexprPrjList = (*pexprGb)[1]; pexprPrjList->AddRef(); CExpression *pexprNewGb = GPOS_NEW(pmp) CExpression (pmp, popGbAgg, pexprInnerJoin, pexprPrjList); // add Apply predicate in a top Select node pexprScalar->AddRef(); CExpression *pexprSelect = CUtils::PexprLogicalSelect(pmp, pexprNewGb, pexprScalar); pxfres->Add(pexprSelect); }
//--------------------------------------------------------------------------- // @function: // CLogical::PpcDeriveConstraintFromTable // // @doc: // Derive constraint property from a table/index get // //--------------------------------------------------------------------------- CPropConstraint * CLogical::PpcDeriveConstraintFromTable ( IMemoryPool *pmp, const CTableDescriptor *ptabdesc, const DrgPcr *pdrgpcrOutput ) { DrgPcrs *pdrgpcrs = GPOS_NEW(pmp) DrgPcrs(pmp); DrgPcnstr *pdrgpcnstr = GPOS_NEW(pmp) DrgPcnstr(pmp); const DrgPcoldesc *pdrgpcoldesc = ptabdesc->Pdrgpcoldesc(); const ULONG ulCols = pdrgpcoldesc->UlLength(); DrgPcr *pdrgpcrNonSystem = GPOS_NEW(pmp) DrgPcr(pmp); for (ULONG ul = 0; ul < ulCols; ul++) { CColumnDescriptor *pcoldesc = (*pdrgpcoldesc)[ul]; CColRef *pcr = (*pdrgpcrOutput)[ul]; // we are only interested in non-system columns that are defined as // being NOT NULL if (pcoldesc->FSystemColumn()) { continue; } pdrgpcrNonSystem->Append(pcr); if (pcoldesc->FNullable()) { continue; } // add a "not null" constraint and an equivalence class CConstraint * pcnstr = CConstraintInterval::PciUnbounded(pmp, pcr, false /*fIncludesNull*/); if (pcnstr == NULL) { continue; } pdrgpcnstr->Append(pcnstr); CColRefSet *pcrsEquiv = GPOS_NEW(pmp) CColRefSet(pmp); pcrsEquiv->Include(pcr); pdrgpcrs->Append(pcrsEquiv); } CMDAccessor *pmda = COptCtxt::PoctxtFromTLS()->Pmda(); const IMDRelation *pmdrel = pmda->Pmdrel(ptabdesc->Pmdid()); const ULONG ulCheckConstraint = pmdrel->UlCheckConstraints(); for (ULONG ul = 0; ul < ulCheckConstraint; ul++) { IMDId *pmdidCheckConstraint = pmdrel->PmdidCheckConstraint(ul); const IMDCheckConstraint *pmdCheckConstraint = pmda->Pmdcheckconstraint(pmdidCheckConstraint); // extract the check constraint expression CExpression *pexprCheckConstraint = pmdCheckConstraint->Pexpr(pmp, pmda, pdrgpcrNonSystem); GPOS_ASSERT(NULL != pexprCheckConstraint); GPOS_ASSERT(CUtils::FPredicate(pexprCheckConstraint)); DrgPcrs *pdrgpcrsChild = NULL; CConstraint *pcnstr = CConstraint::PcnstrFromScalarExpr(pmp, pexprCheckConstraint, &pdrgpcrsChild); if (NULL != pcnstr) { pdrgpcnstr->Append(pcnstr); // merge with the equivalence classes we have so far DrgPcrs *pdrgpcrsMerged = CUtils::PdrgpcrsMergeEquivClasses(pmp, pdrgpcrs, pdrgpcrsChild); pdrgpcrs->Release(); pdrgpcrs = pdrgpcrsMerged; } CRefCount::SafeRelease(pdrgpcrsChild); pexprCheckConstraint->Release(); } pdrgpcrNonSystem->Release(); return GPOS_NEW(pmp) CPropConstraint(pmp, pdrgpcrs, CConstraint::PcnstrConjunction(pmp, pdrgpcnstr)); }