greenplumn CScalarProjectList 源码
greenplumn CScalarProjectList 代码
文件路径:/src/backend/gporca/libgpopt/src/operators/CScalarProjectList.cpp
//---------------------------------------------------------------------------
// Greenplum Database
// Copyright (C) 2009 Greenplum, Inc.
//
// @filename:
// CScalarProjectList.cpp
//
// @doc:
// Implementation of scalar projection list operator
//---------------------------------------------------------------------------
#include "gpopt/operators/CScalarProjectList.h"
#include "gpos/base.h"
#include "gpos/memory/CAutoMemoryPool.h"
#include "gpopt/base/CColRefSet.h"
#include "gpopt/base/CDrvdPropScalar.h"
#include "gpopt/operators/CExpressionHandle.h"
#include "gpopt/operators/CScalarWindowFunc.h"
#include "gpopt/xforms/CXformUtils.h"
using namespace gpopt;
//---------------------------------------------------------------------------
// @function:
// CScalarProjectList::CScalarProjectList
//
// @doc:
// ctor
//
//---------------------------------------------------------------------------
CScalarProjectList::CScalarProjectList(CMemoryPool *mp) : CScalar(mp)
{
}
//---------------------------------------------------------------------------
// @function:
// CScalarProjectList::Matches
//
// @doc:
// Match function on operator level
//
//---------------------------------------------------------------------------
BOOL
CScalarProjectList::Matches(COperator *pop) const
{
return (pop->Eopid() == Eopid());
}
//---------------------------------------------------------------------------
// @function:
// CScalarProjectList::FInputOrderSensitive
//
// @doc:
// Prjection lists are insensitive to order; no dependencies between
// elements;
//
//---------------------------------------------------------------------------
BOOL
CScalarProjectList::FInputOrderSensitive() const
{
return false;
}
//---------------------------------------------------------------------------
// @function:
// CScalarProjectList::UlDistinctAggs
//
// @doc:
// Return number of Distinct Aggs in the given project list
//
//---------------------------------------------------------------------------
ULONG
CScalarProjectList::UlDistinctAggs(CExpressionHandle &exprhdl)
{
// We make do with an inexact representative expression returned by exprhdl.PexprScalarRep(),
// knowing that at this time, aggregate functions are accurately contained in it. What's not
// exact are subqueries. This is better than just returning 0 for project lists with subqueries.
CExpression *pexprPrjList = exprhdl.PexprScalarRep();
GPOS_ASSERT(nullptr != pexprPrjList);
GPOS_ASSERT(COperator::EopScalarProjectList ==
pexprPrjList->Pop()->Eopid());
ULONG ulDistinctAggs = 0;
const ULONG arity = pexprPrjList->Arity();
for (ULONG ul = 0; ul < arity; ul++)
{
CExpression *pexprPrjEl = (*pexprPrjList)[ul];
CExpression *pexprChild = (*pexprPrjEl)[0];
COperator::EOperatorId eopidChild = pexprChild->Pop()->Eopid();
if (COperator::EopScalarAggFunc == eopidChild)
{
CScalarAggFunc *popScAggFunc =
CScalarAggFunc::PopConvert(pexprChild->Pop());
if (popScAggFunc->IsDistinct())
{
ulDistinctAggs++;
}
}
else if (COperator::EopScalarWindowFunc == eopidChild)
{
CScalarWindowFunc *popScWinFunc =
CScalarWindowFunc::PopConvert(pexprChild->Pop());
if (popScWinFunc->IsDistinct() && popScWinFunc->FAgg())
{
ulDistinctAggs++;
}
}
}
return ulDistinctAggs;
}
ULONG
CScalarProjectList::UlOrderedAggs(CExpressionHandle &exprhdl)
{
// We make do with an inexact representative expression returned by exprhdl.PexprScalarRep(),
// knowing that at this time, aggregate functions are accurately contained in it. What's not
// exact are subqueries. This is better than just returning 0 for project lists with subqueries.
CExpression *pexprPrjList = exprhdl.PexprScalarRep();
GPOS_ASSERT(nullptr != pexprPrjList);
GPOS_ASSERT(COperator::EopScalarProjectList ==
pexprPrjList->Pop()->Eopid());
ULONG ulOrderedAggs = 0;
const ULONG arity = pexprPrjList->Arity();
for (ULONG ul = 0; ul < arity; ul++)
{
CExpression *pexprPrjEl = (*pexprPrjList)[ul];
CExpression *pexprChild = (*pexprPrjEl)[0];
COperator::EOperatorId eopidChild = pexprChild->Pop()->Eopid();
if (COperator::EopScalarAggFunc == eopidChild)
{
if (CUtils::FHasOrderedAggToSplit(pexprChild))
{
ulOrderedAggs++;
}
}
}
return ulOrderedAggs;
}
//---------------------------------------------------------------------------
// @function:
// CScalarProjectList::FHasMultipleDistinctAggs
//
// @doc:
// Check if given project list has multiple distinct aggregates, for example:
// select count(distinct a), sum(distinct b) from T;
//
// select count(distinct a) over(), sum(distinct b) over() from T;
//
//---------------------------------------------------------------------------
BOOL
CScalarProjectList::FHasMultipleDistinctAggs(CExpressionHandle &exprhdl)
{
// We make do with an inexact representative expression returned by exprhdl.PexprScalarRep(),
// knowing that at this time, aggregate functions are accurately contained in it. What's not
// exact are subqueries. This is better than just returning false for project lists with subqueries.
CExpression *pexprPrjList = exprhdl.PexprScalarRep();
GPOS_ASSERT(COperator::EopScalarProjectList ==
pexprPrjList->Pop()->Eopid());
if (0 == UlDistinctAggs(exprhdl))
{
return false;
}
CAutoMemoryPool amp;
ExprToExprArrayMap *phmexprdrgpexpr = nullptr;
ULONG ulDifferentDQAs = 0;
CXformUtils::MapPrjElemsWithDistinctAggs(
amp.Pmp(), pexprPrjList, &phmexprdrgpexpr, &ulDifferentDQAs);
phmexprdrgpexpr->Release();
return (1 < ulDifferentDQAs);
}
//---------------------------------------------------------------------------
// @function:
// CScalarProjectList::FHasScalarFunc
//
// @doc:
// Check if given project list has a scalar func, for example:
// select random() from T;
//
//---------------------------------------------------------------------------
BOOL
CScalarProjectList::FHasScalarFunc(CExpressionHandle &exprhdl)
{
// We make do with an inexact representative expression returned by exprhdl.PexprScalarRep(),
// knowing that at this time, aggregate functions are accurately contained in it. What's not
// exact are subqueries. This is better than just returning 0 for project lists with subqueries.
CExpression *pexprPrjList = exprhdl.PexprScalarRep();
GPOS_ASSERT(nullptr != pexprPrjList);
GPOS_ASSERT(COperator::EopScalarProjectList ==
pexprPrjList->Pop()->Eopid());
const ULONG arity = pexprPrjList->Arity();
for (ULONG ul = 0; ul < arity; ul++)
{
CExpression *pexprPrjEl = (*pexprPrjList)[ul];
CExpression *pexprChild = (*pexprPrjEl)[0];
COperator::EOperatorId eopidChild = pexprChild->Pop()->Eopid();
if (COperator::EopScalarFunc == eopidChild)
{
return true;
}
}
return false;
}
// EOF
相关信息
相关文章
greenplumn CExpressionFactorizer 源码
greenplumn CExpressionHandle 源码
greenplumn CExpressionPreprocessor 源码
greenplumn CExpressionUtils 源码
0
赞
热门推荐
-
2、 - 优质文章
-
3、 gate.io
-
7、 golang
-
9、 openharmony
-
10、 Vue中input框自动聚焦