greenplumn CPhysicalInnerIndexNLJoin 源码
greenplumn CPhysicalInnerIndexNLJoin 代码
文件路径:/src/backend/gporca/libgpopt/src/operators/CPhysicalInnerIndexNLJoin.cpp
//---------------------------------------------------------------------------
// Greenplum Database
// Copyright (C) 2013 Greenplum, Inc.
//
// @filename:
// CPhysicalInnerIndexNLJoin.cpp
//
// @doc:
// Implementation of index inner nested-loops join operator
//---------------------------------------------------------------------------
#include "gpopt/operators/CPhysicalInnerIndexNLJoin.h"
#include "gpos/base.h"
#include "gpopt/base/CDistributionSpecAny.h"
#include "gpopt/base/CDistributionSpecHashed.h"
#include "gpopt/base/CDistributionSpecNonSingleton.h"
#include "gpopt/base/CDistributionSpecReplicated.h"
#include "gpopt/operators/CExpressionHandle.h"
#include "gpopt/operators/CPredicateUtils.h"
using namespace gpopt;
//---------------------------------------------------------------------------
// @function:
// CPhysicalInnerIndexNLJoin::CPhysicalInnerIndexNLJoin
//
// @doc:
// Ctor
//
//---------------------------------------------------------------------------
CPhysicalInnerIndexNLJoin::CPhysicalInnerIndexNLJoin(CMemoryPool *mp,
CColRefArray *colref_array,
CExpression *origJoinPred)
: CPhysicalInnerNLJoin(mp),
m_pdrgpcrOuterRefs(colref_array),
m_origJoinPred(origJoinPred)
{
GPOS_ASSERT(nullptr != colref_array);
if (nullptr != origJoinPred)
{
origJoinPred->AddRef();
}
}
//---------------------------------------------------------------------------
// @function:
// CPhysicalInnerIndexNLJoin::~CPhysicalInnerIndexNLJoin
//
// @doc:
// Dtor
//
//---------------------------------------------------------------------------
CPhysicalInnerIndexNLJoin::~CPhysicalInnerIndexNLJoin()
{
m_pdrgpcrOuterRefs->Release();
CRefCount::SafeRelease(m_origJoinPred);
}
//---------------------------------------------------------------------------
// @function:
// CPhysicalInnerIndexNLJoin::Matches
//
// @doc:
// Match function
//
//---------------------------------------------------------------------------
BOOL
CPhysicalInnerIndexNLJoin::Matches(COperator *pop) const
{
if (pop->Eopid() == Eopid())
{
return m_pdrgpcrOuterRefs->Equals(
CPhysicalInnerIndexNLJoin::PopConvert(pop)->PdrgPcrOuterRefs());
}
return false;
}
//---------------------------------------------------------------------------
// @function:
// CPhysicalInnerIndexNLJoin::PdsRequired
//
// @doc:
// Compute required distribution of the n-th child;
//
//---------------------------------------------------------------------------
CDistributionSpec *
CPhysicalInnerIndexNLJoin::PdsRequired(CMemoryPool *mp GPOS_UNUSED,
CExpressionHandle &exprhdl GPOS_UNUSED,
CDistributionSpec *, //pdsRequired,
ULONG child_index GPOS_UNUSED,
CDrvdPropArray *pdrgpdpCtxt GPOS_UNUSED,
ULONG // ulOptReq
) const
{
GPOS_RAISE(
CException::ExmaInvalid, CException::ExmiInvalid,
GPOS_WSZ_LIT(
"PdsRequired should not be called for CPhysicalInnerIndexNLJoin"));
return nullptr;
}
CEnfdDistribution *
CPhysicalInnerIndexNLJoin::Ped(CMemoryPool *mp, CExpressionHandle &exprhdl,
CReqdPropPlan *prppInput, ULONG child_index,
CDrvdPropArray *pdrgpdpCtxt, ULONG ulDistrReq)
{
GPOS_ASSERT(2 > child_index);
CEnfdDistribution::EDistributionMatching dmatch =
Edm(prppInput, child_index, pdrgpdpCtxt, ulDistrReq);
if (1 == child_index)
{
// inner (index-scan side) is requested for Any distribution,
// we allow outer references on the inner child of the join since it needs
// to refer to columns in join's outer child
return GPOS_NEW(mp) CEnfdDistribution(
GPOS_NEW(mp)
CDistributionSpecAny(this->Eopid(), true /*fAllowOuterRefs*/),
dmatch);
}
// we need to match distribution of inner
CDistributionSpec *pdsInner =
CDrvdPropPlan::Pdpplan((*pdrgpdpCtxt)[0])->Pds();
CDistributionSpec::EDistributionType edtInner = pdsInner->Edt();
if (CDistributionSpec::EdtSingleton == edtInner ||
CDistributionSpec::EdtStrictSingleton == edtInner ||
CDistributionSpec::EdtUniversal == edtInner)
{
// enforce executing on a single host
return GPOS_NEW(mp) CEnfdDistribution(
GPOS_NEW(mp) CDistributionSpecSingleton(), dmatch);
}
if (CDistributionSpec::EdtHashed == edtInner)
{
// check if we could create an equivalent hashed distribution request to the inner child
CDistributionSpecHashed *pdshashed =
CDistributionSpecHashed::PdsConvert(pdsInner);
CDistributionSpecHashed *pdshashedEquiv = pdshashed->PdshashedEquiv();
// If the inner child is a IndexScan on a multi-key distributed index, it
// may derive an incomplete equiv spec (see CPhysicalScan::PdsDerive()).
// However, there is no point to using that here since there will be no
// operator above this that can complete it.
if (pdshashed->HasCompleteEquivSpec(mp))
{
// request hashed distribution from outer
pdshashedEquiv->Pdrgpexpr()->AddRef();
CDistributionSpecHashed *pdsHashedRequired = GPOS_NEW(mp)
CDistributionSpecHashed(pdshashedEquiv->Pdrgpexpr(),
pdshashedEquiv->FNullsColocated());
pdsHashedRequired->ComputeEquivHashExprs(mp, exprhdl);
return GPOS_NEW(mp) CEnfdDistribution(pdsHashedRequired, dmatch);
}
}
// otherwise, require outer child to be replicated
// The match type for this request has to be "Satisfy" since EdtReplicated
// is required only property. Since a Broadcast motion will always
// derive a EdtStrictReplicated distribution spec, it will never "Match"
// the required distribution spec and hence will not be optimized.
return GPOS_NEW(mp) CEnfdDistribution(
GPOS_NEW(mp)
CDistributionSpecReplicated(CDistributionSpec::EdtReplicated),
CEnfdDistribution::EdmSatisfy);
}
// EOF
相关信息
相关文章
greenplumn CExpressionFactorizer 源码
greenplumn CExpressionHandle 源码
greenplumn CExpressionPreprocessor 源码
greenplumn CExpressionUtils 源码
0
赞
热门推荐
-
2、 - 优质文章
-
3、 gate.io
-
7、 golang
-
9、 openharmony
-
10、 Vue中input框自动聚焦