greenplumn CXformExpandFullOuterJoin 源码
greenplumn CXformExpandFullOuterJoin 代码
文件路径:/src/backend/gporca/libgpopt/src/xforms/CXformExpandFullOuterJoin.cpp
//---------------------------------------------------------------------------
// Greenplum Database
// Copyright (C) 2013 EMC Corp.
//
// @filename:
// CXformExpandFullOuterJoin.cpp
//
// @doc:
// Implementation of transform
//---------------------------------------------------------------------------
#include "gpopt/xforms/CXformExpandFullOuterJoin.h"
#include "gpos/base.h"
#include "gpopt/base/COptCtxt.h"
#include "gpopt/operators/CLogicalCTEAnchor.h"
#include "gpopt/operators/CLogicalCTEConsumer.h"
#include "gpopt/operators/CLogicalFullOuterJoin.h"
#include "gpopt/operators/CLogicalUnionAll.h"
#include "gpopt/operators/CPatternTree.h"
#include "gpopt/xforms/CXformUtils.h"
using namespace gpopt;
//---------------------------------------------------------------------------
// @function:
// CXformExpandFullOuterJoin::CXformExpandFullOuterJoin
//
// @doc:
// Ctor
//
//---------------------------------------------------------------------------
CXformExpandFullOuterJoin::CXformExpandFullOuterJoin(CMemoryPool *mp)
: CXformExploration(
// pattern
GPOS_NEW(mp) CExpression(
mp, GPOS_NEW(mp) CLogicalFullOuterJoin(mp),
GPOS_NEW(mp) CExpression(
mp, GPOS_NEW(mp) CPatternTree(mp)), // outer child
GPOS_NEW(mp) CExpression(
mp, GPOS_NEW(mp) CPatternTree(mp)), // inner child
GPOS_NEW(mp) CExpression(
mp, GPOS_NEW(mp) CPatternTree(mp)) // scalar child
))
{
}
//---------------------------------------------------------------------------
// @function:
// CXformExpandFullOuterJoin::Exfp
//
// @doc:
// Compute promise of xform
//
//---------------------------------------------------------------------------
CXform::EXformPromise
CXformExpandFullOuterJoin::Exfp(CExpressionHandle & //exprhdl
) const
{
return CXform::ExfpHigh;
}
//---------------------------------------------------------------------------
// @function:
// CXformExpandFullOuterJoin::Transform
//
// @doc:
// Actual transformation
// The expression A FOJ B is translated to:
//
// CTEAnchor(cteA)
// +-- CTEAnchor(cteB)
// +--UnionAll
// |-- LOJ
// | |-- CTEConsumer(cteA)
// | +-- CTEConsumer(cteB)
// +-- Project
// +-- LASJ
// | |-- CTEConsumer(cteB)
// | +-- CTEConsumer(cteA)
// +-- (NULLS - same schema of A)
//
// Also, two CTE producers for cteA and cteB are added to CTE info
//
//---------------------------------------------------------------------------
void
CXformExpandFullOuterJoin::Transform(CXformContext *pxfctxt,
CXformResult *pxfres,
CExpression *pexpr) const
{
GPOS_ASSERT(nullptr != pxfctxt);
GPOS_ASSERT(FPromising(pxfctxt->Pmp(), this, pexpr));
GPOS_ASSERT(FCheckPattern(pexpr));
CMemoryPool *mp = pxfctxt->Pmp();
CExpression *pexprA = (*pexpr)[0];
CExpression *pexprB = (*pexpr)[1];
CExpression *pexprScalar = (*pexpr)[2];
// 1. create the CTE producers
const ULONG ulCTEIdA = COptCtxt::PoctxtFromTLS()->Pcteinfo()->next_id();
CColRefArray *pdrgpcrOutA = pexprA->DeriveOutputColumns()->Pdrgpcr(mp);
(void) CXformUtils::PexprAddCTEProducer(mp, ulCTEIdA, pdrgpcrOutA, pexprA);
const ULONG ulCTEIdB = COptCtxt::PoctxtFromTLS()->Pcteinfo()->next_id();
CColRefArray *pdrgpcrOutB = pexprB->DeriveOutputColumns()->Pdrgpcr(mp);
(void) CXformUtils::PexprAddCTEProducer(mp, ulCTEIdB, pdrgpcrOutB, pexprB);
// 2. create the right child (PROJECT over LASJ)
CColRefArray *pdrgpcrRightA = CUtils::PdrgpcrCopy(mp, pdrgpcrOutA);
CColRefArray *pdrgpcrRightB = CUtils::PdrgpcrCopy(mp, pdrgpcrOutB);
CExpression *pexprScalarRight = CXformUtils::PexprRemapColumns(
mp, pexprScalar, pdrgpcrOutA, pdrgpcrRightA, pdrgpcrOutB,
pdrgpcrRightB);
CExpression *pexprLASJ = PexprLogicalJoinOverCTEs(
mp, EdxljtLeftAntiSemijoin, ulCTEIdB, pdrgpcrRightB, ulCTEIdA,
pdrgpcrRightA, pexprScalarRight);
CExpression *pexprProject =
CUtils::PexprLogicalProjectNulls(mp, pdrgpcrRightA, pexprLASJ);
// 3. create the left child (LOJ) - this has to use the original output
// columns and the original scalar expression
pexprScalar->AddRef();
CExpression *pexprLOJ =
PexprLogicalJoinOverCTEs(mp, EdxljtLeft, ulCTEIdA, pdrgpcrOutA,
ulCTEIdB, pdrgpcrOutB, pexprScalar);
// 4. create the UNION ALL expression
// output columns of the union are the same as the outputs of the first child (LOJ)
CColRefArray *pdrgpcrOutput = GPOS_NEW(mp) CColRefArray(mp);
pdrgpcrOutput->AppendArray(pdrgpcrOutA);
pdrgpcrOutput->AppendArray(pdrgpcrOutB);
// input columns of the union
CColRef2dArray *pdrgdrgpcrInput = GPOS_NEW(mp) CColRef2dArray(mp);
// inputs from the first child (LOJ)
pdrgpcrOutput->AddRef();
pdrgdrgpcrInput->Append(pdrgpcrOutput);
// inputs from the second child have to be in the correct order
// a. add new computed columns from the project only
CColRefSet *pcrsProjOnly = GPOS_NEW(mp) CColRefSet(mp);
pcrsProjOnly->Include(pexprProject->DeriveOutputColumns());
pcrsProjOnly->Exclude(pdrgpcrRightB);
CColRefArray *pdrgpcrProj = pcrsProjOnly->Pdrgpcr(mp);
pcrsProjOnly->Release();
// b. add columns from the LASJ expression
pdrgpcrProj->AppendArray(pdrgpcrRightB);
pdrgdrgpcrInput->Append(pdrgpcrProj);
CExpression *pexprUnionAll = GPOS_NEW(mp) CExpression(
mp, GPOS_NEW(mp) CLogicalUnionAll(mp, pdrgpcrOutput, pdrgdrgpcrInput),
pexprLOJ, pexprProject);
// 5. Add CTE anchor for the B subtree
CExpression *pexprAnchorB = GPOS_NEW(mp) CExpression(
mp, GPOS_NEW(mp) CLogicalCTEAnchor(mp, ulCTEIdB), pexprUnionAll);
// 6. Add CTE anchor for the A subtree
CExpression *pexprAnchorA = GPOS_NEW(mp) CExpression(
mp, GPOS_NEW(mp) CLogicalCTEAnchor(mp, ulCTEIdA), pexprAnchorB);
// add alternative to xform result
pxfres->Add(pexprAnchorA);
}
//---------------------------------------------------------------------------
// @function:
// CXformExpandFullOuterJoin::PexprLogicalJoinOverCTEs
//
// @doc:
// Construct a join expression of two CTEs using the given CTE ids
// and output columns
//
//---------------------------------------------------------------------------
CExpression *
CXformExpandFullOuterJoin::PexprLogicalJoinOverCTEs(
CMemoryPool *mp, EdxlJoinType edxljointype, ULONG ulLeftCTEId,
CColRefArray *pdrgpcrLeft, ULONG ulRightCTEId, CColRefArray *pdrgpcrRight,
CExpression *pexprScalar)
{
GPOS_ASSERT(nullptr != pexprScalar);
CExpressionArray *pdrgpexprChildren = GPOS_NEW(mp) CExpressionArray(mp);
CCTEInfo *pcteinfo = COptCtxt::PoctxtFromTLS()->Pcteinfo();
CLogicalCTEConsumer *popConsumerLeft =
GPOS_NEW(mp) CLogicalCTEConsumer(mp, ulLeftCTEId, pdrgpcrLeft);
CExpression *pexprLeft = GPOS_NEW(mp) CExpression(mp, popConsumerLeft);
pcteinfo->IncrementConsumers(ulLeftCTEId);
CLogicalCTEConsumer *popConsumerRight =
GPOS_NEW(mp) CLogicalCTEConsumer(mp, ulRightCTEId, pdrgpcrRight);
CExpression *pexprRight = GPOS_NEW(mp) CExpression(mp, popConsumerRight);
pcteinfo->IncrementConsumers(ulRightCTEId);
pdrgpexprChildren->Append(pexprLeft);
pdrgpexprChildren->Append(pexprRight);
pdrgpexprChildren->Append(pexprScalar);
return CUtils::PexprLogicalJoin(mp, edxljointype, pdrgpexprChildren);
}
// EOF
相关信息
相关文章
greenplumn CJoinOrderGreedy 源码
greenplumn CJoinOrderMinCard 源码
greenplumn CSubqueryHandler 源码
0
赞
热门推荐
-
2、 - 优质文章
-
3、 gate.io
-
7、 golang
-
9、 openharmony
-
10、 Vue中input框自动聚焦