greenplumn CXformRemoveSubqDistinct 源码
greenplumn CXformRemoveSubqDistinct 代码
文件路径:/src/backend/gporca/libgpopt/src/xforms/CXformRemoveSubqDistinct.cpp
//---------------------------------------------------------------------------
// Greenplum Database
// Copyright (C) 2017 VMware, Inc. or its affiliates.
//
// @filename:
// CXformRemoveSubqDistinct.cpp
//
// @doc:
// Implementation of the transform that removes distinct clause from subquery
//---------------------------------------------------------------------------
#include "gpopt/xforms/CXformRemoveSubqDistinct.h"
#include "gpos/base.h"
#include "gpopt/operators/CLogicalSelect.h"
#include "gpopt/operators/COperator.h"
#include "gpopt/operators/CPatternLeaf.h"
#include "gpopt/search/CGroupProxy.h"
#include "gpopt/xforms/CXformUtils.h"
using namespace gpopt;
CXformRemoveSubqDistinct::CXformRemoveSubqDistinct(CMemoryPool *mp)
: // pattern
CXformExploration(GPOS_NEW(mp) CExpression(
mp, GPOS_NEW(mp) CLogicalSelect(mp),
GPOS_NEW(mp) CExpression(
mp, GPOS_NEW(mp) CPatternLeaf(mp)), // relational child
GPOS_NEW(mp)
CExpression(mp, GPOS_NEW(mp) CPatternTree(mp)) // predicate tree
))
{
}
CXform::EXformPromise
CXformRemoveSubqDistinct::Exfp(CExpressionHandle &exprhdl) const
{
// consider this transformation only if subqueries exist
if (!exprhdl.DeriveHasSubquery(1))
{
return CXform::ExfpNone;
}
CGroupProxy gp((*exprhdl.Pgexpr())[1]);
CGroupExpression *pexprScalar = gp.PgexprFirst();
COperator *pop = pexprScalar->Pop();
if (CUtils::FQuantifiedSubquery(pop) || CUtils::FExistentialSubquery(pop))
{
return CXform::ExfpHigh;
}
return CXform::ExfpNone;
}
// For quantified subqueries (IN / NOT IN), the following transformation will be applied:
// CLogicalSelect
// |--CLogicalGet "foo"
// +--CScalarSubqueryAny(=)["c" (9)]
// |--CLogicalGbAgg( Global ) Grp Cols: ["c" (9)]
// | |--CLogicalGet "bar"
// | +--CScalarProjectList
// +--CScalarIdent "a" (0)
//
// will produce
//
// CLogicalSelect
// |--CLogicalGet "foo"
// +--CScalarSubqueryAny(=)["c" (9)]
// |--CLogicalGet "bar"
// +--CScalarIdent "a" (0)
//
// For existential subqueries (EXISTS / NOT EXISTS), the following transformation will be applied:
// CLogicalSelect
// |--CLogicalGet "foo"
// +--CScalarSubqueryExists
// +--CLogicalGbAgg( Global ) Grp Cols: ["c" (9)]
// |--CLogicalGet "bar"
// +--CScalarProjectList
//
// will produce
//
// CLogicalSelect
// |--CLogicalGet "foo"
// +--CScalarSubqueryExists
// +--CLogicalGet "bar"
//
void
CXformRemoveSubqDistinct::Transform(CXformContext *pxfctxt,
CXformResult *pxfres,
CExpression *pexpr) const
{
GPOS_ASSERT(nullptr != pxfctxt);
GPOS_ASSERT(nullptr != pxfres);
GPOS_ASSERT(FCheckPattern(pexpr));
CMemoryPool *mp = pxfctxt->Pmp();
CExpression *pexprScalar = (*pexpr)[1];
CExpression *pexprGbAgg = (*pexprScalar)[0];
if (COperator::EopLogicalGbAgg == pexprGbAgg->Pop()->Eopid())
{
CExpression *pexprGbAggProjectList = (*pexprGbAgg)[1];
// only consider removing distinct when there is no aggregation functions
if (0 == pexprGbAggProjectList->Arity())
{
CExpression *pexprNewScalar = nullptr;
CExpression *pexprRelChild = (*pexprGbAgg)[0];
pexprRelChild->AddRef();
COperator *pop = pexprScalar->Pop();
pop->AddRef();
if (CUtils::FExistentialSubquery(pop))
{
// EXIST/NOT EXIST scalar subquery
pexprNewScalar =
GPOS_NEW(mp) CExpression(mp, pop, pexprRelChild);
}
else
{
// IN/NOT IN scalar subquery
CExpression *pexprScalarIdent = (*pexprScalar)[1];
pexprScalarIdent->AddRef();
pexprNewScalar = GPOS_NEW(mp)
CExpression(mp, pop, pexprRelChild, pexprScalarIdent);
}
pexpr->Pop()->AddRef(); // logical select operator
(*pexpr)[0]->AddRef(); // relational child of logical select
// new logical select expression
CExpression *ppexprNew = GPOS_NEW(mp)
CExpression(mp, pexpr->Pop(), (*pexpr)[0], pexprNewScalar);
pxfres->Add(ppexprNew);
}
}
}
// EOF
相关信息
相关文章
greenplumn CJoinOrderGreedy 源码
greenplumn CJoinOrderMinCard 源码
greenplumn CSubqueryHandler 源码
0
赞
热门推荐
-
2、 - 优质文章
-
3、 gate.io
-
7、 golang
-
9、 openharmony
-
10、 Vue中input框自动聚焦