greenplumn CPhysicalTVF 源码
greenplumn CPhysicalTVF 代码
文件路径:/src/backend/gporca/libgpopt/src/operators/CPhysicalTVF.cpp
//---------------------------------------------------------------------------
// Greenplum Database
// Copyright (C) 2012 EMC Corp
//
// @filename:
// CPhysicalTVF.cpp
//
// @doc:
// Implementation of table-valued functions
//---------------------------------------------------------------------------
#include "gpopt/operators/CPhysicalTVF.h"
#include "gpos/base.h"
#include "gpopt/base/CCTEMap.h"
#include "gpopt/base/CColRefSet.h"
#include "gpopt/base/CDistributionSpecSingleton.h"
#include "gpopt/base/CDistributionSpecUniversal.h"
#include "gpopt/base/COptCtxt.h"
#include "gpopt/metadata/CName.h"
#include "gpopt/operators/CExpressionHandle.h"
using namespace gpopt;
//---------------------------------------------------------------------------
// @function:
// CPhysicalTVF::CPhysicalTVF
//
// @doc:
// Ctor
//
//---------------------------------------------------------------------------
CPhysicalTVF::CPhysicalTVF(CMemoryPool *mp, IMDId *mdid_func,
IMDId *mdid_return_type, CWStringConst *str,
CColumnDescriptorArray *pdrgpcoldesc,
CColRefSet *pcrsOutput)
: CPhysical(mp),
m_func_mdid(mdid_func),
m_return_type_mdid(mdid_return_type),
m_pstr(str),
m_pdrgpcoldesc(pdrgpcoldesc),
m_pcrsOutput(pcrsOutput)
{
GPOS_ASSERT(m_return_type_mdid->IsValid());
GPOS_ASSERT(nullptr != m_pstr);
GPOS_ASSERT(nullptr != m_pdrgpcoldesc);
GPOS_ASSERT(nullptr != m_pcrsOutput);
CMDAccessor *md_accessor = COptCtxt::PoctxtFromTLS()->Pmda();
if (m_func_mdid->IsValid())
{
m_pmdfunc = md_accessor->RetrieveFunc(m_func_mdid);
}
else
{
m_pmdfunc = nullptr;
}
}
//---------------------------------------------------------------------------
// @function:
// CPhysicalTVF::~CPhysicalTVF
//
// @doc:
// Dtor
//
//---------------------------------------------------------------------------
CPhysicalTVF::~CPhysicalTVF()
{
m_func_mdid->Release();
m_return_type_mdid->Release();
m_pdrgpcoldesc->Release();
m_pcrsOutput->Release();
GPOS_DELETE(m_pstr);
}
//---------------------------------------------------------------------------
// @function:
// CPhysicalTVF::Matches
//
// @doc:
// Match function on operator level
//
//---------------------------------------------------------------------------
BOOL
CPhysicalTVF::Matches(COperator *pop) const
{
if (pop->Eopid() == Eopid())
{
CPhysicalTVF *popTVF = CPhysicalTVF::PopConvert(pop);
return m_func_mdid->Equals(popTVF->FuncMdId()) &&
m_return_type_mdid->Equals(popTVF->ReturnTypeMdId()) &&
m_pdrgpcoldesc == popTVF->Pdrgpcoldesc() &&
m_pcrsOutput->Equals(popTVF->DeriveOutputColumns());
}
return false;
}
//---------------------------------------------------------------------------
// @function:
// CPhysicalTVF::FInputOrderSensitive
//
// @doc:
// Sensitivity to input order
//
//---------------------------------------------------------------------------
BOOL
CPhysicalTVF::FInputOrderSensitive() const
{
return true;
}
//---------------------------------------------------------------------------
// @function:
// CPhysicalTVF::PcrsRequired
//
// @doc:
// Compute required columns of the n-th child;
// we only compute required columns for the relational child;
//
//---------------------------------------------------------------------------
CColRefSet *
CPhysicalTVF::PcrsRequired(CMemoryPool *, // mp,
CExpressionHandle &, // exprhdl,
CColRefSet *, // pcrsRequired,
ULONG, // child_index,
CDrvdPropArray *, // pdrgpdpCtxt
ULONG // ulOptReq
)
{
GPOS_ASSERT(!"CPhysicalTVF has no relational children");
return nullptr;
}
//---------------------------------------------------------------------------
// @function:
// CPhysicalTVF::PosRequired
//
// @doc:
// Compute required sort order of the n-th child
//
//---------------------------------------------------------------------------
COrderSpec *
CPhysicalTVF::PosRequired(CMemoryPool *, // mp,
CExpressionHandle &, // exprhdl,
COrderSpec *, // posRequired,
ULONG, // child_index,
CDrvdPropArray *, // pdrgpdpCtxt
ULONG // ulOptReq
) const
{
GPOS_ASSERT(!"CPhysicalTVF has no relational children");
return nullptr;
}
//---------------------------------------------------------------------------
// @function:
// CPhysicalTVF::PdsRequired
//
// @doc:
// Compute required distribution of the n-th child
//
//---------------------------------------------------------------------------
CDistributionSpec *
CPhysicalTVF::PdsRequired(CMemoryPool *, // mp,
CExpressionHandle &, // exprhdl,
CDistributionSpec *, // pdsRequired,
ULONG, //child_index
CDrvdPropArray *, // pdrgpdpCtxt
ULONG // ulOptReq
) const
{
GPOS_ASSERT(!"CPhysicalTVF has no relational children");
return nullptr;
}
//---------------------------------------------------------------------------
// @function:
// CPhysicalTVF::PrsRequired
//
// @doc:
// Compute required rewindability of the n-th child
//
//---------------------------------------------------------------------------
CRewindabilitySpec *
CPhysicalTVF::PrsRequired(CMemoryPool *, // mp,
CExpressionHandle &, // exprhdl,
CRewindabilitySpec *, // prsRequired,
ULONG, // child_index,
CDrvdPropArray *, // pdrgpdpCtxt
ULONG // ulOptReq
) const
{
GPOS_ASSERT(!"CPhysicalTVF has no relational children");
return nullptr;
}
//---------------------------------------------------------------------------
// @function:
// CPhysicalTVF::PcteRequired
//
// @doc:
// Compute required CTE map of the n-th child
//
//---------------------------------------------------------------------------
CCTEReq *
CPhysicalTVF::PcteRequired(CMemoryPool *, //mp,
CExpressionHandle &, //exprhdl,
CCTEReq *, //pcter,
ULONG, //child_index,
CDrvdPropArray *, //pdrgpdpCtxt,
ULONG //ulOptReq
) const
{
GPOS_ASSERT(!"CPhysicalTVF has no relational children");
return nullptr;
}
//---------------------------------------------------------------------------
// @function:
// CPhysicalTVF::FProvidesReqdCols
//
// @doc:
// Check if required columns are included in output columns
//
//---------------------------------------------------------------------------
BOOL
CPhysicalTVF::FProvidesReqdCols(CExpressionHandle &, // exprhdl,
CColRefSet *pcrsRequired,
ULONG // ulOptReq
) const
{
GPOS_ASSERT(nullptr != pcrsRequired);
return m_pcrsOutput->ContainsAll(pcrsRequired);
}
//---------------------------------------------------------------------------
// @function:
// CPhysicalTVF::PosDerive
//
// @doc:
// Derive sort order
//
//---------------------------------------------------------------------------
COrderSpec *
CPhysicalTVF::PosDerive(CMemoryPool *mp,
CExpressionHandle & // exprhdl
) const
{
return GPOS_NEW(mp) COrderSpec(mp);
}
//---------------------------------------------------------------------------
// @function:
// CPhysicalTVF::PdsDerive
//
// @doc:
// Derive distribution
//
//---------------------------------------------------------------------------
CDistributionSpec *
CPhysicalTVF::PdsDerive(CMemoryPool *mp, CExpressionHandle &exprhdl) const
{
if (exprhdl.NeedsSingletonExecution())
{
return GPOS_NEW(mp) CDistributionSpecSingleton();
}
return GPOS_NEW(mp) CDistributionSpecUniversal();
}
//---------------------------------------------------------------------------
// @function:
// CPhysicalTVF::PrsDerive
//
// @doc:
// Derive rewindability
//
//---------------------------------------------------------------------------
CRewindabilitySpec *
CPhysicalTVF::PrsDerive(CMemoryPool *mp, CExpressionHandle &exprhdl) const
{
// TODO: shardikar; If the executor materializes the function results, aren't
// volatile functions rewindable? Or should they be rescannable and
// re-executed every time?
if (IMDFunction::EfsVolatile == exprhdl.DeriveFunctionProperties()->Efs())
{
return GPOS_NEW(mp)
CRewindabilitySpec(CRewindabilitySpec::ErtRescannable,
CRewindabilitySpec::EmhtNoMotion);
}
// TVF scan materializes the results of its execution, and so is rewindable.
return GPOS_NEW(mp) CRewindabilitySpec(CRewindabilitySpec::ErtRewindable,
CRewindabilitySpec::EmhtNoMotion);
}
// derive partition propagation
CPartitionPropagationSpec *
CPhysicalTVF::PppsDerive(CMemoryPool *mp, CExpressionHandle &) const
{
return GPOS_NEW(mp) CPartitionPropagationSpec(mp);
}
//---------------------------------------------------------------------------
// @function:
// CPhysicalTVF::PcmDerive
//
// @doc:
// Common case of combining cte maps of all logical children
//
//---------------------------------------------------------------------------
CCTEMap *
CPhysicalTVF::PcmDerive(CMemoryPool *mp,
CExpressionHandle & //exprhdl
) const
{
return GPOS_NEW(mp) CCTEMap(mp);
}
//---------------------------------------------------------------------------
// @function:
// CPhysicalTVF::EpetOrder
//
// @doc:
// Return the enforcing type for order property based on this operator
//
//---------------------------------------------------------------------------
CEnfdProp::EPropEnforcingType
CPhysicalTVF::EpetOrder(CExpressionHandle &, // exprhdl
const CEnfdOrder *
#ifdef GPOS_DEBUG
peo
#endif // GPOS_DEBUG
) const
{
GPOS_ASSERT(nullptr != peo);
GPOS_ASSERT(!peo->PosRequired()->IsEmpty());
return CEnfdProp::EpetRequired;
}
//---------------------------------------------------------------------------
// @function:
// CPhysicalTVF::EpetRewindability
//
// @doc:
// Return the enforcing type for rewindability property based on this operator
//
//---------------------------------------------------------------------------
CEnfdProp::EPropEnforcingType
CPhysicalTVF::EpetRewindability(CExpressionHandle &exprhdl,
const CEnfdRewindability *per) const
{
// get rewindability delivered by the TVF node
CRewindabilitySpec *prs = CDrvdPropPlan::Pdpplan(exprhdl.Pdp())->Prs();
if (per->FCompatible(prs))
{
// required distribution is already provided
return CEnfdProp::EpetUnnecessary;
}
return CEnfdProp::EpetRequired;
}
// EOF
相关信息
相关文章
greenplumn CExpressionFactorizer 源码
greenplumn CExpressionHandle 源码
greenplumn CExpressionPreprocessor 源码
greenplumn CExpressionUtils 源码
0
赞
热门推荐
-
2、 - 优质文章
-
3、 gate.io
-
7、 golang
-
9、 openharmony
-
10、 Vue中input框自动聚焦