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