//--------------------------------------------------------------------------- // Greenplum Database // Copyright (C) 2009 - 2011 EMC CORP. // // @filename: // CExpression.h // // @doc: // Basic tree/DAG-based representation for an expression //--------------------------------------------------------------------------- #ifndef GPOPT_CExpression_H #define GPOPT_CExpression_H #include "gpos/base.h" #include "gpos/common/CDynamicPtrArray.h" #include "gpos/common/CRefCount.h" #include "gpos/common/DbgPrintMixin.h" #include "gpopt/base/CColRef.h" #include "gpopt/base/CCostContext.h" #include "gpopt/base/CDrvdPropRelational.h" #include "gpopt/base/CDrvdPropScalar.h" #include "gpopt/base/CKeyCollection.h" #include "gpopt/base/CPrintPrefix.h" #include "gpopt/base/CReqdProp.h" #include "gpopt/base/CReqdPropRelational.h" #include "gpopt/cost/CCost.h" #include "gpopt/operators/COperator.h" #include "naucrates/statistics/IStatistics.h" namespace gpopt { // cleanup function for arrays class CExpression; using CExpressionArray = CDynamicPtrArray; // array of arrays of expression pointers using CExpressionArrays = CDynamicPtrArray; class CGroupExpression; class CDrvdPropPlan; class CDrvdPropCtxt; class CDrvdPropCtxtPlan; class CPropConstraint; using namespace gpos; using namespace gpnaucrates; //--------------------------------------------------------------------------- // @class: // CExpression // // @doc: // Simply dynamic array for pointer types // //--------------------------------------------------------------------------- class CExpression : public CRefCount, public gpos::DbgPrintMixin { friend class CExpressionHandle; private: // memory pool CMemoryPool *m_mp; // operator class COperator *m_pop; // array of children CExpressionArray *m_pdrgpexpr; // derived relational properties CDrvdPropRelational *m_pdprel; // derived stats IStatistics *m_pstats; // required plan properties CReqdPropPlan *m_prpp; // derived physical properties CDrvdPropPlan *m_pdpplan; // derived scalar properties CDrvdPropScalar *m_pdpscalar; // group reference to Memo CGroupExpression *m_pgexpr; // cost of physical expression node when copied out of the memo CCost m_cost; // id of origin group, used for debugging expressions extracted from memo ULONG m_ulOriginGrpId; // id of origin group expression, used for debugging expressions extracted from memo ULONG m_ulOriginGrpExprId; // get expression's derived property given its type CDrvdProp *Pdp(const CDrvdProp::EPropType ept) const; #ifdef GPOS_DEBUG // assert valid property derivation void AssertValidPropDerivation(const CDrvdProp::EPropType ept); // print expression properties void PrintProperties(IOstream &os, CPrintPrefix &pfx) const; #endif // GPOS_DEBUG // check if the distributions of all children are compatible BOOL FValidChildrenDistribution(CDrvdPropCtxtPlan *pdpctxtplan); // copy group properties and stats to expression void CopyGroupPropsAndStats(IStatistics *input_stats); public: CExpression(const CExpression &) = delete; // ctor's with different arity // ctor for leaf nodes CExpression(CMemoryPool *mp, COperator *pop, CGroupExpression *pgexpr = nullptr); // ctor for unary expressions CExpression(CMemoryPool *mp, COperator *pop, CExpression *pexpr); // ctor for binary expressions CExpression(CMemoryPool *mp, COperator *pop, CExpression *pexprChildFirst, CExpression *pexprChildSecond); // ctor for ternary expressions CExpression(CMemoryPool *mp, COperator *pop, CExpression *pexprChildFirst, CExpression *pexprChildSecond, CExpression *pexprChildThird); // ctor n-ary expressions CExpression(CMemoryPool *mp, COperator *pop, CExpressionArray *pdrgpexpr); // ctor for n-ary expression with origin group expression CExpression(CMemoryPool *mp, COperator *pop, CGroupExpression *pgexpr, CExpressionArray *pdrgpexpr, CReqdPropPlan *prpp, IStatistics *input_stats, CCost cost = GPOPT_INVALID_COST); // dtor ~CExpression() override; // shorthand to access children CExpression * operator[](ULONG ulPos) const { GPOS_ASSERT(nullptr != m_pdrgpexpr); return (*m_pdrgpexpr)[ulPos]; }; // arity function ULONG Arity() const { return m_pdrgpexpr == nullptr ? 0 : m_pdrgpexpr->Size(); } // accessor for operator COperator * Pop() const { GPOS_ASSERT(nullptr != m_pop); return m_pop; } // accessor of children array CExpressionArray * PdrgPexpr() const { return m_pdrgpexpr; } // accessor for origin group expression CGroupExpression * Pgexpr() const { return m_pgexpr; } // accessor for computed required plan props CReqdPropPlan * Prpp() const { return m_prpp; } CDrvdPropRelational *GetDrvdPropRelational() const; CDrvdPropPlan *GetDrvdPropPlan() const; CDrvdPropScalar *GetDrvdPropScalar() const; // get derived statistics object const IStatistics * Pstats() const { return m_pstats; } // cost accessor CCost Cost() const { return m_cost; } // get the suitable derived property type based on operator CDrvdProp::EPropType Ept() const; // Derive all properties immediately. The suitable derived property is // determined internally. To derive properties on an on-demand bases, use // DeriveXXX() methods. CDrvdProp *PdpDerive(CDrvdPropCtxt *pdpctxt = nullptr); // derive statistics IStatistics *PstatsDerive(CReqdPropRelational *prprel, IStatisticsArray *stats_ctxt); // reset a derived property void ResetDerivedProperty(CDrvdProp::EPropType ept); // reset all derived properties void ResetDerivedProperties(); // reset expression stats void ResetStats(); // check for outer references BOOL HasOuterRefs(); // print driver IOstream &OsPrint(IOstream &os) const; // print driver, customized for expressions IOstream &OsPrintExpression(IOstream &os, const CPrintPrefix * = nullptr, BOOL fLast = true) const; // match with group expression BOOL FMatchPattern(CGroupExpression *pgexpr) const; // return a copy of the expression with remapped columns CExpression *PexprCopyWithRemappedColumns(CMemoryPool *mp, UlongToColRefMap *colref_mapping, BOOL must_exist) const; // compare entire expression rooted here BOOL Matches(CExpression *pexpr) const; // match against given pattern BOOL FMatchPattern(CExpression *pexpr) const; // match children against given pattern BOOL FMatchPatternChildren(CExpression *pexpr) const; // compare entire expression rooted here BOOL FMatchDebug(CExpression *pexpr) const; // debug print; for interactive debugging sessions only // prints expression properties as well void DbgPrintWithProperties() const; // check if the expression satisfies given required properties BOOL FValidPlan(const CReqdPropPlan *prpp, CDrvdPropCtxtPlan *pdpctxtplan); // static hash function static ULONG HashValue(const CExpression *pexpr); // static hash function static ULONG UlHashDedup(const CExpression *pexpr); // rehydrate expression from a given cost context and child expressions static CExpression *PexprRehydrate(CMemoryPool *mp, CCostContext *pcc, CExpressionArray *pdrgpexpr, CDrvdPropCtxtPlan *pdpctxtplan); // Relational property accessors - derived as needed CColRefSet *DeriveOuterReferences(); CColRefSet *DeriveOutputColumns(); CColRefSet *DeriveNotNullColumns(); CColRefSet *DeriveCorrelatedApplyColumns(); CKeyCollection *DeriveKeyCollection(); CPropConstraint *DerivePropertyConstraint(); CMaxCard DeriveMaxCard(); ULONG DeriveJoinDepth(); CFunctionProp *DeriveFunctionProperties(); CFunctionalDependencyArray *DeriveFunctionalDependencies(); CPartInfo *DerivePartitionInfo(); CTableDescriptorHashSet *DeriveTableDescriptor(); // Scalar property accessors - derived as needed CColRefSet *DeriveDefinedColumns(); CColRefSet *DeriveUsedColumns(); CColRefSet *DeriveSetReturningFunctionColumns(); BOOL DeriveHasSubquery(); CPartInfo *DeriveScalarPartitionInfo(); CFunctionProp *DeriveScalarFunctionProperties(); BOOL DeriveHasNonScalarFunction(); ULONG DeriveTotalDistinctAggs(); BOOL DeriveHasMultipleDistinctAggs(); BOOL DeriveHasScalarArrayCmp(); BOOL DeriveHasScalarFuncProject(); BOOL DeriveContainsOnlyReplicationSafeAggFuncs(); ULONG DeriveTotalOrderedAggs(); }; // class CExpression // shorthand for printing inline IOstream & operator<<(IOstream &os, CExpression &expr) { return expr.OsPrint(os); } // hash map from ULONG to expression using UlongToExprMap = CHashMap, gpos::Equals, CleanupDelete, CleanupRelease>; // map iterator using UlongToExprMapIter = CHashMapIter, gpos::Equals, CleanupDelete, CleanupRelease>; } // namespace gpopt #endif // !GPOPT_CExpression_H // EOF