//--------------------------------------------------------------------------- // Greenplum Database // Copyright (C) 2011 EMC Corp. // // @filename: // CDistributionSpecHashed.h // // @doc: // Description of a hashed distribution; // Can be used as required or derived property; //--------------------------------------------------------------------------- #ifndef GPOPT_CDistributionSpecHashed_H #define GPOPT_CDistributionSpecHashed_H #include "gpos/base.h" #include "gpopt/base/CColRef.h" #include "gpopt/base/CDistributionSpecRandom.h" namespace gpopt { using namespace gpos; //--------------------------------------------------------------------------- // @class: // CDistributionSpecHashed // // @doc: // Class for representing hashed distribution specification. // //--------------------------------------------------------------------------- class CDistributionSpecHashed : public CDistributionSpecRandom { private: // array of distribution expressions CExpressionArray *m_pdrgpexpr; IMdIdArray *m_opfamilies; // are NULLS consistently distributed BOOL m_fNullsColocated; // equivalent hashed distribution introduced by a hash join CDistributionSpecHashed *m_pdshashedEquiv; // array of expression arrays, an array at position n // is the list of expression which are equivalent to the distribution expr // at position n in m_pdrgpexpr array. CExpressionArrays *m_equiv_hash_exprs; // check if specs are compatible wrt to co-location of nulls; // HD1 satisfies HD2 if: // * HD1 colocates NULLs or // * HD2 doesn't care about NULLs BOOL FNullsColocatedCompatible(const CDistributionSpecHashed *pds) const { return (m_fNullsColocated || !pds->m_fNullsColocated); } // check if specs are compatible wrt to duplicate sensitivity // HD1 satisfies HD2 if: // * HD1 is duplicate sensitive, or // * HD2 doesn't care about duplicates BOOL FDuplicateSensitiveCompatible(const CDistributionSpecHashed *pds) const { return (m_is_duplicate_sensitive || !pds->m_is_duplicate_sensitive); } public: CDistributionSpecHashed(const CDistributionSpecHashed &) = delete; // ctor CDistributionSpecHashed(CExpressionArray *pdrgpexpr, BOOL fNullsColocated, IMdIdArray *opfamilies = nullptr); // ctor CDistributionSpecHashed(CExpressionArray *pdrgpexpr, BOOL fNullsColocated, CDistributionSpecHashed *pdshashedEquiv, IMdIdArray *opfamilies = nullptr); static CDistributionSpecHashed *MakeHashedDistrSpec( CMemoryPool *mp, CExpressionArray *pdrgpexpr, BOOL fNullsColocated, CDistributionSpecHashed *pdshashedEquiv, IMdIdArray *opfamilies); // dtor ~CDistributionSpecHashed() override; void PopulateDefaultOpfamilies(); // distribution type accessor EDistributionType Edt() const override { return CDistributionSpec::EdtHashed; } const CHAR * SzId() const override { return "HASHED"; } // expression array accessor CExpressionArray * Pdrgpexpr() const { return m_pdrgpexpr; } // is distribution nulls colocated BOOL FNullsColocated() const { return m_fNullsColocated; } // equivalent hashed distribution CDistributionSpecHashed * PdshashedEquiv() const { return m_pdshashedEquiv; } IMdIdArray * Opfamilies() const { return m_opfamilies; } // columns used by distribution expressions CColRefSet *PcrsUsed(CMemoryPool *mp) const override; // return a copy of the distribution spec after excluding the given columns virtual CDistributionSpecHashed *PdshashedExcludeColumns(CMemoryPool *mp, CColRefSet *pcrs); // exact match against given hashed distribution BOOL FMatchHashedDistribution( const CDistributionSpecHashed *pdshashed) const; // does this distribution match the given one BOOL Matches(const CDistributionSpec *pds) const override; // does this distribution satisfy the given one BOOL FSatisfies(const CDistributionSpec *pds) const override; // check if the columns of passed spec match a subset of the // object's columns BOOL FMatchSubset(const CDistributionSpecHashed *pds) const; // equality function BOOL Equals(const CDistributionSpec *pds) const override; // return a copy of the distribution spec with remapped columns CDistributionSpec *PdsCopyWithRemappedColumns( CMemoryPool *mp, UlongToColRefMap *colref_mapping, BOOL must_exist) override; // strip off any equivalent columns embedded in the distribution spec CDistributionSpec *StripEquivColumns(CMemoryPool *) override; // append enforcers to dynamic array for the given plan properties void AppendEnforcers(CMemoryPool *mp, CExpressionHandle &exprhdl, CReqdPropPlan *prpp, CExpressionArray *pdrgpexpr, CExpression *pexpr) override; // hash function for hashed distribution spec ULONG HashValue() const override; // return distribution partitioning type EDistributionPartitioningType Edpt() const override { return EdptPartitioned; } // print IOstream &OsPrint(IOstream &os) const override; IOstream &OsPrintWithPrefix(IOstream &os, const char *prefix) const; // return a hashed distribution on the maximal hashable subset of given columns static CDistributionSpecHashed *PdshashedMaximal(CMemoryPool *mp, CColRefArray *colref_array, BOOL fNullsColocated); // conversion function static CDistributionSpecHashed * PdsConvert(CDistributionSpec *pds) { GPOS_ASSERT(nullptr != pds); CDistributionSpecHashed *pdsHashed = dynamic_cast(pds); GPOS_ASSERT(nullptr != pdsHashed); return pdsHashed; } // conversion function: const argument static const CDistributionSpecHashed * PdsConvert(const CDistributionSpec *pds) { GPOS_ASSERT(nullptr != pds); const CDistributionSpecHashed *pdsHashed = dynamic_cast(pds); GPOS_ASSERT(nullptr != pdsHashed); return pdsHashed; } CExpressionArrays * HashSpecEquivExprs() const { return m_equiv_hash_exprs; } void ComputeEquivHashExprs(CMemoryPool *mp, CExpressionHandle &expression_handle); // does the current spec or equivalent spec cover the input expression array BOOL IsCoveredBy(const CExpressionArray *dist_cols_expr_array) const; // create a copy of the distribution spec CDistributionSpecHashed *Copy(CMemoryPool *mp); // create a copy of the distribution spec with given nulls colocated value CDistributionSpecHashed *Copy(CMemoryPool *mp, BOOL fNullsColocated); // get distribution expr array from the current and its equivalent spec CExpressionArrays *GetAllDistributionExprs(CMemoryPool *mp); // return a new spec created by merging the current with the input spec CDistributionSpecHashed *Combine(CMemoryPool *mp, CDistributionSpecHashed *other_spec); // check if the equivalent spec (if any) has no matching columns with the main spec BOOL HasCompleteEquivSpec(CMemoryPool *mp) const; // use given predicates to complete an incomplete spec, if possible static CDistributionSpecHashed *TryToCompleteEquivSpec( CMemoryPool *mp, CDistributionSpecHashed *pdshashed, CExpression *pexprPred, CColRefSet *outerRefs); }; // class CDistributionSpecHashed } // namespace gpopt #endif // !GPOPT_CDistributionSpecHashed_H // EOF