greenplumn CPredicateUtils 源码
greenplumn CPredicateUtils 代码
文件路径:/src/backend/gporca/libgpopt/include/gpopt/operators/CPredicateUtils.h
//---------------------------------------------------------------------------
// Greenplum Database
// Copyright 2011 EMC Corp.
//
// @filename:
// CPredicateUtils.h
//
// @doc:
// Utility functions for normalizing scalar predicates
//---------------------------------------------------------------------------
#ifndef GPOPT_CPredicateUtils_H
#define GPOPT_CPredicateUtils_H
#include "gpos/base.h"
#include "gpopt/base/CUtils.h"
#include "gpopt/mdcache/CMDAccessor.h"
#include "gpopt/operators/CExpression.h"
#include "gpopt/operators/CScalarBoolOp.h"
namespace gpopt
{
using namespace gpos;
// fwd decl
class CConstraintInterval;
//---------------------------------------------------------------------------
// @class:
// CPredicateUtils
//
// @doc:
// Utility functions for normalizing scalar predicates
//
//---------------------------------------------------------------------------
class CPredicateUtils
{
private:
// collect conjuncts recursively
static void CollectConjuncts(CExpression *pexpr,
CExpressionArray *pdrgpexpr);
// collect disjuncts recursively
static void CollectDisjuncts(CExpression *pexpr,
CExpressionArray *pdrgpexpr);
// check if a conjunct/disjunct can be skipped
static BOOL FSkippable(CExpression *pexpr, BOOL fConjunction);
// check if a conjunction/disjunction can be reduced to a constant True/False
static BOOL FReducible(CExpression *pexpr, BOOL fConjunction);
// check if given expression is a comparison over the given column
static BOOL FComparison(CExpression *pexpr, CColRef *colref,
CColRefSet *pcrsAllowedRefs);
// check whether the given expression contains references to only the given
// columns. If pcrsAllowedRefs is NULL, then check whether the expression has
// no column references and no volatile functions
static BOOL FValidRefsOnly(CExpression *pexprScalar,
CColRefSet *pcrsAllowedRefs);
// determine which predicates we should test implication for
static BOOL FCheckPredicateImplication(CExpression *pexprPred);
// check if predicate is implied by given equivalence classes
static BOOL FImpliedPredicate(CExpression *pexprPred,
CColRefSetArray *pdrgpcrsEquivClasses);
// helper to create index lookup comparison predicate with index key on left side
static CExpression *PexprIndexLookupKeyOnLeft(CMemoryPool *mp,
CMDAccessor *md_accessor,
CExpression *pexprScalar,
const IMDIndex *pmdindex,
CColRefArray *pdrgpcrIndex,
CColRefSet *outer_refs);
// helper to create index lookup comparison predicate with index key on right side
static CExpression *PexprIndexLookupKeyOnRight(CMemoryPool *mp,
CMDAccessor *md_accessor,
CExpression *pexprScalar,
const IMDIndex *pmdindex,
CColRefArray *pdrgpcrIndex,
CColRefSet *outer_refs);
// for all columns that appear in the given expression and are members
// of the given set, replace these columns with NULL constants
static CExpression *PexprReplaceColsWithNulls(CMemoryPool *mp,
CExpression *pexprScalar,
CColRefSet *pcrs);
public:
// private dtor
virtual ~CPredicateUtils() = delete;
// private ctor
CPredicateUtils() = delete;
CPredicateUtils(const CPredicateUtils &) = delete;
// reverse the comparison, for example "<" => ">", "<=" => "=>
static IMDType::ECmpType EcmptReverse(IMDType::ECmpType cmp_type);
// check if the expression is a boolean scalar identifier
static BOOL FBooleanScalarIdent(CExpression *pexprPred);
// check if the expression is a negated boolean scalar identifier
static BOOL FNegatedBooleanScalarIdent(CExpression *pexprPred);
// is the given expression an equality comparison
static BOOL IsEqualityOp(CExpression *pexpr);
// is the given expression a scalar comparison
static BOOL FComparison(CExpression *pexpr);
// is the given expression a conjunction of equality comparisons
static BOOL FConjunctionOfEqComparisons(CMemoryPool *mp,
CExpression *pexpr);
// is the given expression a comparison of the given type
static BOOL FComparison(CExpression *pexpr, IMDType::ECmpType cmp_type);
// is the given array of expressions contain a volatile function like random()
static BOOL FContainsVolatileFunction(CExpressionArray *pdrgpexpr);
// is the given expressions contain a volatile function like random()
static BOOL FContainsVolatileFunction(CExpression *pexpr);
// is the given expression an equality comparison over two scalar identifiers
static BOOL FPlainEquality(CExpression *pexpr);
// is the given expression a self comparison on some column
static BOOL FSelfComparison(CExpression *pexpr, IMDType::ECmpType *pecmpt);
// eliminate self comparison if possible
static CExpression *PexprEliminateSelfComparison(CMemoryPool *mp,
CExpression *pexpr);
// is the given expression in the form (col1 Is NOT DISTINCT FROM col2)
static BOOL FINDFScalarIdents(CExpression *pexpr);
// is the given expression in the form (col1 IS DISTINCT FROM col2)
static BOOL FIDFScalarIdents(CExpression *pexpr);
// check if expression is an Is DISTINCT FROM FALSE expression
static BOOL FIDFFalse(CExpression *pexpr);
static BOOL FCompareScalarIdentToConstAndScalarIdentArray(
CExpression *pexpr);
// is the given expression in the form (expr IS DISTINCT FROM expr)
static BOOL FIDF(CExpression *pexpr);
// is the given expression in the form (expr IS NOT DISTINCT FROM expr)
static BOOL FINDF(CExpression *pexpr);
// generate a conjunction of INDF expressions between corresponding columns in the given arrays
static CExpression *PexprINDFConjunction(CMemoryPool *mp,
CColRefArray *pdrgpcrFirst,
CColRefArray *pdrgpcrSecond);
// is the given expression of the form (col CMP/IS DISTINCT/IS NOT DISTINCT FROM constant)
// either the constant or the column can be casted
static BOOL FIdentCompareConstIgnoreCast(CExpression *pexpr,
COperator::EOperatorId);
// check if a given expression is a comparison between a column and an expression
// using only constants and one or more outer references from a given ColRefSet,
// it optionally returns the colref of the local table
static BOOL FIdentCompareOuterRefExprIgnoreCast(
CExpression *pexpr, CColRefSet *pcrsOuterRefs,
CColRef **localColRef = nullptr);
// is the given expression a comparison between scalar ident and a const array
// either the ident or constant array can be casted
static BOOL FArrayCompareIdentToConstIgnoreCast(CExpression *pexpr);
// is the given expression of the form (col IS DISTINCT FROM constant)
// either the constant or the column can be casted
static BOOL FIdentIDFConstIgnoreCast(CExpression *pexpr);
// is the given expression of the form NOT (col IS DISTINCT FROM constant)
// either the constant or the column can be casted
static BOOL FIdentINDFConstIgnoreCast(CExpression *pexpr);
// is the given expression a comparison between a scalar ident and a constant
static BOOL FCompareIdentToConst(CExpression *pexpr);
// is the given expression a comparison between a const and a const
static BOOL FCompareConstToConstIgnoreCast(CExpression *pexpr);
// is the given expression of the form (col IS DISTINCT FROM const)
static BOOL FIdentIDFConst(CExpression *pexpr);
static BOOL FEqIdentsOfSameType(CExpression *pexpr);
// checks if comparison is between two columns, or a column and a const
static BOOL FCompareColToConstOrCol(CExpression *pexprScalar);
// is the given expression a comparison between a scalar ident under a scalar cast and a constant array
static BOOL FCompareCastIdentToConstArray(CExpression *pexpr);
// is the given expression a comparison between a scalar ident and a constant array
static BOOL FCompareIdentToConstArray(CExpression *pexpr);
// is the given expression an AND
static BOOL
FAnd(CExpression *pexpr)
{
return CUtils::FScalarBoolOp(pexpr, CScalarBoolOp::EboolopAnd);
}
// is the given expression an OR
static BOOL
FOr(CExpression *pexpr)
{
return CUtils::FScalarBoolOp(pexpr, CScalarBoolOp::EboolopOr);
}
// does the given expression have any NOT children?
// is the given expression a NOT
static BOOL
FNot(CExpression *pexpr)
{
return CUtils::FScalarBoolOp(pexpr, CScalarBoolOp::EboolopNot);
}
// returns true iff the given expression is a Not operator whose child is a
// scalar identifier
static BOOL FNotIdent(CExpression *pexpr);
// does the given expression have any NOT children?
static BOOL FHasNegatedChild(CExpression *pexpr);
// is the given expression an inner join or NAry join
static BOOL
FInnerOrNAryJoin(CExpression *pexpr)
{
return COperator::EopLogicalInnerJoin == pexpr->Pop()->Eopid() ||
COperator::EopLogicalNAryJoin == pexpr->Pop()->Eopid();
}
static BOOL
FLeftOuterJoin(CExpression *pexpr)
{
return COperator::EopLogicalLeftOuterJoin == pexpr->Pop()->Eopid();
}
// is the given expression either a union or union all operator
static BOOL
FUnionOrUnionAll(CExpression *pexpr)
{
return COperator::EopLogicalUnion == pexpr->Pop()->Eopid() ||
COperator::EopLogicalUnionAll == pexpr->Pop()->Eopid();
}
// check if we can collapse the nth child of the given union / union all operator
static BOOL FCollapsibleChildUnionUnionAll(CExpression *pexprParent,
ULONG child_index);
// if the nth child of the given union/union all expression is also an union / union all expression,
// then collect the later's children and set the input columns of the new n-ary union/unionall operator
static void CollectGrandChildrenUnionUnionAll(
CMemoryPool *mp, CExpression *pexpr, ULONG child_index,
CExpressionArray *pdrgpexprResult, CColRef2dArray *pdrgdrgpcrResult);
// extract conjuncts from a scalar tree
static CExpressionArray *PdrgpexprConjuncts(CMemoryPool *mp,
CExpression *pexpr);
// extract disjuncts from a scalar tree
static CExpressionArray *PdrgpexprDisjuncts(CMemoryPool *mp,
CExpression *pexpr);
// extract equality predicates on scalar identifier from a list of scalar expressions
static CExpressionArray *PdrgpexprPlainEqualities(
CMemoryPool *mp, CExpressionArray *pdrgpexpr);
// create conjunction/disjunction
static CExpression *PexprConjDisj(CMemoryPool *mp,
CExpressionArray *Pdrgpexpr,
BOOL fConjunction);
// create conjunction/disjunction of two expressions
static CExpression *PexprConjDisj(CMemoryPool *mp, CExpression *pexprOne,
CExpression *pexprTwo, BOOL fConjunction);
// create conjunction
static CExpression *PexprConjunction(CMemoryPool *mp,
CExpressionArray *pdrgpexpr);
// create conjunction of two expressions
static CExpression *PexprConjunction(CMemoryPool *mp, CExpression *pexprOne,
CExpression *pexprTwo);
// create disjunction of two expressions
static CExpression *PexprDisjunction(CMemoryPool *mp, CExpression *pexprOne,
CExpression *pexprTwo);
// expand disjuncts in the given array by converting ArrayComparison to AND/OR tree and deduplicating resulting disjuncts
static CExpressionArray *PdrgpexprExpandDisjuncts(
CMemoryPool *mp, CExpressionArray *pdrgpexprDisjuncts);
// expand conjuncts in the given array by converting ArrayComparison to AND/OR tree and deduplicating resulting conjuncts
static CExpressionArray *PdrgpexprExpandConjuncts(
CMemoryPool *mp, CExpressionArray *pdrgpexprConjuncts);
// check if the given expression is a boolean expression on the
// given column, e.g. if its of the form "ScalarIdent(colref)" or
// "Not(ScalarIdent(colref))"
static BOOL FBoolPredicateOnColumn(CExpression *pexpr, CColRef *colref);
// check if the given expression is a scalar array cmp expression on the
// given column
static BOOL FScArrayCmpOnColumn(CExpression *pexpr, CColRef *colref,
BOOL fConstOnly);
// check if the given expression is a null check on the given column
// i.e. "is null" or "is not null"
static BOOL FNullCheckOnColumn(CExpression *pexpr, CColRef *colref);
// check if the given expression of the form "col is not null"
static BOOL FNotNullCheckOnColumn(CExpression *pexpr, CColRef *colref);
// check if the given expression is a disjunction of scalar cmp
// expressions on the given column
static BOOL IsDisjunctionOfRangeComparison(CMemoryPool *mp,
CExpression *pexpr,
CColRef *colref,
CColRefSet *pcrsAllowedRefs,
BOOL allowNotEqualPreds);
// check if the given comparison type is one of the range comparisons, i.e.
// LT, GT, LEq, GEq, Eq
static BOOL FRangeComparison(CExpression *expr, CColRef *colref,
CColRefSet *pcrsAllowedRefs,
BOOL allowNotEqualPreds);
// create disjunction
static CExpression *PexprDisjunction(CMemoryPool *mp,
CExpressionArray *Pdrgpexpr);
static CExpression *ValidatePartPruningExpr(CMemoryPool *mp,
CExpression *expr,
CColRef *pcrPartKey,
CColRefSet *pcrsAllowedRefs,
BOOL allow_not_equals_preds);
// find a predicate that can be used for partition pruning with the given part key
static CExpression *PexprPartPruningPredicate(
CMemoryPool *mp, const CExpressionArray *pdrgpexpr, CColRef *pcrPartKey,
CExpression *pexprCol, CColRefSet *pcrsAllowedRefs,
BOOL allowNotEqualPreds);
// append the conjuncts from the given expression to the given array, removing
// any duplicates, and return the resulting array
static CExpressionArray *PdrgpexprAppendConjunctsDedup(
CMemoryPool *mp, CExpressionArray *pdrgpexpr, CExpression *pexpr);
// extract interesting conditions involving the partitioning keys
static CExpression *PexprExtractPredicatesOnPartKeys(
CMemoryPool *mp, CExpression *pexprScalar,
CColRef2dArray *pdrgpdrgpcrPartKeys, CColRefSet *pcrsAllowedRefs,
BOOL fUseConstraints, const IMDRelation *pmdrel = nullptr);
// extract the constraint on the given column and return the corresponding
// scalar expression
static CExpression *PexprPredicateCol(CMemoryPool *mp, CConstraint *pcnstr,
CColRef *colref,
BOOL fUseConstraints);
// extract components of a comparison expression on the given key
static void ExtractComponents(CExpression *pexprScCmp, CColRef *pcrKey,
CExpression **ppexprKey,
CExpression **ppexprOther,
IMDType::ECmpType *pecmpt);
// Expression is a comparison with a simple identifer on at least one side
static BOOL FIdentCompare(CExpression *pexpr, IMDType::ECmpType pecmpt,
CColRef *colref);
// check if given column is a constant
static BOOL FConstColumn(CConstraint *pcnstr, const CColRef *colref);
// check if given column is a disjunction of constants
static BOOL FColumnDisjunctionOfConst(CConstraint *pcnstr,
const CColRef *colref);
// check if given column is a disjunction of constants
static BOOL FColumnDisjunctionOfConst(CConstraintInterval *pcnstr,
const CColRef *colref);
// split predicates into those that refer to an index key, and those that don't
static void ExtractIndexPredicates(
CMemoryPool *mp, CMDAccessor *md_accessor,
CExpressionArray *pdrgpexprPredicate, const IMDIndex *pmdindex,
CColRefArray *pdrgpcrIndex, CExpressionArray *pdrgpexprIndex,
CExpressionArray *pdrgpexprResidual,
CColRefSet *pcrsAcceptedOuterRefs =
nullptr, // outer refs that are acceptable in an index predicate
BOOL allowArrayCmpForBTreeIndexes = false);
// return the inverse of given comparison expression
static CExpression *PexprInverseComparison(CMemoryPool *mp,
CExpression *pexprCmp);
// prune unnecessary equality operations
static CExpression *PexprPruneSuperfluosEquality(CMemoryPool *mp,
CExpression *pexpr);
// remove conjuncts that are implied based on child columns equivalence classes
static CExpression *PexprRemoveImpliedConjuncts(CMemoryPool *mp,
CExpression *pexprScalar,
CExpressionHandle &exprhdl);
// check if given correlations are valid for semi join operator;
static BOOL FValidSemiJoinCorrelations(
CMemoryPool *mp, CExpression *pexprOuter, CExpression *pexprInner,
CExpressionArray *pdrgpexprCorrelations);
// check if given expression is composed of simple column equalities that use columns from given column set
static BOOL FSimpleEqualityUsingCols(CMemoryPool *mp,
CExpression *pexprScalar,
CColRefSet *pcrs);
// check if given expression is a valid index lookup predicate
// return (modified) predicate suited for index lookup
static CExpression *PexprIndexLookup(
CMemoryPool *mp, CMDAccessor *md_accessor, CExpression *pexpPred,
const IMDIndex *pmdindex, CColRefArray *pdrgpcrIndex,
CColRefSet *outer_refs, BOOL allowArrayCmpForBTreeIndexes);
// split given scalar expression into two conjunctions; without and with outer references
static void SeparateOuterRefs(CMemoryPool *mp, CExpression *pexprScalar,
CColRefSet *outer_refs,
CExpression **ppexprLocal,
CExpression **ppexprOuterRef);
// is the condition a LIKE predicate
static BOOL FLikePredicate(IMDId *mdid);
// is the condition a LIKE predicate
static BOOL FLikePredicate(CExpression *pexprPred);
// extract the components of a LIKE predicate
static void ExtractLikePredComponents(CExpression *pexprPred,
CExpression **ppexprScIdent,
CExpression **ppexprConst);
// check if scalar expression is null-rejecting and uses columns from given column set
static BOOL FNullRejecting(CMemoryPool *mp, CExpression *pexprScalar,
CColRefSet *pcrs);
// returns true iff the given predicate pexprPred is compatible with the given index pmdindex
static BOOL FCompatibleIndexPredicate(CExpression *pexprPred,
const IMDIndex *pmdindex,
CColRefArray *pdrgpcrIndex,
CMDAccessor *md_accessor);
// returns true iff all predicates in the given array are compatible with the given index
static BOOL FCompatiblePredicates(CExpressionArray *pdrgpexprPred,
const IMDIndex *pmdindex,
CColRefArray *pdrgpcrIndex,
CMDAccessor *md_accessor);
// check if the expensive CNF conversion is beneficial in finding predicate for hash join
static BOOL FConvertToCNF(CExpression *pexpr, CExpression *pexprOuter,
CExpression *pexprInner);
// check if the predicate is a simple scalar cmp or a simple conjuct that can be used directly
// for bitmap index looup without breaking it down.
static BOOL FBitmapLookupSupportedPredicateOrConjunct(
CExpression *pexpr, CColRefSet *outer_refs);
// Check if a given comparison operator is "very strict", meaning that it is strict
// (NULL operands result in NULL result) and that it never produces a NULL result on
// non-null operands. Note that this check may return false negatives (some operators
// may have very strict behavior, yet this method returns false).
static BOOL FBuiltInComparisonIsVeryStrict(IMDId *mdid);
// Check if the given expr only contains conjuncts of strict comparison operators
// NB: This does NOT recurse into Boolean AND/OR operations
static BOOL ExprContainsOnlyStrictComparisons(CMemoryPool *mp,
CExpression *expr);
// Check if the given exprs only contains conjuncts of strict comparison operators
// NB: This does NOT recurse into Boolean AND/OR operations
static BOOL ExprsContainsOnlyStrictComparisons(CExpressionArray *conjuncts);
}; // class CPredicateUtils
} // namespace gpopt
#endif // !GPOPT_CPredicateUtils_H
// EOF
相关信息
相关文章
greenplumn CExpressionFactorizer 源码
greenplumn CExpressionHandle 源码
greenplumn CExpressionPreprocessor 源码
greenplumn CExpressionUtils 源码
0
赞
热门推荐
-
2、 - 优质文章
-
3、 gate.io
-
6、 golang
-
8、 openharmony