greenplumn CPhysicalTVF 源码

  • 2022-08-18
  • 浏览 (298)

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 源码目录

相关文章

greenplumn CExpression 源码

greenplumn CExpressionFactorizer 源码

greenplumn CExpressionHandle 源码

greenplumn CExpressionPreprocessor 源码

greenplumn CExpressionUtils 源码

greenplumn CHashedDistributions 源码

greenplumn CLogical 源码

greenplumn CLogicalApply 源码

greenplumn CLogicalAssert 源码

greenplumn CLogicalBitmapTableGet 源码

0  赞