//--------------------------------------------------------------------------- // Greenplum Database // Copyright (C) 2011 EMC Corp. // // @filename: // CJobGroupExpressionOptimization.h // // @doc: // Explore group expression job //--------------------------------------------------------------------------- #ifndef GPOPT_CJobGroupExpressionOptimization_H #define GPOPT_CJobGroupExpressionOptimization_H #include "gpos/base.h" #include "gpopt/base/COptimizationContext.h" #include "gpopt/search/CJobGroupExpression.h" #include "gpopt/search/CJobStateMachine.h" namespace gpopt { using namespace gpos; // prototypes class CCostContext; //--------------------------------------------------------------------------- // @class: // CJobGroupExpressionOptimization // // @doc: // Group expression optimization job // // Responsible for finding the best plan rooted by a given group // expression, such that the identified plan satisfies given required plan // properties. Note that a group optimization job entails running a group // expression optimization job for each group expression in the underlying // group. // //--------------------------------------------------------------------------- class CJobGroupExpressionOptimization : public CJobGroupExpression { public: // transition events of group expression optimization enum EEvent { eevOptimizingChildren, // child groups optimization is in progress eevChildrenOptimized, // done with children optimization eevCheckingEnfdProps, // check enforceable properties eevOptimizingSelf, // cost computation is in progress eevSelfOptimized, // done with costing group expression eevFinalized, // done with optimization eevSentinel }; // states of group expression optimization enum EState { estInitialized = 0, // initial state estOptimizingChildren, // child groups are under optimization estChildrenOptimized, // child groups are optimized estEnfdPropsChecked, // enforceable properties are checked estSelfOptimized, // group expression cost is computed estCompleted, // done optimization estSentinel }; private: // shorthand for job state machine using JSM = CJobStateMachine; // job state machine JSM m_jsm; // optimization context of the job COptimizationContext *m_poc; // optimization request number ULONG m_ulOptReq; // array of child groups optimization contexts COptimizationContextArray *m_pdrgpoc; // stats context to be used during costing IStatisticsArray *m_pdrgpstatCurrentCtxt; // array of derived properties of optimal implementations of child groups CDrvdPropArray *m_pdrgpdp; // optimization order of children CPhysical::EChildExecOrder m_eceo; // counter of next child group to be optimized ULONG m_ulChildIndex; // number of children ULONG m_ulArity; // flag to indicate if optimizing a child has failed BOOL m_fChildOptimizationFailed; // flag to indicate if current job optimizes a Sequence operator that captures a CTE BOOL m_fOptimizeCTESequence; // plan properties required from CTE producer based on consumer derived plan properties CReqdPropPlan *m_prppCTEProducer; // flag to indicate if a child job for optimizing CTE has been scheduled BOOL m_fScheduledCTEOptimization; // a handle object for required plan properties computation CExpressionHandle *m_pexprhdlPlan; // a handle object for required relational property computation CExpressionHandle *m_pexprhdlRel; // initialization routine for child groups optimization void InitChildGroupsOptimization(CSchedulerContext *psc); // derive plan properties and stats of the child previous to the one being optimized void DerivePrevChildProps(CSchedulerContext *psc); // compute required plan properties for current child void ComputeCurrentChildRequirements(CSchedulerContext *psc); // initialize action static EEvent EevtInitialize(CSchedulerContext *psc, CJob *pj); // optimize child groups action static EEvent EevtOptimizeChildren(CSchedulerContext *psc, CJob *pj); // add enforcers to the owning group static EEvent EevtAddEnforcers(CSchedulerContext *psc, CJob *pj); // optimize group expression action static EEvent EevtOptimizeSelf(CSchedulerContext *psc, CJob *pj); // finalize action static EEvent EevtFinalize(CSchedulerContext *psc, CJob *pj); // schedule a new group expression optimization job for CTE optimization static BOOL FScheduleCTEOptimization(CSchedulerContext *psc, CGroupExpression *pgexpr, COptimizationContext *poc, ULONG ulOptReq, CJob *pjParent); protected: // schedule transformation jobs for applicable xforms void ScheduleApplicableTransformations(CSchedulerContext * // psc ) override { // no transformations are applicable to this job } // schedule optimization jobs for all child groups void ScheduleChildGroupsJobs(CSchedulerContext *psc) override; public: CJobGroupExpressionOptimization(const CJobGroupExpressionOptimization &) = delete; // ctor CJobGroupExpressionOptimization(); // dtor ~CJobGroupExpressionOptimization() override; // initialize job void Init(CGroupExpression *pgexpr, COptimizationContext *poc, ULONG ulOptReq, CReqdPropPlan *prppCTEProducer = nullptr); // cleanup internal state void Cleanup() override; // schedule a new group expression optimization job static void ScheduleJob(CSchedulerContext *psc, CGroupExpression *pgexpr, COptimizationContext *poc, ULONG ulOptReq, CJob *pjParent); // job's function BOOL FExecute(CSchedulerContext *psc) override; #ifdef GPOS_DEBUG // print function IOstream &OsPrint(IOstream &os) const override; // dump state machine diagram in graphviz format virtual IOstream & OsDiagramToGraphviz(CMemoryPool *mp, IOstream &os, const WCHAR *wszTitle) const { (void) m_jsm.OsDiagramToGraphviz(mp, os, wszTitle); return os; } // compute unreachable states void Unreachable(CMemoryPool *mp, EState **ppestate, ULONG *pulSize) const { m_jsm.Unreachable(mp, ppestate, pulSize); } #endif // GPOS_DEBUG // conversion function static CJobGroupExpressionOptimization * PjConvert(CJob *pj) { GPOS_ASSERT(nullptr != pj); GPOS_ASSERT(EjtGroupExpressionOptimization == pj->Ejt()); return dynamic_cast(pj); } }; // class CJobGroupExpressionOptimization } // namespace gpopt #endif // !GPOPT_CJobGroupExpressionOptimization_H // EOF