greenplumn CJobGroupExpressionOptimization 源码
greenplumn CJobGroupExpressionOptimization 代码
文件路径:/src/backend/gporca/libgpopt/src/search/CJobGroupExpressionOptimization.cpp
//---------------------------------------------------------------------------
// Greenplum Database
// Copyright (C) 2011 Greenplum, Inc.
//
// @filename:
// CJobGroupExpressionOptimization.cpp
//
// @doc:
// Implementation of group expression optimization job
//---------------------------------------------------------------------------
#include "gpopt/search/CJobGroupExpressionOptimization.h"
#include "gpopt/base/CCostContext.h"
#include "gpopt/base/CDrvdPropCtxtPlan.h"
#include "gpopt/base/CReqdPropPlan.h"
#include "gpopt/engine/CEngine.h"
#include "gpopt/operators/CExpressionHandle.h"
#include "gpopt/operators/CLogical.h"
#include "gpopt/search/CGroup.h"
#include "gpopt/search/CGroupExpression.h"
#include "gpopt/search/CJobFactory.h"
#include "gpopt/search/CJobGroupImplementation.h"
#include "gpopt/search/CJobTransformation.h"
#include "gpopt/search/CScheduler.h"
#include "gpopt/search/CSchedulerContext.h"
using namespace gpopt;
// State transition diagram for group expression optimization job state machine;
//
// +------------------------+
// | estInitialized: |
// +------------- | EevtInitialize() |
// | +------------------------+
// | |
// | | eevOptimizingChildren
// | v
// | +------------------------+ eevOptimizingChildren
// | | estOptimizingChildren: | ------------------------+
// | | EevtOptimizeChildren() | |
// +------------- | | <-----------------------+
// | +------------------------+
// | |
// | eevFinalized | eevChildrenOptimized
// | v
// | +------------------------+
// | | estChildrenOptimized: |
// +------------- | EevtAddEnforcers() |
// | +------------------------+
// | |
// | | eevOptimizingSelf
// | v
// | +------------------------+ eevOptimizingSelf
// | | estEnfdPropsChecked: | ------------------------+
// | | EevtOptimizeSelf() | |
// +------------- | | <-----------------------+
// | +------------------------+
// | |
// | | eevSelfOptimized
// | v
// | +------------------------+
// | | estSelfOptimized: |
// | eevFinalized | EevtFinalize() |
// | +------------------------+
// | |
// | |
// | |
// | |
// +----------------+
// |
// |
// | eevFinalized
// v
// +------------------------+
// | estCompleted |
// +------------------------+
//
const CJobGroupExpressionOptimization::EEvent
rgeev[CJobGroupExpressionOptimization::estSentinel]
[CJobGroupExpressionOptimization::estSentinel] = {
{// estInitialized
CJobGroupExpressionOptimization::eevSentinel,
CJobGroupExpressionOptimization::eevOptimizingChildren,
CJobGroupExpressionOptimization::eevSentinel,
CJobGroupExpressionOptimization::eevSentinel,
CJobGroupExpressionOptimization::eevSentinel,
CJobGroupExpressionOptimization::eevFinalized},
{// estOptimizingChildren
CJobGroupExpressionOptimization::eevSentinel,
CJobGroupExpressionOptimization::eevOptimizingChildren,
CJobGroupExpressionOptimization::eevChildrenOptimized,
CJobGroupExpressionOptimization::eevSentinel,
CJobGroupExpressionOptimization::eevSentinel,
CJobGroupExpressionOptimization::eevFinalized},
{// estChildrenOptimized
CJobGroupExpressionOptimization::eevSentinel,
CJobGroupExpressionOptimization::eevSentinel,
CJobGroupExpressionOptimization::eevSentinel,
CJobGroupExpressionOptimization::eevOptimizingSelf,
CJobGroupExpressionOptimization::eevSentinel,
CJobGroupExpressionOptimization::eevFinalized},
{// estEnfdPropsChecked
CJobGroupExpressionOptimization::eevSentinel,
CJobGroupExpressionOptimization::eevSentinel,
CJobGroupExpressionOptimization::eevSentinel,
CJobGroupExpressionOptimization::eevOptimizingSelf,
CJobGroupExpressionOptimization::eevSelfOptimized,
CJobGroupExpressionOptimization::eevFinalized},
{// estSelfOptimized
CJobGroupExpressionOptimization::eevSentinel,
CJobGroupExpressionOptimization::eevSentinel,
CJobGroupExpressionOptimization::eevSentinel,
CJobGroupExpressionOptimization::eevSentinel,
CJobGroupExpressionOptimization::eevSentinel,
CJobGroupExpressionOptimization::eevFinalized},
{// estCompleted
CJobGroupExpressionOptimization::eevSentinel,
CJobGroupExpressionOptimization::eevSentinel,
CJobGroupExpressionOptimization::eevSentinel,
CJobGroupExpressionOptimization::eevSentinel,
CJobGroupExpressionOptimization::eevSentinel,
CJobGroupExpressionOptimization::eevSentinel},
};
#ifdef GPOS_DEBUG
// names for states
const WCHAR rgwszStates[CJobGroupExpressionOptimization::estSentinel]
[GPOPT_FSM_NAME_LENGTH] = {
GPOS_WSZ_LIT("initialized"),
GPOS_WSZ_LIT("optimizing children"),
GPOS_WSZ_LIT("children optimized"),
GPOS_WSZ_LIT("enforceable properties checked"),
GPOS_WSZ_LIT("self optimized"),
GPOS_WSZ_LIT("completed")};
// names for events
const WCHAR rgwszEvents[CJobGroupExpressionOptimization::eevSentinel]
[GPOPT_FSM_NAME_LENGTH] = {
GPOS_WSZ_LIT("optimizing child groups"),
GPOS_WSZ_LIT("optimized child groups"),
GPOS_WSZ_LIT("checking enforceable properties"),
GPOS_WSZ_LIT("computing group expression cost"),
GPOS_WSZ_LIT("computed group expression cost"),
GPOS_WSZ_LIT("finalized")};
#endif // GPOS_DEBUG
//---------------------------------------------------------------------------
// @function:
// CJobGroupExpressionOptimization::CJobGroupExpressionOptimization
//
// @doc:
// Ctor
//
//---------------------------------------------------------------------------
CJobGroupExpressionOptimization::CJobGroupExpressionOptimization() = default;
//---------------------------------------------------------------------------
// @function:
// CJobGroupExpressionOptimization::~CJobGroupExpressionOptimization
//
// @doc:
// Dtor
//
//---------------------------------------------------------------------------
CJobGroupExpressionOptimization::~CJobGroupExpressionOptimization() = default;
//---------------------------------------------------------------------------
// @function:
// CJobGroupExpressionOptimization::Init
//
// @doc:
// Initialize job
//
//---------------------------------------------------------------------------
void
CJobGroupExpressionOptimization::Init(CGroupExpression *pgexpr,
COptimizationContext *poc, ULONG ulOptReq,
CReqdPropPlan *prppCTEProducer)
{
GPOS_ASSERT(nullptr != poc);
CJobGroupExpression::Init(pgexpr);
GPOS_ASSERT(pgexpr->Pop()->FPhysical());
GPOS_ASSERT(pgexpr->Pgroup() == poc->Pgroup());
GPOS_ASSERT(ulOptReq <=
CPhysical::PopConvert(pgexpr->Pop())->UlOptRequests());
m_jsm.Init(rgeev
#ifdef GPOS_DEBUG
,
rgwszStates, rgwszEvents
#endif // GPOS_DEBUG
);
// set job actions
m_jsm.SetAction(estInitialized, EevtInitialize);
m_jsm.SetAction(estOptimizingChildren, EevtOptimizeChildren);
m_jsm.SetAction(estChildrenOptimized, EevtAddEnforcers);
m_jsm.SetAction(estEnfdPropsChecked, EevtOptimizeSelf);
m_jsm.SetAction(estSelfOptimized, EevtFinalize);
m_pdrgpoc = nullptr;
m_pdrgpstatCurrentCtxt = nullptr;
m_pdrgpdp = nullptr;
m_pexprhdlPlan = nullptr;
m_pexprhdlRel = nullptr;
m_eceo = CPhysical::PopConvert(pgexpr->Pop())->Eceo();
m_ulArity = pgexpr->Arity();
m_ulChildIndex = gpos::ulong_max;
m_poc = poc;
m_ulOptReq = ulOptReq;
m_fChildOptimizationFailed = false;
m_fOptimizeCTESequence =
(COperator::EopPhysicalSequence == pgexpr->Pop()->Eopid() &&
(*pgexpr)[0]->FHasCTEProducer());
if (nullptr != prppCTEProducer)
{
prppCTEProducer->AddRef();
}
m_prppCTEProducer = prppCTEProducer;
m_fScheduledCTEOptimization = false;
CJob::SetInit();
}
//---------------------------------------------------------------------------
// @function:
// CJobGroupExpressionOptimization::Cleanup
//
// @doc:
// Cleanup allocated memory
//
//---------------------------------------------------------------------------
void
CJobGroupExpressionOptimization::Cleanup()
{
CRefCount::SafeRelease(m_pdrgpoc);
CRefCount::SafeRelease(m_pdrgpstatCurrentCtxt);
CRefCount::SafeRelease(m_pdrgpdp);
CRefCount::SafeRelease(m_prppCTEProducer);
GPOS_DELETE(m_pexprhdlPlan);
GPOS_DELETE(m_pexprhdlRel);
}
//---------------------------------------------------------------------------
// @function:
// CJobGroupExpressionOptimization::InitChildGroupsOptimization
//
// @doc:
// Initialization routine for child groups optimization
//
//---------------------------------------------------------------------------
void
CJobGroupExpressionOptimization::InitChildGroupsOptimization(
CSchedulerContext *psc)
{
GPOS_ASSERT(nullptr == m_pexprhdlPlan);
GPOS_ASSERT(nullptr == m_pexprhdlRel);
// initialize required plan properties computation
m_pexprhdlPlan = GPOS_NEW(psc->GetGlobalMemoryPool())
CExpressionHandle(psc->GetGlobalMemoryPool());
m_pexprhdlPlan->Attach(m_pgexpr);
if (0 < m_ulArity)
{
m_ulChildIndex = m_pexprhdlPlan->UlFirstOptimizedChildIndex();
}
m_pexprhdlPlan->DeriveProps(nullptr /*pdpctxt*/);
m_pexprhdlPlan->InitReqdProps(m_poc->Prpp());
// initialize required relational properties computation
m_pexprhdlRel = GPOS_NEW(psc->GetGlobalMemoryPool())
CExpressionHandle(psc->GetGlobalMemoryPool());
CGroupExpression *pgexprForStats = m_pgexpr->Pgroup()->PgexprBestPromise(
psc->GetGlobalMemoryPool(), m_pgexpr);
if (nullptr != pgexprForStats)
{
m_pexprhdlRel->Attach(pgexprForStats);
m_pexprhdlRel->DeriveProps(nullptr /*pdpctxt*/);
m_pexprhdlRel->ComputeReqdProps(m_poc->GetReqdRelationalProps(),
0 /*ulOptReq*/);
}
// create child groups derived properties
m_pdrgpdp = GPOS_NEW(psc->GetGlobalMemoryPool())
CDrvdPropArray(psc->GetGlobalMemoryPool());
// initialize stats context with input stats context
m_pdrgpstatCurrentCtxt = GPOS_NEW(psc->GetGlobalMemoryPool())
IStatisticsArray(psc->GetGlobalMemoryPool());
CUtils::AddRefAppend(m_pdrgpstatCurrentCtxt, m_poc->Pdrgpstat());
}
//---------------------------------------------------------------------------
// @function:
// CJobGroupExpressionOptimization::EevtInitialize
//
// @doc:
// Initialize internal data structures;
//
//---------------------------------------------------------------------------
CJobGroupExpressionOptimization::EEvent
CJobGroupExpressionOptimization::EevtInitialize(CSchedulerContext *psc,
CJob *pjOwner)
{
// get a job pointer
CJobGroupExpressionOptimization *pjgeo = PjConvert(pjOwner);
CExpressionHandle exprhdl(psc->GetGlobalMemoryPool());
exprhdl.Attach(pjgeo->m_pgexpr);
exprhdl.DeriveProps(nullptr /*pdpctxt*/);
if (!psc->Peng()->FCheckReqdProps(exprhdl, pjgeo->m_poc->Prpp(),
pjgeo->m_ulOptReq))
{
return eevFinalized;
}
// check if job can be early terminated without optimizing any child
CCost costLowerBound(GPOPT_INVALID_COST);
if (psc->Peng()->FSafeToPrune(
pjgeo->m_pgexpr, pjgeo->m_poc->Prpp(), nullptr /*pccChild*/,
gpos::ulong_max /*child_index*/, &costLowerBound))
{
(void) pjgeo->m_pgexpr->PccComputeCost(
psc->GetGlobalMemoryPool(), pjgeo->m_poc, pjgeo->m_ulOptReq,
nullptr /*pdrgpoc*/, true /*fPruned*/, costLowerBound);
return eevFinalized;
}
pjgeo->InitChildGroupsOptimization(psc);
return eevOptimizingChildren;
}
//---------------------------------------------------------------------------
// @function:
// CJobGroupExpressionOptimization::DerivePrevChildProps
//
// @doc:
// Derive plan properties and stats of the child previous to
// the one being optimized
//
//---------------------------------------------------------------------------
void
CJobGroupExpressionOptimization::DerivePrevChildProps(CSchedulerContext *psc)
{
ULONG ulPrevChildIndex =
m_pexprhdlPlan->UlPreviousOptimizedChildIndex(m_ulChildIndex);
// retrieve plan properties of the optimal implementation of previous child group
CGroup *pgroupChild = (*m_pgexpr)[ulPrevChildIndex];
if (pgroupChild->FScalar())
{
// exit if previous child is a scalar group
return;
}
COptimizationContext *pocChild = pgroupChild->PocLookupBest(
psc->GetGlobalMemoryPool(), psc->Peng()->UlSearchStages(),
m_pexprhdlPlan->Prpp(ulPrevChildIndex));
GPOS_ASSERT(nullptr != pocChild);
CCostContext *pccChildBest = pocChild->PccBest();
if (nullptr == pccChildBest)
{
// failed to optimize child
m_fChildOptimizationFailed = true;
return;
}
// check if job can be early terminated after previous children have been optimized
CCost costLowerBound(GPOPT_INVALID_COST);
if (psc->Peng()->FSafeToPrune(m_pgexpr, m_poc->Prpp(), pccChildBest,
ulPrevChildIndex, &costLowerBound))
{
// failed to optimize child due to cost bounding
(void) m_pgexpr->PccComputeCost(psc->GetGlobalMemoryPool(), m_poc,
m_ulOptReq, nullptr /*pdrgpoc*/,
true /*fPruned*/, costLowerBound);
m_fChildOptimizationFailed = true;
return;
}
CExpressionHandle exprhdl(psc->GetGlobalMemoryPool());
exprhdl.Attach(pccChildBest);
exprhdl.DerivePlanPropsForCostContext();
exprhdl.Pdp()->AddRef();
m_pdrgpdp->Append(exprhdl.Pdp());
// copy stats of child's best cost context to current stats context
IStatistics *pstat = pccChildBest->Pstats();
pstat->AddRef();
m_pdrgpstatCurrentCtxt->Append(pstat);
}
//---------------------------------------------------------------------------
// @function:
// CJobGroupExpressionOptimization::ComputeCurrentChildRequirements
//
// @doc:
// Compute required plan properties for current child
//
//---------------------------------------------------------------------------
void
CJobGroupExpressionOptimization::ComputeCurrentChildRequirements(
CSchedulerContext *psc)
{
// derive plan properties of previous child group
if (m_ulChildIndex != m_pexprhdlPlan->UlFirstOptimizedChildIndex())
{
DerivePrevChildProps(psc);
if (m_fChildOptimizationFailed)
{
return;
}
}
// compute required plan properties of current child group
if (0 == m_ulChildIndex && nullptr != m_prppCTEProducer)
{
GPOS_ASSERT(m_fOptimizeCTESequence);
GPOS_ASSERT((*m_pgexpr)[m_ulChildIndex]->FHasCTEProducer());
m_prppCTEProducer->AddRef();
m_pexprhdlPlan->CopyChildReqdProps(m_ulChildIndex, m_prppCTEProducer);
}
else
{
m_pexprhdlPlan->ComputeChildReqdProps(m_ulChildIndex, m_pdrgpdp,
m_ulOptReq);
}
}
//---------------------------------------------------------------------------
// @function:
// CJobGroupExpressionOptimization::ScheduleChildGroupsJobs
//
// @doc:
// Schedule optimization job for the next child group; skip child groups
// as they do not require optimization
//
//---------------------------------------------------------------------------
void
CJobGroupExpressionOptimization::ScheduleChildGroupsJobs(CSchedulerContext *psc)
{
GPOS_ASSERT(!FChildrenScheduled());
CGroup *pgroupChild = (*m_pgexpr)[m_ulChildIndex];
if (pgroupChild->FScalar())
{
if (!m_pexprhdlPlan->FNextChildIndex(&m_ulChildIndex))
{
// child group optimization is complete
SetChildrenScheduled();
}
return;
}
ComputeCurrentChildRequirements(psc);
if (m_fChildOptimizationFailed)
{
return;
}
m_pexprhdlPlan->Prpp(m_ulChildIndex)->AddRef();
// use current stats for optimizing current child
IStatisticsArray *stats_ctxt = GPOS_NEW(psc->GetGlobalMemoryPool())
IStatisticsArray(psc->GetGlobalMemoryPool());
CUtils::AddRefAppend(stats_ctxt, m_pdrgpstatCurrentCtxt);
// compute required relational properties
CReqdPropRelational *prprel = nullptr;
if (CPhysical::PopConvert(m_pgexpr->Pop())->FPassThruStats())
{
// copy requirements from origin context
prprel = m_poc->GetReqdRelationalProps();
}
else
{
// retrieve requirements from handle
prprel = m_pexprhdlRel->GetReqdRelationalProps(m_ulChildIndex);
}
GPOS_ASSERT(nullptr != prprel);
prprel->AddRef();
// schedule optimization job for current child group
COptimizationContext *pocChild = GPOS_NEW(psc->GetGlobalMemoryPool())
COptimizationContext(psc->GetGlobalMemoryPool(), pgroupChild,
m_pexprhdlPlan->Prpp(m_ulChildIndex), prprel,
stats_ctxt, psc->Peng()->UlCurrSearchStage());
if (pgroupChild == m_pgexpr->Pgroup() && pocChild->Matches(m_poc))
{
// this is to prevent deadlocks, child context cannot be the same as parent context
m_fChildOptimizationFailed = true;
pocChild->Release();
return;
}
CJobGroupOptimization::ScheduleJob(psc, pgroupChild, m_pgexpr, pocChild,
this);
pocChild->Release();
// advance to next child
if (!m_pexprhdlPlan->FNextChildIndex(&m_ulChildIndex))
{
// child group optimization is complete
SetChildrenScheduled();
}
}
//---------------------------------------------------------------------------
// @function:
// CJobGroupExpressionOptimization::EevtOptimizeChildren
//
// @doc:
// Optimize child groups
//
//---------------------------------------------------------------------------
CJobGroupExpressionOptimization::EEvent
CJobGroupExpressionOptimization::EevtOptimizeChildren(CSchedulerContext *psc,
CJob *pjOwner)
{
// get a job pointer
CJobGroupExpressionOptimization *pjgeo = PjConvert(pjOwner);
if (0 < pjgeo->m_ulArity && !pjgeo->FChildrenScheduled())
{
pjgeo->ScheduleChildGroupsJobs(psc);
if (pjgeo->m_fChildOptimizationFailed)
{
// failed to optimize child, terminate job
pjgeo->Cleanup();
return eevFinalized;
}
return eevOptimizingChildren;
}
return eevChildrenOptimized;
}
//---------------------------------------------------------------------------
// @function:
// CJobGroupExpressionOptimization::EevtAddEnforcers
//
// @doc:
// Add required enforcers to owning group
//
//---------------------------------------------------------------------------
CJobGroupExpressionOptimization::EEvent
CJobGroupExpressionOptimization::EevtAddEnforcers(CSchedulerContext *psc,
CJob *pjOwner)
{
// get a job pointer
CJobGroupExpressionOptimization *pjgeo = PjConvert(pjOwner);
// build child contexts array
GPOS_ASSERT(nullptr == pjgeo->m_pdrgpoc);
pjgeo->m_pdrgpoc = psc->Peng()->PdrgpocChildren(psc->GetGlobalMemoryPool(),
*pjgeo->m_pexprhdlPlan);
// enforce physical properties
BOOL fCheckEnfdProps = psc->Peng()->FCheckEnfdProps(
psc->GetGlobalMemoryPool(), pjgeo->m_pgexpr, pjgeo->m_poc,
pjgeo->m_ulOptReq, pjgeo->m_pdrgpoc);
if (fCheckEnfdProps)
{
// No new enforcers group expressions were added because they were either
// optional or unnecessary. So, move on to optimize the current group
// expression.
return eevOptimizingSelf;
}
// Either adding enforcers was prohibited or at least one enforcer was added
// because it was required. In any case, this job can be finalized, since
// optimizing the current group expression is not needed (because of the
// prohibition) or the newly created enforcer group expression job will get
// to it later on.
pjgeo->Cleanup();
return eevFinalized;
}
//---------------------------------------------------------------------------
// @function:
// CJobGroupExpressionOptimization::EevtOptimizeSelf
//
// @doc:
// Optimize group expression
//
//---------------------------------------------------------------------------
CJobGroupExpressionOptimization::EEvent
CJobGroupExpressionOptimization::EevtOptimizeSelf(CSchedulerContext *psc,
CJob *pjOwner)
{
// get a job pointer
CJobGroupExpressionOptimization *pjgeo = PjConvert(pjOwner);
if (pjgeo->m_fScheduledCTEOptimization)
{
// current job has triggered a CTE optimization child job,
// we can only come here if the child job is complete,
// we can now safely terminate current job
return eevSelfOptimized;
}
// compute group expression cost under current context
COptimizationContext *poc = pjgeo->m_poc;
CGroupExpression *pgexpr = pjgeo->m_pgexpr;
COptimizationContextArray *pdrgpoc = pjgeo->m_pdrgpoc;
ULONG ulOptReq = pjgeo->m_ulOptReq;
CCostContext *pcc =
pgexpr->PccComputeCost(psc->GetGlobalMemoryPool(), poc, ulOptReq,
pdrgpoc, false /*fPruned*/, CCost(0.0));
if (nullptr == pcc)
{
pjgeo->Cleanup();
// failed to create cost context, terminate optimization job
return eevFinalized;
}
pgexpr->Pgroup()->UpdateBestCost(poc, pcc);
if (FScheduleCTEOptimization(psc, pgexpr, poc, ulOptReq, pjgeo))
{
// a child job for optimizing CTE has been scheduled
pjgeo->m_fScheduledCTEOptimization = true;
// suspend current job until CTE optimization child job is complete
return eevOptimizingSelf;
}
return eevSelfOptimized;
}
//---------------------------------------------------------------------------
// @function:
// CJobGroupExpressionOptimization::EevtFinalize
//
// @doc:
// Finalize optimization
//
//---------------------------------------------------------------------------
CJobGroupExpressionOptimization::EEvent
CJobGroupExpressionOptimization::EevtFinalize(CSchedulerContext *, // psc
CJob *pjOwner)
{
// get a job pointer
CJobGroupExpressionOptimization *pjgeo = PjConvert(pjOwner);
GPOS_ASSERT(!pjgeo->m_fChildOptimizationFailed);
#ifdef GPOS_DEBUG
CCostContext *pcc = pjgeo->m_poc->PccBest();
#endif // GPOS_DEBUG
GPOS_ASSERT(nullptr != pcc);
GPOS_ASSERT(CCostContext::estCosted == pcc->Est());
pjgeo->Cleanup();
return eevFinalized;
}
//---------------------------------------------------------------------------
// @function:
// CJobGroupExpressionOptimization::FExecute
//
// @doc:
// Main job function
//
//---------------------------------------------------------------------------
BOOL
CJobGroupExpressionOptimization::FExecute(CSchedulerContext *psc)
{
GPOS_ASSERT(FInit());
return m_jsm.FRun(psc, this);
}
//---------------------------------------------------------------------------
// @function:
// CJobGroupExpressionOptimization::ScheduleJob
//
// @doc:
// Schedule a new group expression optimization job
//
//---------------------------------------------------------------------------
void
CJobGroupExpressionOptimization::ScheduleJob(CSchedulerContext *psc,
CGroupExpression *pgexpr,
COptimizationContext *poc,
ULONG ulOptReq, CJob *pjParent)
{
CJob *pj = psc->Pjf()->PjCreate(CJob::EjtGroupExpressionOptimization);
// initialize job
CJobGroupExpressionOptimization *pjgeo = PjConvert(pj);
pjgeo->Init(pgexpr, poc, ulOptReq);
psc->Psched()->Add(pjgeo, pjParent);
}
//---------------------------------------------------------------------------
// @function:
// CJobGroupExpressionOptimization::FScheduleCTEOptimization
//
// @doc:
// Schedule a new job for CTE optimization
//
//---------------------------------------------------------------------------
BOOL
CJobGroupExpressionOptimization::FScheduleCTEOptimization(
CSchedulerContext *psc, CGroupExpression *pgexpr, COptimizationContext *poc,
ULONG ulOptReq, CJob *pjParent)
{
GPOS_ASSERT(nullptr != psc);
if (GPOS_FTRACE(EopttraceDisablePushingCTEConsumerReqsToCTEProducer))
{
// pushing CTE consumer requirements to producer is disabled
return false;
}
CJobGroupExpressionOptimization *pjgeoParent = PjConvert(pjParent);
GPOS_ASSERT(!pjgeoParent->m_fScheduledCTEOptimization);
if (!pjgeoParent->m_fOptimizeCTESequence)
{
// root operator is not a Sequence
return false;
}
if (nullptr != pjgeoParent->m_prppCTEProducer)
{
// parent job is already a CTE optimization job
return false;
}
// compute new requirements for CTE producer based on delivered properties of consumers plan
CReqdPropPlan *prppCTEProducer = COptimizationContext::PrppCTEProducer(
psc->GetGlobalMemoryPool(), poc, psc->Peng()->UlSearchStages());
if (nullptr == prppCTEProducer)
{
// failed to create CTE producer requirements
return false;
}
// schedule CTE optimization job
CJob *pj = psc->Pjf()->PjCreate(CJob::EjtGroupExpressionOptimization);
CJobGroupExpressionOptimization *pjgeo = PjConvert(pj);
// initialize job
pjgeo->Init(pgexpr, poc, ulOptReq, prppCTEProducer);
psc->Psched()->Add(pjgeo, pjParent);
prppCTEProducer->Release();
return true;
}
#ifdef GPOS_DEBUG
//---------------------------------------------------------------------------
// @function:
// CJobGroupExpressionOptimization::OsPrint
//
// @doc:
// Print function
//
//---------------------------------------------------------------------------
IOstream &
CJobGroupExpressionOptimization::OsPrint(IOstream &os) const
{
os << "Group expr: ";
m_pgexpr->OsPrint(os);
os << std::endl;
return m_jsm.OsHistory(os);
}
#endif // GPOS_DEBUG
// EOF
相关信息
相关文章
greenplumn CGroupExpression 源码
greenplumn CJobGroupExploration 源码
0
赞
热门推荐
-
2、 - 优质文章
-
3、 gate.io
-
7、 golang
-
9、 openharmony
-
10、 Vue中input框自动聚焦