//--------------------------------------------------------------------------- // @function: // CPhysicalPartitionSelector::EpetDistribution // // @doc: // Return the enforcing type for distribution property based on this operator // //--------------------------------------------------------------------------- CEnfdProp::EPropEnforcingType CPhysicalPartitionSelector::EpetDistribution ( CExpressionHandle &exprhdl, const CEnfdDistribution *ped ) const { CDrvdPropPlan *pdpplan = exprhdl.Pdpplan(0 /* child_index */); if (ped->FCompatible(pdpplan->Pds())) { // required distribution established by the operator return CEnfdProp::EpetUnnecessary; } CPartIndexMap *ppimDrvd = pdpplan->Ppim(); if (!ppimDrvd->Contains(m_scan_id)) { // part consumer is defined above: prohibit adding a motion on top of the // part resolver as this will create two slices return CEnfdProp::EpetProhibited; } GPOS_ASSERT(CPartIndexMap::EpimConsumer == ppimDrvd->Epim(m_scan_id)); // part consumer found below: enforce distribution on top of part resolver return CEnfdProp::EpetRequired; }
//--------------------------------------------------------------------------- // @function: // CPhysicalUnionAll::AssertValidChildDistributions // // @doc: // Helper to validate child distributions // //--------------------------------------------------------------------------- void CPhysicalUnionAll::AssertValidChildDistributions ( IMemoryPool *pmp, CExpressionHandle &exprhdl, CDistributionSpec::EDistributionType *pedt, // array of distribution types to check ULONG ulDistrs, // number of distribution types to check const CHAR *szAssertMsg ) { const ULONG ulArity = exprhdl.UlArity(); for (ULONG ulChild = 0; ulChild < ulArity; ulChild++) { CDistributionSpec *pdsChild = exprhdl.Pdpplan(ulChild)->Pds(); CDistributionSpec::EDistributionType edtChild = pdsChild->Edt(); BOOL fMatch = false; for (ULONG ulDistr = 0; !fMatch && ulDistr < ulDistrs; ulDistr++) { fMatch = (pedt[ulDistr] == edtChild); } if (!fMatch) { CAutoTrace at(pmp); at.Os() << szAssertMsg; } GPOS_ASSERT(fMatch); } }
//--------------------------------------------------------------------------- // @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; }