//--------------------------------------------------------------------------- // @function: // CDrvdPropPlan::Derive // // @doc: // Derive plan props // //--------------------------------------------------------------------------- void CDrvdPropPlan::Derive ( IMemoryPool *pmp, CExpressionHandle &exprhdl, CDrvdPropCtxt *pdpctxt ) { CPhysical *popPhysical = CPhysical::PopConvert(exprhdl.Pop()); if (NULL != pdpctxt && COperator::EopPhysicalCTEConsumer == popPhysical->Eopid()) { CopyCTEProducerPlanProps(pmp, pdpctxt, popPhysical); } else { // call property derivation functions on the operator m_pos = popPhysical->PosDerive(pmp, exprhdl); m_pds = popPhysical->PdsDerive(pmp, exprhdl); m_prs = popPhysical->PrsDerive(pmp, exprhdl); m_ppim = popPhysical->PpimDerive(pmp, exprhdl, pdpctxt); m_ppfm = popPhysical->PpfmDerive(pmp, exprhdl); GPOS_ASSERT(NULL != m_ppim); GPOS_ASSERT(CDistributionSpec::EdtAny != m_pds->Edt() && "CDistributionAny is a require-only, cannot be derived"); } m_pcm = popPhysical->PcmDerive(pmp, exprhdl); }
//--------------------------------------------------------------------------- // @function: // CLogicalSequenceProject::FHasLocalOuterRefs // // @doc: // Return true if outer references are included in Partition/Order, // or window frame edges // //--------------------------------------------------------------------------- BOOL CLogicalSequenceProject::FHasLocalOuterRefs ( CExpressionHandle &exprhdl ) const { GPOS_ASSERT(this == exprhdl.Pop()); CColRefSet *outer_refs = CDrvdPropRelational::GetRelationalProperties(exprhdl.Pdp())->PcrsOuter(); return !(outer_refs->IsDisjoint(m_pcrsLocalUsed)); }
//--------------------------------------------------------------------------- // @function: // CXformCollapseGbAgg::Exfp // // @doc: // Compute xform promise for a given expression handle; // GbAgg must be global and have non empty grouping columns // //--------------------------------------------------------------------------- CXform::EXformPromise CXformCollapseGbAgg::Exfp ( CExpressionHandle &exprhdl ) const { CLogicalGbAgg *popAgg = CLogicalGbAgg::PopConvert(exprhdl.Pop()); if (!popAgg->FGlobal() || 0 == popAgg->Pdrgpcr()->UlLength()) { return CXform::ExfpNone; } return CXform::ExfpHigh; }
//--------------------------------------------------------------------------- // @function: // CXformPushGbBelowJoin::Exfp // // @doc: // Compute xform promise for a given expression handle; // we only push down global aggregates // //--------------------------------------------------------------------------- CXform::EXformPromise CXformPushGbBelowJoin::Exfp ( CExpressionHandle &exprhdl ) const { CLogicalGbAgg *popGbAgg = CLogicalGbAgg::PopConvert(exprhdl.Pop()); if (!popGbAgg->FGlobal()) { return CXform::ExfpNone; } return CXform::ExfpHigh; }
//--------------------------------------------------------------------------- // @function: // CXformGbAgg2Apply::Exfp // // @doc: // Compute xform promise for a given expression handle; // scalar child must have subquery // //--------------------------------------------------------------------------- CXform::EXformPromise CXformGbAgg2Apply::Exfp ( CExpressionHandle &exprhdl ) const { CLogicalGbAgg *popGbAgg = CLogicalGbAgg::PopConvert(exprhdl.Pop()); if (popGbAgg->FGlobal() && exprhdl.Pdpscalar(1)->FHasSubquery()) { return CXform::ExfpHigh; } return CXform::ExfpNone; }
//--------------------------------------------------------------------------- // @function: // CXformCTEAnchor2Sequence::Exfp // // @doc: // Compute promise of xform // //--------------------------------------------------------------------------- CXform::EXformPromise CXformCTEAnchor2Sequence::Exfp ( CExpressionHandle &exprhdl ) const { ULONG ulId = CLogicalCTEAnchor::PopConvert(exprhdl.Pop())->UlId(); const ULONG ulConsumers = COptCtxt::PoctxtFromTLS()->Pcteinfo()->UlConsumers(ulId); GPOS_ASSERT(0 < ulConsumers); if (1 == ulConsumers && CXformUtils::FInlinableCTE(ulId)) { return CXform::ExfpNone; } return CXform::ExfpHigh; }
//--------------------------------------------------------------------------- // @function: // CXformSimplifyGbAgg::Exfp // // @doc: // Compute xform promise for a given expression handle; // aggregate must have grouping columns // //--------------------------------------------------------------------------- CXform::EXformPromise CXformSimplifyGbAgg::Exfp ( CExpressionHandle &exprhdl ) const { CLogicalGbAgg *popAgg = CLogicalGbAgg::PopConvert(exprhdl.Pop()); GPOS_ASSERT(COperator::EgbaggtypeGlobal == popAgg->Egbaggtype()); if (0 == popAgg->Pdrgpcr()->UlLength() || NULL != popAgg->PdrgpcrMinimal()) { return CXform::ExfpNone; } return CXform::ExfpHigh; }
//--------------------------------------------------------------------------- // @function: // CPhysical::FChildrenHaveCompatibleDistributions // // @doc: // Returns true iff the delivered distributions of the children are // compatible among themselves. // //--------------------------------------------------------------------------- BOOL CPhysical::FCompatibleChildrenDistributions ( const CExpressionHandle &exprhdl ) const { GPOS_ASSERT(exprhdl.Pop() == this); BOOL fSingletonOrUniversalChild = false; BOOL fNotSingletonOrUniversalDistributedChild = false; const ULONG arity = exprhdl.Arity(); for (ULONG ul = 0; ul < arity; ul++) { if (!exprhdl.FScalarChild(ul)) { CDrvdPropPlan *pdpplanChild = exprhdl.Pdpplan(ul); // an operator cannot have a singleton or universal distributed child // and one distributed on multiple nodes // this assumption is safe for all current operators, but it can be // too conservative: we could allow for instance the following cases // * LeftOuterJoin (universal, distributed) // * AntiSemiJoin (universal, distributed) // These cases can be enabled if considered necessary by overriding // this function. if (CDistributionSpec::EdtUniversal == pdpplanChild->Pds()->Edt() || pdpplanChild->Pds()->FSingletonOrStrictSingleton()) { fSingletonOrUniversalChild = true; } else { fNotSingletonOrUniversalDistributedChild = true; } if (fSingletonOrUniversalChild && fNotSingletonOrUniversalDistributedChild) { return false; } } } return true; }
//--------------------------------------------------------------------------- // @function: // CXformGbAggWithMDQA2Join::Exfp // // @doc: // Compute xform promise for a given expression handle; // //--------------------------------------------------------------------------- CXform::EXformPromise CXformGbAggWithMDQA2Join::Exfp ( CExpressionHandle &exprhdl ) const { CAutoMemoryPool amp; CLogicalGbAgg *popAgg = CLogicalGbAgg::PopConvert(exprhdl.Pop()); if (COperator::EgbaggtypeGlobal == popAgg->Egbaggtype() && exprhdl.Pdpscalar(1 /*ulChildIndex*/)->FHasMultipleDistinctAggs()) { return CXform::ExfpHigh; } return CXform::ExfpNone; }
//--------------------------------------------------------------------------- // @function: // CXformGbAgg2StreamAgg::Exfp // // @doc: // Compute xform promise for a given expression handle; // grouping columns must be non-empty // //--------------------------------------------------------------------------- CXform::EXformPromise CXformGbAgg2StreamAgg::Exfp ( CExpressionHandle &exprhdl ) const { CLogicalGbAgg *popAgg = CLogicalGbAgg::PopConvert(exprhdl.Pop()); if (0 == popAgg->Pdrgpcr()->UlLength() || !CUtils::FComparisonPossible(popAgg->Pdrgpcr(), IMDType::EcmptL) || exprhdl.Pdpscalar(1 /*ulChildIndex*/)->FHasSubquery()) { // no grouping columns, or no sort operators are available for grouping columns, or // agg functions use subquery arguments return CXform::ExfpNone; } return CXform::ExfpHigh; }
//--------------------------------------------------------------------------- // @function: // CDrvdPropScalar::Derive // // @doc: // Derive scalar props // //--------------------------------------------------------------------------- void CDrvdPropScalar::Derive ( IMemoryPool *pmp, CExpressionHandle &exprhdl, CDrvdPropCtxt * // pdpctxt ) { CScalar *popScalar = CScalar::PopConvert(exprhdl.Pop()); // call derivation functions on the operator GPOS_ASSERT(NULL == m_pcrsDefined); m_pcrsDefined = popScalar->PcrsDefined(pmp, exprhdl); GPOS_ASSERT(NULL == m_pcrsSetReturningFunction); m_pcrsSetReturningFunction = popScalar->PcrsSetReturningFunction(pmp, exprhdl); GPOS_ASSERT(NULL == m_pcrsUsed); m_pcrsUsed = popScalar->PcrsUsed(pmp, exprhdl); // derive function properties m_pfp = popScalar->PfpDerive(pmp, exprhdl); // add defined and used columns of children const ULONG ulArity = exprhdl.UlArity(); for (ULONG i = 0; i < ulArity; i++) { // only propagate properties from scalar children if (exprhdl.FScalarChild(i)) { m_pcrsDefined->Union(exprhdl.Pdpscalar(i)->PcrsDefined()); m_pcrsUsed->Union(exprhdl.Pdpscalar(i)->PcrsUsed()); m_pcrsSetReturningFunction->Union(exprhdl.Pdpscalar(i)->PcrsSetReturningFunction()); } else { GPOS_ASSERT(CUtils::FSubquery(popScalar)); // parent operator is a subquery, add outer references // from its relational child as used columns m_pcrsUsed->Union(exprhdl.Pdprel(0)->PcrsOuter()); } } // derive existence of subqueries GPOS_ASSERT(!m_fHasSubquery); m_fHasSubquery = popScalar->FHasSubquery(exprhdl); if (m_fHasSubquery) { m_ppartinfo = popScalar->PpartinfoDerive(pmp, exprhdl); } else { m_ppartinfo = GPOS_NEW(pmp) CPartInfo(pmp); } m_fHasNonScalarFunction = popScalar->FHasNonScalarFunction(exprhdl); if (COperator::EopScalarProjectList == exprhdl.Pop()->Eopid()) { m_ulDistinctAggs = CScalarProjectList::UlDistinctAggs(exprhdl); m_fHasMultipleDistinctAggs = CScalarProjectList::FHasMultipleDistinctAggs(exprhdl); } if (COperator::EopScalarProjectElement == exprhdl.Pop()->Eopid()) { if (m_fHasNonScalarFunction) { CScalarProjectElement *pspeProject = (CScalarProjectElement *)(exprhdl.Pop()); m_pcrsSetReturningFunction->Include(pspeProject->Pcr()); } } }