| /********************************************************************** |
| // @@@ START COPYRIGHT @@@ |
| // |
| // Licensed to the Apache Software Foundation (ASF) under one |
| // or more contributor license agreements. See the NOTICE file |
| // distributed with this work for additional information |
| // regarding copyright ownership. The ASF licenses this file |
| // to you under the Apache License, Version 2.0 (the |
| // "License"); you may not use this file except in compliance |
| // with the License. You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, |
| // software distributed under the License is distributed on an |
| // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| // KIND, either express or implied. See the License for the |
| // specific language governing permissions and limitations |
| // under the License. |
| // |
| // @@@ END COPYRIGHT @@@ |
| **********************************************************************/ |
| #ifndef ITEMLOG_H |
| #define ITEMLOG_H |
| /* -*-C++-*- |
| ****************************************************************************** |
| * |
| * File: ItemLog.h |
| * Description: Logical (boolean) item expressions (AND, OR, =, >, ...) |
| * |
| * |
| * Created: 11/04/94 |
| * Language: C++ |
| * |
| * |
| * |
| * |
| ****************************************************************************** |
| */ |
| |
| #include "QRExprElement.h" |
| |
| // ----------------------------------------------------------------------- |
| // contents of this file |
| // ----------------------------------------------------------------------- |
| class BiLogic; |
| class UnLogic; |
| class BiRelat; |
| |
| // Global func for Normalizer, should be an ItemExpr:: member but I'm too lazy! |
| ItemExpr * UnLogicMayBeAnEliminableTruthTest(ItemExpr *item, |
| NABoolean aggsAreEliminable=FALSE); |
| |
| // ----------------------------------------------------------------------- |
| // Forward declarations |
| // ----------------------------------------------------------------------- |
| class Generator; |
| class MdamCodeGenHelper; |
| class MdamPred; |
| class NormWA; |
| class IntegerList; |
| class CostScalar; |
| |
| class ColStatDesc; |
| template <class T> class SharedPtr; |
| typedef SharedPtr<ColStatDesc> ColStatDescSharedPtr; |
| class ColStatDescList; |
| // ----------------------------------------------------------------------- |
| // binary logic operators (ITM_AND, ITM_OR) |
| // ----------------------------------------------------------------------- |
| class BiLogic : public ItemExpr |
| { |
| // ITM_AND, ITM_OR |
| public: |
| BiLogic(OperatorTypeEnum otype, |
| ItemExpr *child0 = NULL, |
| ItemExpr *child1 = NULL) |
| : ItemExpr(otype,child0,child1) |
| , createdFromINlist_(FALSE) |
| { |
| numLeaves_ = 0; |
| } |
| |
| // virtual destructor |
| // warning elimination (removed "inline") |
| virtual ~BiLogic() {} |
| |
| // we want BiLogic to be cacheable |
| virtual NABoolean isCacheableExpr(CacheWA& cwa); |
| |
| // selectively change literals of cacheable query into constant parameters |
| virtual ItemExpr* normalizeForCache(CacheWA& cwa, BindWA& bindWA); |
| |
| // if BiLogic ever gets its own data member(s), we must make its data |
| // member(s) contribute to its cache key via our own generateCacheKey here |
| |
| // get the degree of this node (it is a binary op). |
| virtual Int32 getArity() const; |
| |
| // An indicator whether this item expression is a predicate. |
| virtual NABoolean isAPredicate() const; |
| |
| // return true iff we're an expansion of a LIKE predicate |
| virtual NABoolean isLike() const; |
| |
| // a virtual function for type propagating the node |
| virtual const NAType * synthesizeType(); |
| |
| // Each operator supports a (virtual) method for transforming its |
| // scalar expressions to a canonical form |
| virtual void transformNode(NormWA & normWARef, |
| ExprValueId & locationOfPointerToMe, |
| ExprGroupId & introduceSemiJoinHere, |
| const ValueIdSet & externalInputs); |
| |
| // A method for inverting (finding the inverse of) the operators |
| // in a subtree that is rooted in a NOT. |
| virtual ItemExpr * transformSubtreeOfNot(NormWA & normWARef, |
| OperatorTypeEnum falseOrNot); |
| |
| // A virtual method for transforming this predicate |
| // if its descendant is a multi-value predicate. |
| // Returns NULL if no transformation was necessary. |
| virtual ItemExpr * transformMultiValuePredicate( |
| NABoolean flattenSubqueries = TRUE, |
| ChildCondition condBiRelat = ANY_CHILD); |
| |
| // determines whether the predicate is capable of discarding |
| // null augmented rows produced by a left join. |
| virtual NABoolean predicateEliminatesNullAugmentedRows(NormWA &, ValueIdSet &); |
| |
| // Each operator supports a (virtual) method for transforming its |
| // query tree to a canonical form. The parameter setOfPredExpr is |
| // supplied only when predicates are normalized. |
| virtual ItemExpr * normalizeNode(NormWA & normWARef); |
| |
| // A transformation method for protecting sequence functions from not |
| // being evaluated due to short-circuit evaluation. |
| // |
| virtual void protectiveSequenceFunctionTransformation(Generator *generator); |
| |
| virtual NABoolean isCovered(const ValueIdSet& newExternalInputs, |
| const GroupAttributes& newRelExprAnchorGA, |
| ValueIdSet& referencedInputs, |
| ValueIdSet& coveredSubExpr, |
| ValueIdSet& unCoveredExpr) const; |
| |
| virtual NABoolean duplicateMatch(const ItemExpr &other) const; |
| virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL, |
| CollHeap* outHeap = 0); |
| |
| void setCreatedFromINlist(NABoolean v){createdFromINlist_ = v;} |
| NABoolean createdFromINlist() { return createdFromINlist_;} |
| ItemExpr* getINlhs(); |
| |
| // virtual method to fixup tree for code generation. |
| virtual ItemExpr * preCodeGen(Generator *); |
| |
| // method to do code generation |
| short codeGen(Generator*); |
| |
| // method to generate Mdam predicates |
| short mdamPredGen(Generator * generator, |
| MdamPred ** head, |
| MdamPred ** tail, |
| MdamCodeGenHelper & mdamHelper, |
| ItemExpr * parent); |
| |
| // method to generate MDAM_BETWEEN predicate |
| virtual void mdamPredGenSubrange(Generator* generator, |
| MdamPred** head, |
| MdamPred** tail, |
| MdamCodeGenHelper& mdamHelper); |
| |
| // get a printable string that identifies the operator |
| const NAString getText() const; |
| |
| virtual NABoolean isOrderPreserving() const; |
| |
| // This operator is supported by the synthesis functions. |
| virtual NABoolean synthSupportedOp() const; |
| |
| virtual NABoolean applyDefaultPred(ColStatDescList & histograms, |
| OperatorTypeEnum exprOpCode, |
| ValueId predValueId, |
| NABoolean & globalPredicate, |
| CostScalar *maxSelectivity=NULL); |
| |
| // MDAM related methods |
| // Performs the MDAM tree walk. See ItemExpr.h for a detailed description. |
| DisjunctArray * mdamTreeWalk(); |
| |
| inline Int32 getNumLeaves () const { return numLeaves_; } |
| void setNumLeaves(Int32 num) {numLeaves_ = num; } |
| |
| virtual QR::ExprElement getQRExprElem() const; |
| virtual NABoolean hasEquivalentProperties(ItemExpr * other) { return TRUE;} |
| |
| private: |
| Int32 numLeaves_; |
| |
| NABoolean createdFromINlist_; |
| }; // class BiLogic |
| |
| // ----------------------------------------------------------------------- |
| // unary logic operators (NOT, IS_TRUE, ...) |
| // ----------------------------------------------------------------------- |
| class UnLogic : public ItemExpr |
| { |
| // ITM_NOT, ITM_IS_TRUE, ITM_IS_FALSE, ITM_IS_NULL, ITM_IS_NOT_NULL, |
| // ITM_IS_UNKNOWN, ITM_IS_NOT_UNKNOWN |
| public: |
| UnLogic(OperatorTypeEnum otype, ItemExpr *child0 = NULL) |
| : ItemExpr(otype,child0) |
| {} |
| |
| // virtual destructor |
| // warning elimination (removed "inline") |
| virtual ~UnLogic() {} |
| |
| // get the degree of this node (it is a unary op). |
| virtual Int32 getArity() const; |
| |
| // a virtual function for performing name binding within the query tree |
| virtual ItemExpr *bindNode(BindWA *bindWA); |
| |
| // we want UnLogic to be cacheable. we do this by inheriting and |
| // not overriding ItemExpr::isCacheableExpr. |
| |
| // do NOT parameterize literals of UnLogic ItemExpr if we |
| // can NOT guarantee the correctness of such parameterization |
| virtual ItemExpr* normalizeForCache(CacheWA& cwa, BindWA& bindWA) |
| { return this; } |
| |
| // if UnLogic ever gets its own data member(s), we must make its data |
| // member(s) contribute to its cache key via our own generateCacheKey here |
| |
| // An indicator whether this item expression is a predicate. |
| virtual NABoolean isAPredicate() const; |
| |
| // Each operator supports a (virtual) method for transforming its |
| // scalar expressions to a canonical form |
| virtual void transformNode(NormWA & normWARef, |
| ExprValueId & locationOfPointerToMe, |
| ExprGroupId & introduceSemiJoinHere, |
| const ValueIdSet & externalInputs); |
| |
| // Note: Only the UnLogic operator needs transformNode2 so not made virtual. |
| void transformNode2(NormWA & normWARef, |
| ExprValueId & locationOfPointerToMe, |
| ExprGroupId & introduceSemiJoinHere, |
| const ValueIdSet & externalInputs); |
| |
| // Each operator supports a (virtual) method for transforming its |
| // query tree to a canonical form. |
| virtual ItemExpr * normalizeNode(NormWA & normWARef); |
| |
| // A method for inverting (finding the inverse of) the operators |
| // in a subtree that is rooted in a NOT. |
| virtual ItemExpr * transformSubtreeOfNot(NormWA & normWARef, |
| OperatorTypeEnum falseOrNot); |
| |
| // A virtual method for transforming this predicate |
| // if its descendant is a multi-value predicate. |
| // Returns NULL if no transformation was necessary. |
| virtual ItemExpr * transformMultiValuePredicate( |
| NABoolean flattenSubqueries = TRUE, |
| ChildCondition condBiRelat = ANY_CHILD); |
| |
| // determines whether the predicate is capable of discarding |
| // null augmented rows produced by a left join. |
| virtual NABoolean predicateEliminatesNullAugmentedRows(NormWA &, ValueIdSet &); |
| |
| // scalar expressions to a canonical form |
| void transformIsNull(NormWA & normWARef, |
| ExprValueId & locationOfPointerToMe, |
| ExprGroupId & introduceSemiJoinHere, |
| const ValueIdSet & externalInputs); |
| |
| // method to do code generation |
| short codeGen(Generator*); |
| |
| // method to generate Mdam predicates |
| short mdamPredGen(Generator * generator, |
| MdamPred ** head, |
| MdamPred ** tail, |
| MdamCodeGenHelper & mdamHelper, |
| ItemExpr * parent); |
| |
| virtual NABoolean duplicateMatch(const ItemExpr &other) const; |
| virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL, |
| CollHeap* outHeap = 0); |
| |
| // a virtual function for type propagating the node |
| virtual const NAType * synthesizeType(); |
| |
| // get a printable string that identifies the operator |
| const NAString getText() const; |
| |
| // Performs the MDAM tree walk. See ItemExpr.h for a detailed description. |
| DisjunctArray * mdamTreeWalk(); |
| |
| // default selectivity for unary relational predicates |
| virtual double defaultSel(); |
| |
| virtual NABoolean applyDefaultPred(ColStatDescList & histograms, |
| OperatorTypeEnum exprOpCode, |
| ValueId predValueId, |
| NABoolean & globalPredicate, |
| CostScalar *maxSelectivity=NULL); |
| |
| // Is this operator supported by the synthesis functions? |
| virtual NABoolean synthSupportedOp() const; |
| |
| virtual QR::ExprElement getQRExprElem() const; |
| virtual NABoolean hasEquivalentProperties(ItemExpr * other) { return TRUE;} |
| |
| }; // class UnLogic |
| |
| |
| // ----------------------------------------------------------------------- |
| // binary "relational" operators (=, <, >=, ...) |
| // ----------------------------------------------------------------------- |
| class BiRelat : public ItemExpr |
| { |
| // ITM_EQUAL, ITM_NOT_EQUAL, ITM_LESS, ITM_LESS_EQ, ITM_GREATER, ITM_GREATER_EQ |
| |
| public: |
| BiRelat(OperatorTypeEnum otype, |
| ItemExpr *child0 = NULL, |
| ItemExpr *child1 = NULL, |
| NABoolean specialNulls = FALSE, |
| NABoolean isaPartKeyPred = FALSE) |
| : ItemExpr(otype,child0,child1), |
| specialNulls_(specialNulls), |
| specialMultiValuePredicateTransformation_(FALSE), |
| directionVector_(NULL), |
| isaPartKeyPred_(isaPartKeyPred), |
| originalLikeExprId_(NULL_VALUE_ID), |
| likeSelectivity_(-1.0), |
| derivedFromMCRP_(FALSE), |
| listOfComparisonExprs_(NULL), |
| preferForSubsetScanKey_(FALSE), |
| createdFromINlist_(FALSE), |
| collationEncodeComp_(FALSE), |
| isNotInPredTransform_(FALSE), |
| outerNullFilteringDetected_ (FALSE), |
| innerNullFilteringDetected_ (FALSE), |
| rollupColumnNum_(-1), |
| flags_(0) |
| { |
| #ifndef NDEBUG |
| if (NULL != getenv("FORCE_SPECIAL_NULLS")) { |
| specialNulls_ = TRUE; |
| } |
| #endif |
| } |
| |
| // virtual destructor |
| // warning elimination (removed "inline") |
| virtual ~BiRelat() {} |
| |
| // we want BiRelat to be cacheable |
| virtual NABoolean isCacheableExpr(CacheWA& cwa); |
| |
| // selectively change literals of a cacheable query into input parameters |
| virtual ItemExpr* normalizeForCache(CacheWA& cachewa, BindWA& bindWA); |
| |
| // append an ascii-version of ItemExpr into cachewa.qryText_ |
| virtual void generateCacheKey(CacheWA& cachewa) const; |
| |
| // get the degree of this node (it is a binary op). |
| virtual Int32 getArity() const; |
| |
| // a virtual function for performing name binding within the query tree |
| virtual ItemExpr *bindNode(BindWA *bindWA); |
| |
| virtual void synthTypeAndValueId(NABoolean redriveTypeSynthesisFlag = FALSE, NABoolean redriveChildTypeSynthesis = FALSE); |
| |
| // a virtual function for relaxing char type match rules |
| ItemExpr* tryToRelaxCharTypeMatchRules(BindWA *bindWA); |
| |
| virtual NABoolean isRelaxCharTypeMatchRulesPossible() {return TRUE;}; |
| |
| // An indicator whether this item expression is a predicate. |
| virtual NABoolean isAPredicate() const; |
| |
| // Each operator supports a (virtual) method for transforming its |
| // scalar expressions to a canonical form |
| virtual void transformNode(NormWA & normWARef, |
| ExprValueId & locationOfPointerToMe, |
| ExprGroupId & introduceSemiJoinHere, |
| const ValueIdSet & externalInputs); |
| |
| // A method for inverting (finding the inverse of) the operators |
| // in a subtree that is rooted in a NOT. |
| virtual ItemExpr * transformSubtreeOfNot(NormWA & normWARef, |
| OperatorTypeEnum falseOrNot); |
| |
| // Get the comparison operator for performing the comparison in reverse |
| OperatorTypeEnum getReverseOperatorType() const; |
| |
| void *unused_NONvirtual_method_1(); //## placeholder: reuse w/ any signature |
| |
| void *unused_NONvirtual_method_2(); //## placeholder: reuse w/ any signature |
| |
| // A virtual method for transforming (a,b) <op> (c,d) for any <op>, |
| // but only if both (or just one of) children are ItemList. |
| // Returns NULL if no transformation was necessary. |
| virtual ItemExpr * transformMultiValuePredicate( |
| NABoolean flattenSubqueries = TRUE, |
| ChildCondition tfmIf = ANY_CHILD); |
| |
| // determines whether the predicate is capable of discarding |
| // null augmented rows produced by a left join. |
| virtual NABoolean predicateEliminatesNullAugmentedRows(NormWA &, ValueIdSet &); |
| |
| // Each operator supports a (virtual) method for transforming its |
| // query tree to a canonical form. The parameter setOfPredExpr is |
| // supplied only when predicates are normalized. |
| virtual ItemExpr * normalizeNode(NormWA & normWARef); |
| |
| // a virtual function for type propagating the node |
| virtual const NAType * synthesizeType(); |
| |
| // method to do code generation |
| ItemExpr * preCodeGen(Generator*); |
| short codeGen(Generator*); |
| |
| // method to generate Mdam predicates |
| short mdamPredGen(Generator * generator, |
| MdamPred ** head, |
| MdamPred ** tail, |
| MdamCodeGenHelper & mdamHelper, |
| ItemExpr * parent); |
| |
| // method to get information on a BiRelat that is one of the operands of an |
| // AND that represents an interval (MDAM_BETWEEN). |
| void getMdamPredDetails(Generator* generator, |
| MdamCodeGenHelper& mdamHelper, |
| enum MdamPred::MdamPredType& predType, |
| ex_expr** vexpr); |
| |
| virtual NABoolean duplicateMatch(const ItemExpr &other) const; |
| virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL, |
| CollHeap* outHeap = 0); |
| |
| // get a printable string that identifies the operator |
| const NAString getText() const; |
| |
| NABoolean getSpecialNulls() const |
| { |
| return specialNulls_; |
| } |
| |
| void setSpecialNulls(NABoolean flag) |
| { |
| specialNulls_ = flag; |
| } |
| |
| NABoolean & specialMultiValuePredicateTransformation() |
| { return specialMultiValuePredicateTransformation_; } |
| |
| void setSpecialMultiValuePredicateTransformation(NABoolean flag) |
| {specialMultiValuePredicateTransformation_ = flag;} |
| |
| NABoolean isaPartKeyPred() const { return isaPartKeyPred_; } |
| void setIsaPartKeyPred(NABoolean flag) {isaPartKeyPred_ = flag; } |
| |
| ValueId originalLikeExprId() const { return originalLikeExprId_; } |
| void setOriginalLikeExprId(ValueId originalLikeExprId) |
| {originalLikeExprId_ = originalLikeExprId; } |
| |
| NABoolean derivativeOfLike(); |
| |
| void adjustRowcountAndUecForLike(const ColStatDescSharedPtr &colStats, |
| CostScalar rowcountBeforePreds, |
| CostScalar totalUecBeforePreds, |
| CostScalar baseUecBeforePreds); |
| |
| virtual NABoolean applyDefaultPred(ColStatDescList & histograms, |
| OperatorTypeEnum exprOpCode, |
| ValueId predValueId, |
| NABoolean & globalPredicate, |
| CostScalar *maxSelectivity=NULL); |
| |
| private: |
| enum { |
| FOR_LIKE = 0x0001 |
| }; |
| |
| // Helper methods for applyDefaultPred() method |
| NABoolean isSimpleComplexPredInvolved(); |
| |
| void applyEquiJoinExpr(ColStatDescSharedPtr & leftStatDesc, |
| ColStatDescSharedPtr & rightStatDesc, |
| ColStatDescList & histograms); |
| |
| void applyLocalPredExpr(ColStatDescSharedPtr & leftStatDesc, |
| ColStatDescSharedPtr & rightStatDesc, |
| OperatorTypeEnum exprOpCode, |
| ValueIdSet leftLeafValues, |
| ValueIdSet rightLeafValues, |
| CostScalar *maxSelectivity=NULL); |
| |
| void applyRangePredExpr(ColStatDescSharedPtr & leftStatDesc, |
| ValueIdSet leftLeafValues, |
| ValueIdSet rightLeafValues); |
| |
| public: |
| |
| // default selectivity for birelational predicates |
| virtual double defaultSel(); |
| |
| // Is this operator supported by the synthesis functions? |
| virtual NABoolean synthSupportedOp() const; |
| |
| const IntegerList *getDirectionVector() const { return directionVector_;} |
| void setDirectionVector(IntegerList *v) { directionVector_ = v; } |
| |
| void setLikeSelectivity (double sel) { likeSelectivity_ = sel; } |
| double getLikeSelectivity() const { return likeSelectivity_ ; } |
| |
| // MCRP Code - Begin |
| |
| // Is this range predicate derived from a MCRP, |
| // i.e. MultiColumn Range Predicate. A MCRP e.g. (a,b) > (1,2) |
| // is transformed into (a >= 1) and (a, b) > (1,2). The transformation is |
| // performed because the single subset scan optimizer does recognize MCRPs. |
| // Therefore a single column range predicate is add (in this case a >= 1 |
| // was added) to help specify a single subset scan begin key. |
| // This will return TRUE for the added predicate i.e. a >= 1. |
| NABoolean isDerivedFromMCRP() { return derivedFromMCRP_;} |
| |
| // Mark this predicate as derived from a MCRP, this is set in method |
| // static ItemExpr * transformMultiValueComparison(). |
| // transfromMultiValueComparison, transforms an MCRP and adds the extra |
| // predicate mentioned above. |
| void setDerivedFromMCRP() { derivedFromMCRP_ = TRUE; } |
| |
| void setListOfComparisons(ItemExprList * comparisonList) |
| { listOfComparisonExprs_ = comparisonList;} |
| |
| ItemExprList * getListOfComparisons() { return listOfComparisonExprs_;} |
| |
| void getListOfComparisonIds(ValueIdList & listOfComparisonIds) |
| { listOfComparisonIds = listOfComparisonExprIds_; } |
| |
| void getLeftMCRPChildList(ValueIdList & leftMCRPChildList); |
| void getRightMCRPChildList(ValueIdList & rightMCRPChildList); |
| |
| void setPreferForSubsetScanKey(NABoolean preference = TRUE) |
| { preferForSubsetScanKey_ = preference; } |
| |
| NABoolean isPreferredForSubsetScanKey() |
| { return preferForSubsetScanKey_;} |
| |
| // converts listOfComparisonExprs_ to listOfComparisonExprIds_ |
| // this is called after the comparisons have be bound, therefore |
| // each comparison should have a ValueId |
| void translateListOfComparisonsIntoValueIds(); |
| |
| //MCRP Code - End |
| |
| void setCreatedFromINlist(NABoolean v){createdFromINlist_ = v;} |
| NABoolean createdFromINlist() { return createdFromINlist_;} |
| |
| void setCollationEncodeComp(NABoolean v) {collationEncodeComp_= v;} |
| NABoolean getCollationEncodeComp() { return collationEncodeComp_;} |
| virtual NABoolean hasEquivalentProperties(ItemExpr * other) { return TRUE;} |
| |
| Int16 &rollupColumnNum() { return rollupColumnNum_; } |
| |
| //Not In optimization methods |
| // indicate that this birelat is a transformation of a NotIn. |
| NABoolean getIsNotInPredTransform() const |
| { |
| return isNotInPredTransform_; |
| } |
| |
| void setIsNotInPredTransform(NABoolean v) |
| { |
| isNotInPredTransform_=v; |
| } |
| |
| // indicate whether Null filtering was detected when the predicates |
| // were pulled up. |
| NABoolean getOuterNullFilteringDetected() const |
| { |
| return outerNullFilteringDetected_; |
| } |
| |
| void setOuterNullFilteringDetected(NABoolean v) |
| { |
| outerNullFilteringDetected_ = v; |
| } |
| |
| NABoolean getInnerNullFilteringDetected() const |
| { |
| return innerNullFilteringDetected_; |
| } |
| |
| void setInnerNullFilteringDetected(NABoolean v) |
| { |
| innerNullFilteringDetected_ = v; |
| } |
| // Not in optimization --end |
| |
| // relax < to <=, > to >=, or return ori |
| OperatorTypeEnum getRelaxedComparisonOpType() const; |
| |
| // get and set for flags_. See enum Flags. |
| NABoolean addedForLikePred() { return (flags_ & FOR_LIKE) != 0; } |
| void setAddedForLikePred(NABoolean v) |
| { (v ? flags_ |= FOR_LIKE : flags_ &= ~FOR_LIKE); } |
| |
| private: |
| |
| // helper to change literals of a cacheable query into input parameters |
| void parameterizeMe(CacheWA& cachewa, BindWA& bindWA, ExprValueId& child, |
| BaseColumn *base, ConstValue *val); |
| |
| // MDAM related methods: |
| |
| // Performs the MDAM tree walk. See ItemExpr.h for a detailed description. |
| DisjunctArray * mdamTreeWalk(); |
| |
| // if we are allowing certain incompatible comparisons handle them. |
| // currently the following incompatible comparisons are supported: |
| // 1. Numeric and Character |
| // 2. Date and Character literal |
| // This returns a pointer to itself if everything goes fine |
| // otherwise it returns NULL |
| BiRelat * handleIncompatibleComparison(BindWA *bindWA); |
| |
| // The flag, if set, indicates that 'nulls are values'. |
| // That means that nulls are equal to other nulls, and they |
| // sort higher than other values. Used for groupby, order |
| // by, hashing, or any other operation where nulls are NOT |
| // to be ignored. |
| // |
| // MVs: |
| // The flag is used in specific equi-join predicates |
| // Irena |
| NABoolean specialNulls_; |
| |
| // See QuantifiedComp::getBlackBoxExpr |
| NABoolean specialMultiValuePredicateTransformation_; |
| |
| // -- MVs |
| // The direction vector is used for comparing lists of index columns |
| // that were created with different orders, for example (A ASC, B DESC). |
| IntegerList *directionVector_; |
| |
| // Predicate is a partitioning key predicate |
| NABoolean isaPartKeyPred_; |
| |
| // If this Range expression is derived from 'Like' expression, then |
| // the following attribute contains the ValueId of the parent Like |
| // expression. If it is a regular logical expression, then it contains |
| // NULL_VALUE_ID. It will be set with the ValueId when the BiRelat |
| // constructor is called from Like::applyBeginEndKeys |
| ValueId originalLikeExprId_; |
| |
| // This contains the portion of the default selectivity for the like |
| // predicate, that should be applied to this predicate. In the |
| // constructor for this expression, we would set it to -1. It would be |
| // set by the computed value in the Like::applyBeginEndKeys method |
| // where we set the originalLikeExprId_ with the ValueId of the original |
| // expression, in case the original expression is a Like predicate. |
| |
| double likeSelectivity_; |
| |
| // MCRP Code - Begin |
| |
| // Flag indicating that this comparison is derived from a MCRP |
| // For MCRPs (MultiColumnRangePredicates), i.e predicates of the form |
| // (a, b, c) > (1, 2, 3), we add a predicate and transform the predicate |
| // to (a >= 1) and ((a, b, c) > (1, 2, 3)). This flag will be set for the |
| // added comparison predicate '>=' i.e. (a >= 1). |
| // If this flag is set then the datamembers below should also be set. |
| // If this flag is not set then the datamembers below should not be set |
| NABoolean derivedFromMCRP_; |
| |
| // list of item expressions representing comparisons on each item of a MCRP |
| ItemExprList * listOfComparisonExprs_; |
| |
| // This is derived from listOfComparisonExprs_ |
| // This is the list of ValueIds corresponding to each comparison |
| // in the listOfComparisonExprs_ |
| ValueIdList listOfComparisonExprIds_; |
| |
| // This is the list of ValueIds for the left Children of the MCRP |
| // Given MCRP (a, b, c) > (1, 2, 3), this list will contain ValueIds |
| // of (a, b, c). The list will likely contain the ValueId for the VEG |
| // representing each of a, b, c. Since this is populated on demand, |
| // therefore whenever the leftMCRPChildList_ is request for the first time |
| // if the VEGs have formed, then the ValueIds will represent VEGs |
| ValueIdList leftMCRPChildList_; |
| |
| // Similar to the list above, except for the right children of the |
| // MCRP. Therefore for MCRP (a, b, c) > (1, 2, 3) this will be |
| // list of ValueIds representing (1, 2, 3). |
| ValueIdList rightMCRPChildList_; |
| |
| // flag to indicate if this predicate should be preferred for defining |
| // subset scan begin/end keys |
| NABoolean preferForSubsetScanKey_; |
| |
| // MCRP Code - End |
| |
| NABoolean createdFromINlist_; |
| |
| virtual QR::ExprElement getQRExprElem() const; |
| |
| NABoolean collationEncodeComp_; |
| |
| // flag to indicate that this birelat is a transformation of a NotIn. |
| NABoolean isNotInPredTransform_; |
| |
| // flags to indicate whether Null filtering was detected when the predicates |
| // were pulled up. |
| NABoolean outerNullFilteringDetected_; |
| |
| NABoolean innerNullFilteringDetected_; |
| |
| // Used for groupby rollup. |
| // Set in generator during groupby comparison expression generation. |
| // It indicates the position of grouping column that caused the group |
| // change during groupby computation. |
| // Used to return the rollup groups. |
| Int16 rollupColumnNum_; |
| |
| UInt32 flags_; |
| |
| }; // class BiRelat |
| |
| class KeyRangeCompare : public BiRelat |
| { |
| |
| public: |
| KeyRangeCompare(const CorrName &objectName, |
| OperatorTypeEnum otype, |
| ItemExpr *child0, |
| ItemExpr *child1) |
| : BiRelat(otype, |
| child0, |
| child1, |
| TRUE /* specialNulls */, |
| FALSE /* isaPartKeyPred */ |
| ), |
| objectName_(objectName) |
| { |
| setSpecialMultiValuePredicateTransformation |
| (FALSE); |
| } |
| |
| // virtual destructor |
| virtual ~KeyRangeCompare() {} |
| |
| // Does semantic checks and binds the function. |
| virtual ItemExpr * bindNode(BindWA * bindWA); |
| |
| // get a printable string that identifies the operator |
| // |
| virtual const NAString getText() const; |
| |
| const CorrName & getObjectName() const { return objectName_; } |
| CorrName & getObjectName() { return objectName_; } |
| |
| void setObjectName(const CorrName& corrName) {objectName_ = corrName;} |
| |
| NABoolean verifyPartitioningKeys(BindWA *bindWA, |
| ItemExpr *tree, |
| const NAColumnArray &partKeyCols, |
| CollHeap* heap); |
| |
| private: |
| |
| // ---------------------------------------------------------------// |
| // the user-specified name of the table or an index or any other |
| // SQL/MX object. |
| // -------------------------------------------------------------- // |
| CorrName objectName_; |
| }; |
| |
| // ----------------------------------------------------------------------- |
| // NOT IN |
| // a query like "select * from T1 where a NOT IN (select b from T2);" |
| // is transformed into an Anti semi join with a join predicate of |
| // NotIn(a,b) |
| // |
| // NotIn (a,b) -- a and b can be either item expressions in the case |
| // of single column NOT IN or itemlists in the case on multi-column |
| // NOT IN |
| // ----------------------------------------------------------------------- |
| class NotIn : public BiRelat |
| { |
| |
| public: |
| NotIn( ItemExpr *child0 = NULL, |
| ItemExpr *child1 = NULL) |
| : BiRelat(ITM_NOT_IN, |
| child0, |
| child1), |
| equivEquiPredicate_(NULL_VALUE_ID), |
| equivNonEquiPredicate_(NULL_VALUE_ID), |
| isOneInnerBroadcastRequired_(NotIn::NOT_SET) |
| {} |
| |
| // virtual destructor |
| virtual ~NotIn() {} |
| |
| virtual void transformNode(NormWA & normWARef, |
| ExprValueId & locationOfPointerToMe, |
| ExprGroupId & introduceSemiJoinHere, |
| const ValueIdSet & externalInputs); |
| |
| static ValueIdSet rewriteMultiColNotInPredicate( ValueId ninValId, |
| ValueIdSet joinPred, |
| ValueIdSet selPred); |
| |
| virtual const NAString getText() const |
| { |
| return "NotIn"; |
| } |
| |
| virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL, |
| CollHeap* outHeap = 0); |
| |
| ItemExpr * preCodeGen(Generator*); |
| |
| ValueId createEquivEquiPredicate() const; |
| ValueId createEquivNonEquiPredicate() const; |
| |
| void cacheEquivEquiPredicate(); |
| void cacheEquivNonEquiPredicate(); |
| |
| ValueId getEquivEquiPredicate() const |
| { |
| return equivEquiPredicate_; |
| } |
| |
| void setEquivEquiPredicate(ValueId v) |
| { |
| DCMPASSERT ( child(0)->getOperatorType() != ITM_ITEM_LIST && |
| child(1)->getOperatorType() != ITM_ITEM_LIST ); |
| |
| equivEquiPredicate_ = v; |
| } |
| |
| ValueId getEquivNonEquiPredicate() const |
| { |
| return equivNonEquiPredicate_; |
| } |
| |
| void setEquivNonEquiPredicate(ValueId v) |
| { |
| DCMPASSERT ( child(0)->getOperatorType() != ITM_ITEM_LIST); |
| equivNonEquiPredicate_ = v; |
| } |
| |
| |
| void cacheIsOneInnerBroadcastRequired(); |
| |
| NABoolean getIsOneInnerBroadcastRequired() |
| { |
| if (isOneInnerBroadcastRequired_ == NotIn::NOT_SET) |
| { |
| cacheIsOneInnerBroadcastRequired(); |
| } |
| if (isOneInnerBroadcastRequired_ == NotIn::REQUIRED) |
| { |
| return TRUE; |
| } |
| else |
| { |
| return FALSE; |
| } |
| } |
| |
| private: |
| enum enumRequireOneBroadcast |
| { |
| NOT_SET = 0, |
| REQUIRED=1, |
| NOT_REQUIRED=2 |
| }; |
| |
| // cache for the equi and non equi-predicate for single col NOT IN |
| // used during optimization phase |
| ValueId equivEquiPredicate_; |
| ValueId equivNonEquiPredicate_; |
| |
| // this field serves as a cache to store a value indicating whether |
| // broadcast of one row is required and reuse it instead of computing |
| // it multiple times |
| enumRequireOneBroadcast isOneInnerBroadcastRequired_; |
| |
| };//class NotIn |
| |
| |
| #endif /* ITEMLOG_H */ |