greenplumn CXformExpandNAryJoin 源码
greenplumn CXformExpandNAryJoin 代码
文件路径:/src/backend/gporca/libgpopt/src/xforms/CXformExpandNAryJoin.cpp
//---------------------------------------------------------------------------
// Greenplum Database
// Copyright (C) 2011 EMC Corp.
//
// @filename:
// CXformExpandNAryJoin.cpp
//
// @doc:
// Implementation of n-ary join expansion
//---------------------------------------------------------------------------
#include "gpopt/xforms/CXformExpandNAryJoin.h"
#include "gpos/base.h"
#include "gpos/memory/CAutoMemoryPool.h"
#include "gpopt/base/CUtils.h"
#include "gpopt/operators/CLogicalInnerJoin.h"
#include "gpopt/operators/CLogicalNAryJoin.h"
#include "gpopt/operators/CNormalizer.h"
#include "gpopt/operators/CPatternMultiLeaf.h"
#include "gpopt/operators/CPredicateUtils.h"
#include "gpopt/xforms/CJoinOrder.h"
#include "gpopt/xforms/CXformUtils.h"
using namespace gpopt;
//---------------------------------------------------------------------------
// @function:
// CXformExpandNAryJoin::CXformExpandNAryJoin
//
// @doc:
// Ctor
//
//---------------------------------------------------------------------------
CXformExpandNAryJoin::CXformExpandNAryJoin(CMemoryPool *mp)
: CXformExploration(
// pattern
GPOS_NEW(mp) CExpression(
mp, GPOS_NEW(mp) CLogicalNAryJoin(mp),
GPOS_NEW(mp) CExpression(mp, GPOS_NEW(mp) CPatternMultiLeaf(mp)),
GPOS_NEW(mp) CExpression(mp, GPOS_NEW(mp) CPatternTree(mp))))
{
}
//---------------------------------------------------------------------------
// @function:
// CXformExpandNAryJoin::Exfp
//
// @doc:
// Compute xform promise for a given expression handle
//
//---------------------------------------------------------------------------
CXform::EXformPromise
CXformExpandNAryJoin::Exfp(CExpressionHandle &exprhdl) const
{
if (exprhdl.DeriveHasSubquery(exprhdl.Arity() - 1))
{
// subqueries must be unnested before applying xform
return CXform::ExfpNone;
}
#ifdef GPOS_DEBUG
CAutoMemoryPool amp;
GPOS_ASSERT(!CXformUtils::FJoinPredOnSingleChild(amp.Pmp(), exprhdl) &&
"join predicates are not pushed down");
#endif // GPOS_DEBUG
return CXform::ExfpHigh;
}
//---------------------------------------------------------------------------
// @function:
// CXformExpandNAryJoin::Transform
//
// @doc:
// Actual transformation of n-ary join to cluster of inner joins in
// the order of the joins existing in the query
//
//---------------------------------------------------------------------------
//Example Input tree:
// +--CLogicalNAryJoin
// |--CLogicalGet "t1"
// |--CLogicalGet "t2"
// |--CLogicalGet "t3"
// +--CScalarBoolOp (EboolopAnd)
// |--CScalarCmp (=)
// | |--CScalarIdent "a" (0)
// | +--CScalarIdent "a" (9)
// |--CScalarCmp (=)
// | |--CScalarIdent "a" (9)
// | +--CScalarIdent "a" (18)
// +--CScalarCmp (=)
// |--CScalarIdent "a" (0)
// +--CScalarIdent "a" (18)
void
CXformExpandNAryJoin::Transform(CXformContext *pxfctxt, CXformResult *pxfres,
CExpression *pexpr) const
{
GPOS_ASSERT(nullptr != pxfctxt);
GPOS_ASSERT(nullptr != pxfres);
GPOS_ASSERT(FPromising(pxfctxt->Pmp(), this, pexpr));
GPOS_ASSERT(FCheckPattern(pexpr));
CMemoryPool *mp = pxfctxt->Pmp();
const ULONG arity = pexpr->Arity();
GPOS_ASSERT(arity >= 3);
// create a cluster of inner joins with same order of given relations
// and dummy join condition
// +--CLogicalInnerJoin
// |--CLogicalInnerJoin
// | |--CLogicalGet "t1"
// | |--CLogicalGet "t2"
// | +--CScalarConst (1)
// |--CLogicalGet "t3"
// +--CScalarConst (1)
(*pexpr)[0]->AddRef();
(*pexpr)[1]->AddRef();
CExpression *pexprJoin = CUtils::PexprLogicalJoin<CLogicalInnerJoin>(
mp, (*pexpr)[0], (*pexpr)[1],
CPredicateUtils::PexprConjunction(mp, nullptr));
for (ULONG ul = 2; ul < arity - 1; ul++)
{
(*pexpr)[ul]->AddRef();
pexprJoin = CUtils::PexprLogicalJoin<CLogicalInnerJoin>(
mp, pexprJoin, (*pexpr)[ul],
CPredicateUtils::PexprConjunction(mp, nullptr));
}
CExpression *pexprScalar = (*pexpr)[arity - 1];
pexprScalar->AddRef();
// create a logical select with the join expression and scalar condition child
CExpression *pexprSelect =
CUtils::PexprLogicalSelect(mp, pexprJoin, pexprScalar);
// normalize the tree and push down the predicates
CExpression *pexprNormalized = CNormalizer::PexprNormalize(mp, pexprSelect);
pexprSelect->Release();
pxfres->Add(pexprNormalized);
}
// EOF
相关信息
相关文章
greenplumn CJoinOrderGreedy 源码
greenplumn CJoinOrderMinCard 源码
greenplumn CSubqueryHandler 源码
0
赞
热门推荐
-
2、 - 优质文章
-
3、 gate.io
-
7、 golang
-
9、 openharmony
-
10、 Vue中input框自动聚焦