greenplumn CLogicalSelect 源码
greenplumn CLogicalSelect 代码
文件路径:/src/backend/gporca/libgpopt/src/operators/CLogicalSelect.cpp
//---------------------------------------------------------------------------
// Greenplum Database
// Copyright (C) 2011 EMC Corp.
//
// @filename:
// CLogicalSelect.cpp
//
// @doc:
// Implementation of select operator
//---------------------------------------------------------------------------
#include "gpopt/operators/CLogicalSelect.h"
#include "gpos/base.h"
#include "gpopt/base/CColRefSet.h"
#include "gpopt/base/CColRefSetIter.h"
#include "gpopt/base/CColRefTable.h"
#include "gpopt/base/COptCtxt.h"
#include "gpopt/operators/CExpression.h"
#include "gpopt/operators/CExpressionHandle.h"
#include "gpopt/operators/CPatternTree.h"
#include "gpopt/operators/CPredicateUtils.h"
#include "naucrates/statistics/CFilterStatsProcessor.h"
#include "naucrates/statistics/CStatisticsUtils.h"
using namespace gpopt;
//---------------------------------------------------------------------------
// @function:
// CLogicalSelect::CLogicalSelect
//
// @doc:
// Ctor
//
//---------------------------------------------------------------------------
CLogicalSelect::CLogicalSelect(CMemoryPool *mp)
: CLogicalUnary(mp), m_ptabdesc(nullptr)
{
m_phmPexprPartPred = GPOS_NEW(mp) ExprPredToExprPredPartMap(mp);
}
CLogicalSelect::CLogicalSelect(CMemoryPool *mp, CTableDescriptor *ptabdesc)
: CLogicalUnary(mp), m_ptabdesc(ptabdesc)
{
m_phmPexprPartPred = GPOS_NEW(mp) ExprPredToExprPredPartMap(mp);
}
CLogicalSelect::~CLogicalSelect()
{
m_phmPexprPartPred->Release();
}
//---------------------------------------------------------------------------
// @function:
// CLogicalSelect::DeriveOutputColumns
//
// @doc:
// Derive output columns
//
//---------------------------------------------------------------------------
CColRefSet *
CLogicalSelect::DeriveOutputColumns(CMemoryPool *, // mp
CExpressionHandle &exprhdl)
{
return PcrsDeriveOutputPassThru(exprhdl);
}
//---------------------------------------------------------------------------
// @function:
// CLogicalSelect::PkcDeriveKeys
//
// @doc:
// Derive key collection
//
//---------------------------------------------------------------------------
CKeyCollection *
CLogicalSelect::DeriveKeyCollection(CMemoryPool *, // mp
CExpressionHandle &exprhdl) const
{
return PkcDeriveKeysPassThru(exprhdl, 0 /* ulChild */);
}
//---------------------------------------------------------------------------
// @function:
// CLogicalSelect::PxfsCandidates
//
// @doc:
// Get candidate xforms
//
//---------------------------------------------------------------------------
CXformSet *
CLogicalSelect::PxfsCandidates(CMemoryPool *mp) const
{
CXformSet *xform_set = GPOS_NEW(mp) CXformSet(mp);
(void) xform_set->ExchangeSet(CXform::ExfSelect2Apply);
(void) xform_set->ExchangeSet(CXform::ExfRemoveSubqDistinct);
(void) xform_set->ExchangeSet(CXform::ExfInlineCTEConsumerUnderSelect);
(void) xform_set->ExchangeSet(CXform::ExfPushGbWithHavingBelowJoin);
(void) xform_set->ExchangeSet(CXform::ExfSelect2IndexGet);
(void) xform_set->ExchangeSet(CXform::ExfSelect2DynamicIndexGet);
(void) xform_set->ExchangeSet(CXform::ExfSelect2BitmapBoolOp);
(void) xform_set->ExchangeSet(CXform::ExfSelect2DynamicBitmapBoolOp);
(void) xform_set->ExchangeSet(CXform::ExfSimplifySelectWithSubquery);
(void) xform_set->ExchangeSet(CXform::ExfSelect2Filter);
return xform_set;
}
//---------------------------------------------------------------------------
// @function:
// CLogicalSelect::DeriveMaxCard
//
// @doc:
// Derive max card
//
//---------------------------------------------------------------------------
CMaxCard
CLogicalSelect::DeriveMaxCard(CMemoryPool *, // mp
CExpressionHandle &exprhdl) const
{
// in case of a false condition or a contradiction, maxcard should be zero
CExpression *pexprScalar = exprhdl.PexprScalarRepChild(1);
if ((nullptr != pexprScalar &&
(CUtils::FScalarConstFalse(pexprScalar) ||
CUtils::FScalarConstBoolNull(pexprScalar))) ||
exprhdl.DerivePropertyConstraint()->FContradiction())
{
return CMaxCard(0 /*ull*/);
}
// pass on max card of first child
return exprhdl.DeriveMaxCard(0);
}
//---------------------------------------------------------------------------
// @function:
// CLogicalSelect::PstatsDerive
//
// @doc:
// Derive statistics based on filter predicates
//
//---------------------------------------------------------------------------
IStatistics *
CLogicalSelect::PstatsDerive(CMemoryPool *mp, CExpressionHandle &exprhdl,
IStatisticsArray *stats_ctxt) const
{
GPOS_ASSERT(Esp(exprhdl) > EspNone);
IStatistics *child_stats = exprhdl.Pstats(0);
if (exprhdl.DeriveHasSubquery(1))
{
// in case of subquery in select predicate, we return child stats
child_stats->AddRef();
return child_stats;
}
// remove implied predicates from selection condition to avoid cardinality under-estimation
CExpression *pexprScalar = exprhdl.PexprScalarRepChild(1 /*child_index*/);
CExpression *pexprPredicate =
CPredicateUtils::PexprRemoveImpliedConjuncts(mp, pexprScalar, exprhdl);
// split selection predicate into local predicate and predicate involving outer references
CExpression *local_expr = nullptr;
CExpression *expr_with_outer_refs = nullptr;
// get outer references from expression handle
CColRefSet *outer_refs = exprhdl.DeriveOuterReferences();
CPredicateUtils::SeparateOuterRefs(mp, pexprPredicate, outer_refs,
&local_expr, &expr_with_outer_refs);
pexprPredicate->Release();
IStatistics *stats = CFilterStatsProcessor::MakeStatsFilterForScalarExpr(
mp, exprhdl, child_stats, local_expr, expr_with_outer_refs, stats_ctxt);
local_expr->Release();
expr_with_outer_refs->Release();
return stats;
}
// compute partition predicate to pass down to n-th child.
// given an input scalar expression, find out the predicate
// in the scalar expression which is used for partitioning
//
// clang-format off
// Input Expr:
// +--CScalarBoolOp (EboolopAnd)
// |--CScalarArrayCmp Any (=)
// | |--CScalarIdent "risk_set_row_id" (2)
// | +--CScalarArray: {eleMDId: (23,1.0), arrayMDId: (1007,1.0) CScalarConst (32) CScalarConst (33) CScalarConst (43) CScalarConst (9) CScalarConst (10) CScalarConst (15) CScalarConst (16) CScalarConst (36) CScalarConst (11) CScalarConst (50) CScalarConst (46) CScalarConst (356) CScalarConst (468) CScalarConst (42)}
// +--CScalarCmp (=)
// |--CScalarIdent "value_date" (0)
// +--CScalarConst (559094400000000.000)
//
// Let's say the partition key is on value_date, then the extracted
// predicate is as below:
// Output Expr:
// +--CScalarCmp (=)
// |--CScalarIdent "value_date" (0)
// +--CScalarConst (559094400000000.000)
// clang-format on
CExpression *
CLogicalSelect::PexprPartPred(CMemoryPool *mp, CExpressionHandle &exprhdl,
CExpression *, //pexprInput
ULONG
#ifdef GPOS_DEBUG
child_index
#endif //GPOS_DEBUG
) const
{
GPOS_ASSERT(0 == child_index);
CExpression *pexprScalar = exprhdl.PexprScalarExactChild(1 /*child_index*/);
if (nullptr == pexprScalar)
{
// no exact predicate is available (e.g. when we have a subquery in the predicate)
return nullptr;
}
// get partition keys
CPartInfo *ppartinfo = exprhdl.DerivePartitionInfo();
GPOS_ASSERT(nullptr != ppartinfo);
// we assume that the select is right on top of the dynamic get, so there
// should be only one part consumer. If there is more, then we are higher up so
// we do not push down any predicates
if (1 != ppartinfo->UlConsumers())
{
return nullptr;
}
// check if a corresponding predicate has already been cached
CExpression *pexprPredOnPartKey = m_phmPexprPartPred->Find(pexprScalar);
if (pexprPredOnPartKey != nullptr)
{
// predicate on partition key found in cache
pexprPredOnPartKey->AddRef();
return pexprPredOnPartKey;
}
CPartKeysArray *pdrgppartkeys = ppartinfo->Pdrgppartkeys(0 /*ulPos*/);
const ULONG ulKeySets = pdrgppartkeys->Size();
for (ULONG ul = 0; nullptr == pexprPredOnPartKey && ul < ulKeySets; ul++)
{
pexprPredOnPartKey = CPredicateUtils::PexprExtractPredicatesOnPartKeys(
mp, pexprScalar, (*pdrgppartkeys)[ul]->Pdrgpdrgpcr(),
nullptr, //pcrsAllowedRefs
true //fUseConstraints
);
}
if (pexprPredOnPartKey != nullptr)
{
// insert the scalar expression and the corresponding partitioning predicate
// in the hashmap
pexprPredOnPartKey->AddRef();
pexprScalar->AddRef();
m_phmPexprPartPred->Insert(pexprScalar, pexprPredOnPartKey);
}
return pexprPredOnPartKey;
}
// EOF
相关信息
相关文章
greenplumn CExpressionFactorizer 源码
greenplumn CExpressionHandle 源码
greenplumn CExpressionPreprocessor 源码
greenplumn CExpressionUtils 源码
0
赞
热门推荐
-
2、 - 优质文章
-
3、 gate.io
-
7、 golang
-
9、 openharmony
-
10、 Vue中input框自动聚焦