blob: e24a1fc54caf4833129fcab2b5d035b2dce7d06d [file] [log] [blame]
/**********************************************************************
// @@@ 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 ITEMEXPR_H
#define ITEMEXPR_H
/* -*-C++-*-
******************************************************************************
*
* File: ItemExpr.h
* Description: Item expression base class ItemExpr
* Created: 5/11/94
* Language: C++
*
*
*
*
******************************************************************************
*/
#include "charinfo.h" // for CollationAndCoercibility
#include "ComASSERT.h"
#include "ExprNode.h"
#include "ItemExprList.h"
#include "ObjectNames.h"
#include "ValueDesc.h"
#include "QRExprElement.h"
#include "IndexDesc.h"
#include "ComKeyMDAM.h"
// -----------------------------------------------------------------------
// contents of this file
// -----------------------------------------------------------------------
class ExprValueId;
class ItemExpr;
// -----------------------------------------------------------------------
// forward references
// -----------------------------------------------------------------------
class Attributes;
class BindWA;
class CacheWA;
class ConstValue;
class ConstantParameter;
class RandomNum;
class SelParameter;
class Generator;
class DisjunctArray;
class ex_clause;
class MdamCodeGenHelper;
class MdamPred;
class VEGReference;
class VEGRewritePairs;
class ColStatDescList;
#define CONST_32K 32768
// -----------------------------------------------------------------------
// An ExprValueId object is a pointer to an ItemExpr object. The pointer
// may be expressed through a true pointer (ItemExpr *) or through a
// ValueId object. This class hides the actual implementation and also
// allows its users to prevent updates to the object. See also class
// ExprGroupId in file RelExpr.h.
// -----------------------------------------------------------------------
class ExprValueId : public NABasicObject
{
public:
// state of the object
enum ItemExprMode
{
STANDALONE,
MEMOIZED
};
// constructors
ExprValueId();
ExprValueId(const ExprValueId &other);
ExprValueId(ItemExpr * exprPtr);
ExprValueId(const ValueId & exprId);
// assignment operators
ExprValueId & operator = (const ExprValueId & other);
ExprValueId & operator = (ItemExpr * other);
ExprValueId & operator = (const ValueId & other);
// compare an ExprValueId with another ExprValueId or ItemExpr * or ValueId
NABoolean operator == (const ExprValueId &other) const;
inline NABoolean operator != (const ExprValueId &other) const
{ return NOT operator == (other); }
NABoolean operator == (const ItemExpr *other) const;
inline NABoolean operator != (const ItemExpr *other) const
{ return NOT operator == (other); }
NABoolean operator == (const ValueId &other) const;
inline NABoolean operator != (const ValueId &other) const
{ return NOT operator == (other); }
// dereferencing operator, this class works like a pointer
inline ItemExpr * operator ->() const; // defined below class ItemExpr
// same as a "normal" method
ItemExpr * getPtr() const; // defined below class ItemExpr
// cast into an ItemExpr *
inline operator ItemExpr *() const; // defined below class ItemExpr
// cast into a ValueId
inline operator ValueId() const { return getValueId(); }
NAColumn *getNAColumn(NABoolean okIfNotColumn = FALSE) const
{ return getValueId().getNAColumn(okIfNotColumn); }
// return the ValueId
ValueId getValueId() const;
// return the mode of the pointer
inline ItemExprMode getMode() const { return exprMode_; }
// change modes
void convertToMemoized();
void convertToStandalone();
private:
enum ItemExprMode exprMode_;
ItemExpr * exprPtr_; // used for the STANDALONE and MEMOIZED mode
ValueId exprId_; // used for the MEMOIZED mode
}; // class ExprValueId
// declarations for ItemExpr::treeWalk below
typedef ItemExpr * (*ItemTreeWalkFunc)(ItemExpr *,
CollHeap *outHeap,
void *context);
enum ItemTreeWalkSeq { ITM_PREFIX_WALK, ITM_POSTFIX_WALK };
// -----------------------------------------------------------------------
// A generic item expression node.
// -----------------------------------------------------------------------
class ItemExpr : public ExprNode
{
public:
// default constructor
ItemExpr(OperatorTypeEnum otype,
ItemExpr *child0 = NULL,
ItemExpr *child1 = NULL);
// copy constructor
ItemExpr(const ItemExpr& s);
// virtual destructor
virtual ~ItemExpr();
// Delete this node without deleting its subtree.
void deleteInstance();
// operator [] is used to access the children of a tree
virtual ExprValueId & operator[] (Lng32 index);
virtual const ExprValueId & operator[] (Lng32 index) const;
// flip tree without extra resources.
ItemExpr * reverseTree();
// for cases where a named method is more convenient than operator []
ExprValueId & child(Lng32 index) { return operator[](index); }
const ExprValueId & child(Lng32 index) const { return operator[](index); }
// return a reference (can be used as an lvalue)
Lng32 &currChildNo() { return currChildNo_; }
virtual NABoolean operator == (const ItemExpr& other) const;
virtual NABoolean isEquivalentForCodeGeneration(const ItemExpr * other);
NABoolean hasBaseEquivalenceForCodeGeneration(const ItemExpr * other);
virtual ConstValue *castToConstValue(NABoolean & negate);
// a method for initializing the ValueId in the item expression.
void setValueId(ValueId valId) { valId_ = valId; }
ValueId getValueId() const { return valId_; }
// a method for allocating the ValueId for an ItemExpr
void allocValueId();
// perform a safe type cast (return NULL ptr for illegal casts)
virtual ItemExpr *castToItemExpr();
const ItemExpr *castToItemExpr() const;
// Ways of determining if *this represents any "IS NOT NULL" predicate
// or in particular, a "col IS NOT NULL" pred.
//
ItemExpr *getChildIfThisIsISNOTNULL() const
{
if (getOperatorType() == ITM_IS_NOT_NULL)
return child(0);
else if (getOperatorType() == ITM_NOT &&
child(0)->getOperatorType() == ITM_IS_NULL)
return child(0)->child(0);
else
return NULL;
}
NABoolean isISNOTNULL() const
{
ItemExpr *ie = getChildIfThisIsISNOTNULL();
if (ie) return TRUE;
if (getOperatorType() == ITM_AND)
return child(0)->isISNOTNULL() && child(1)->isISNOTNULL();
return FALSE;
}
void getColumnsIfThisIsISNOTNULL(ItemExprList &il, NABoolean) const
{
ItemExpr *ie = getChildIfThisIsISNOTNULL();
if (ie)
{
if (ie->getOperatorType() == ITM_REFERENCE ||
ie->getOperatorType() == ITM_BASECOLUMN ||
ie->getOperatorType() == ITM_INDEXCOLUMN)
il.insert(ie);
}
else
{
child(0)->getColumnsIfThisIsISNOTNULL(il, TRUE);
child(1)->getColumnsIfThisIsISNOTNULL(il, TRUE);
}
}
NABoolean getColumnsIfThisIsISNOTNULL(ItemExprList &il) const
{
il.clear();
if (!isISNOTNULL()) return FALSE;
getColumnsIfThisIsISNOTNULL(il, TRUE);
return il.entries() > 0;
}
// methods required for traversing an ExprNode tree:
// non-const & const access a child of an ExprNode, replace a particular child
virtual ExprNode *getChild(Lng32 index) { return child(index); }
virtual const ExprNode *getConstChild(Lng32 index) const {return child(index);}
virtual void setChild(Lng32 index, ExprNode *);
ItemExpr *containsRightmost(const ItemExpr *ie);
// The recognition for common subexpressions or a transformation
// can cause this scalar expression to be replaced with another one.
// The original expression remembers its replacement expression.
//
void setReplacementExpr(ItemExpr * replacementExpr)
{ replacementExpr_ = replacementExpr; };
virtual ItemExpr * getReplacementExpr() const { return replacementExpr_; };
// Take an item expression and remove all nodes from its top that form
// a "backbone". Then add the value ids of all the remaining nodes to
// a ValueIdSet.
Int32 convertToValueIdSet(ValueIdSet &vs,
BindWA *bindWA = NULL,
OperatorTypeEnum backboneType = ITM_AND,
NABoolean transformSubqueries = TRUE,
NABoolean flattenLists = FALSE);
// Take an item expression and remove all nodes from its top that form
// a "backbone". Then add the value ids of all the remaining nodes to
// a ValueIdList.
Int32 convertToValueIdList(ValueIdList &vl,
BindWA *bindWA = NULL,
OperatorTypeEnum backboneType = ITM_ITEM_LIST,
RelExpr *parent = NULL);
// rewrite this expression by replacing all value ids in it with
// the equivalent mapped value ids; return a new value id for the result
// Also add to the map the mapping form the old to the new expression
virtual ValueId mapAndRewrite(ValueIdMap &map,
NABoolean mapDownwards = FALSE);
// The method is similar to the mapAndRewrite method. Except it looks
// for the bottom value from the given index of the list.
// This is to take care of duplicates appearing in the
// bottomValue list. Sol: 10-040416-5166
virtual ValueId mapAndRewriteWithIndx(ValueIdMap &map,
CollIndex i);
virtual NABoolean hasEquivalentProperties(ItemExpr * other);
NABoolean hasBaseEquivalence(ItemExpr * other);
ItemExpr * changeDefaultOrderToDesc();
ValueId removeInverseFromExprTree( NABoolean & invExists );
ItemExpr* removeInverseFromExprTree( NABoolean & invExists,
const NABoolean onlyDouble );
static void removeNotCoveredFromExprTree( ItemExpr* &ie,
const ValueIdSet &seqColumns,
NABoolean rootNode = TRUE);
NABoolean containsSequenceFunctions();
// This method encapsulates the decision about which scalar expression
// operators can belong to a VEG.
virtual NABoolean isAColumnReference( );
// return true iff maxSelectivity(this) == selectivity(this)
NABoolean maxSelectivitySameAsSelectivity() const;
// starts the ItemExpr tree anchored by the this pointer and
// checks if childNum[0] th child is of type opType[0] and if so
// gets that child and proceeds to the same check with childNum[1]
// and opType[1], and so on. The objective is to walk down a specific
// tree looking for a certain node. The specific tree is given by the
// two input arguments. If the required node is not found, NULL is returned.
// Used currently by LPAD and RPAD.
ItemExpr* getParticularItemExprFromTree(NAList<Lng32>& childNum,
NAList<OperatorTypeEnum>& opType) const;
// This method checks if the ItemExpr represents a OR reprdicate that can be
// transformed into an IN subquery (i.e. implemented using a semijoin)
// only logical conditions are checked by this method and a TRUE/FALSE
// reply is provided. If the return value is TRUE valuesListIE will contain
// all the constants in the IN List. This datamember is cleared upon entry
// into the method. numParams is the number of params/hostvars in the INList,
// it is guaranteed to be less than equal to number of entries in the first
// argument.
NABoolean canTransformToSemiJoin(ItemExprList& valuesListIE, TableDesc* tdesc,
Lng32& numParams, ValueId& colVid, CollHeap* h) const;
void transformOlapFunctions(CollHeap *wHeap);
private:
// This method has the code that is common to
// mapAndRewrite() and mapAndRewriteWithIndex().
ValueId mapAndRewriteCommon(ValueIdMap &map,
NABoolean mapDownwards);
public:
// Recursively walk this item expression tree and try to fold constants
// (e.g. by transforming the expression "5 + 3" to "8"). Note that
// at this time there is only limited intelligence built into this
// method. Errors (such as 1/0) and warnings are reported in the diags area.
// Unless allowed by setting newTypeSynthesis to TRUE, the folded expression
// will have the same type as the original expression.
virtual ItemExpr *foldConstants(ComDiagsArea *diagsArea,
NABoolean newTypeSynthesis = FALSE);
ItemExpr *foldConstants(BindWA *bindWA);
// Find common subexpressions in an expression, for example
// (C1 AND C2 AND C3) OR (C1 AND C2 AND C4) OR (C1 AND C5 AND C2 AND C6),
// and apply the inverse distributivity law to pull them out. This
// results in this example in a new expression:
// (C1 AND C2) AND (C3 OR C4 OR (C5 AND C6))
// The method may someday take operators other than OR and AND as well
// (e.g. + and *), but that will require some minor code changes.
ItemExpr *applyInverseDistributivityLaw(
OperatorTypeEnum backboneType = ITM_OR,
OperatorTypeEnum innerType = ITM_AND);
// little helper for the above method
ItemExpr *connect2(OperatorTypeEnum op, ItemExpr *op1, ItemExpr *op2);
// a virtual function for performing name binding within the query tree
// The following method performs name binding, allocates a ValueId and
// synthesizes the resultant type for the expression.
virtual ItemExpr *bindNode(BindWA *bindWA);
// a virtual function for performing name binding within the query tree
// The following method performs name binding, allocates a ValueId and
// synthesizes the resultant type for the UDFs or Subqueries in
// the expression.
virtual ItemExpr *bindUDFsOrSubqueries(BindWA *bindWA);
// this should be the entry point to bind an item expr tree,
// as the method checks the incomplete type and fills the
// unknown. It calls _bindNodeRoot() to do the real work. This
// method has the choice of returning "this" or the expression
// returned by _bindNodeRoot().
virtual ItemExpr *bindNodeRoot(BindWA *bindWA);
// prepare the expression to be bound again, e.g. after changing
// a child pointer, something that should be done only if we are
// sure the expression is not used elsewhere.
void unBind() { markAsUnBound(); setValueId(NULL_VALUE_ID); }
virtual NABoolean isTypeComplete(const NAType*) { return TRUE; };
virtual void reportTypeIsIncomplete() {};
void bindChildren(BindWA *bindWA); // a method for binding the children
void bindSelf(BindWA *bindWA); // a method for binding the children and self
// a method for binding host variables, dynamic parameters and constants.
ItemExpr *bindUserInput(BindWA *, const NAType *, const NAString &);
OperatorTypeEnum origOpType() const { return origOpType_; }
void setOrigOpType(OperatorTypeEnum o) { origOpType_ = o; }
//OperatorTypeEnum &origOpTypeBeingBound() { return origOpTypeBeingBound_; }
//Int32 &origOpTypeCounter() { return origOpTypeCounter_;}
// the NON-virtual encapsulating function for type-propagating the node
// (calls the virtual one, below)
const NAType *synthTypeWithCollateClause(BindWA *bindWA,
const NAType *type = NULL);
// a virtual function to determine whether an itemexpr can relax
// the charset matching rule for its children WITHOUT examining
// whether the children have Unicode hostvars
virtual NABoolean isRelaxCharTypeMatchRulesPossible() {return FALSE;};
// a virtual function to determine whether an itemexpr's type can
// be relaxed.
virtual NABoolean isCharTypeMatchRulesRelaxable() { return FALSE; };
// relax the charset matching rule for Unicode hostvars
virtual ItemExpr* tryToRelaxCharTypeMatchRules(BindWA *bindWA);
ItemExpr* performImplicitCasting(CharInfo::CharSet cs, BindWA *bindWA);
virtual ItemExpr* tryToDoImplicitCasting(BindWA *bindWA);
Int32 shouldPushTranslateDown(CharInfo::CharSet chrset) const;
virtual NABoolean CanChild0BeImplicitlyCast() { return TRUE; };
// a virtual function for type-propagating the node
virtual const NAType *synthesizeType();
// for expressions created after binding, do type synthesis w/o bind
// If the redriveTypeSynthesisFlag is set, it synthesises iself.
// If the redriveChildTypeSynthesis is set, it synthesizes the
// types for the entire subtree, from the leaves upto this operator,
// once again.
virtual void synthTypeAndValueId(NABoolean redriveTypeSynthesisFlag = FALSE,
NABoolean redriveChildTypeSynthesis = FALSE);
virtual void synthTypeAndValueId2(NABoolean redriveTypeSynthesisFlag = FALSE,
NABoolean redriveChildTypeSynthesis = FALSE);
// Propagate type information down the ItemExpr tree.
// Called by coerceType(). The default implementation
// does nothing. Currently is only redefined by ValueIdUnion
// to propagate the desired type to the sources of the ValueIdUnion.
//
virtual const NAType *pushDownType(NAType &desiredType,
enum NABuiltInTypeEnum defaultQualifier
= NA_UNKNOWN_TYPE);
virtual void coerceChildType(NAType& desiredType,
enum NABuiltInTypeEnum defaultQualifier);
// set/get resolving-incomplete-type status. Used by charset inference.
virtual void setResolveIncompleteTypeStatus(NABoolean x)
{ resolveIncompleteType_ = x; }
NABoolean getResolveIncompleteTypeStatus()
{ return resolveIncompleteType_ ; }
void setpreCodeGenNATypeChangeStatus()
{ preCodeGenNATypeChange_ = TRUE;}
NABoolean isPreCodeGenNATypeChanged()
{ return preCodeGenNATypeChange_;}
// --------------------------------------------------------------------
// transformNode()
//
// transformNode() is an overloaded name, which is used for a set
// of methods that implement the transformation phase of query
// normalization.
//
// We use the term query tree for a tree of relational operators,
// each of which can contain none or more scalar expression trees.
// The transformations performed by transformNode() brings scalar
// expressions into a canonical form. The effect of most such
// transformations is local to the scalar expression tree.
// However, the transformation of a subquery requires a semijoin
// to be performed between the relational operator that contains
// the subquery and the query tree for the subquery. The effect
// of such a subquery transformation is therefore visible not
// only in the scalar expression tree but also in the relational
// expression tree.
//
// Originally, transformNode() was a virtual method on ExprNode.
// The relational as well as scalar expressions are derived from
// ExprNode and used to provide proprietary implementations for it.
// However, relational and scalar expressions have different
// processing requirements during the transformation phase. Hence,
// each of them now support a virtual transformNode() method that
// differ in their interfaces.
//
// transformNode() uses four parameters, namely,
// 1) the normalizer work area
// 2) a location that contains the pointer to the (Rel/Item)Expr that
// is currently being processed.
// 3) a location in the query tree that can be updated by a
// subquery tranformation to introduce a new semijoin
// 4) the set of values that are available as external inputs to
// the RelExpr operator whose ItemExprs are being processed
// by transformNode().
//
//
// Parameters:
//
// NormWA & normWARef
// IN : a pointer to the normalizer work area
//
// ExprValueId & locationOfPointerToMe
// IN : a reference to the location that contains a pointer to
// the ItemExpr that is currently being processed.
//
// ExprGroupId & introduceSemijoinHere
// IN : a reference to the location in the query tree where a
// subquery transformation can introduce a semijoin. It
// is usually the location of the pointer to the relational
// operator with which the given predicate tree is associated.
//
// const ValueIdSet & externalInputs
// IN : the set of values that are available as external inputs to
// the RelExpr operator whose ItemExprs are being processed
// by transformNode().
//
// --------------------------------------------------------------------
virtual void transformNode(NormWA & normWARef,
ExprValueId & locationOfPointerToMe,
ExprGroupId & introduceSemiJoinHere,
const ValueIdSet & externalInputs);
// --------------------------------------------------------------------
// transformToRelExpr()
//
// transformToRelExpr() is an overloaded name, it is used during
// transformation by those classes that needs to convert an ItemExpr
// into a RelExpr.
//
// At the moment, it is used for subqueries and Isolated Routines.
//
// --------------------------------------------------------------------
virtual void transformToRelExpr(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 a multi-value predicate
// to ANDs and ORs of simpler subconditions,
// but only if all (by default) children are ItemList.
// Returns NULL if no transformation was necessary or possible.
virtual ItemExpr * transformMultiValuePredicate(
NABoolean flattenSubqueries = TRUE,
ChildCondition tfmIf = ANY_CHILD);
NABoolean referencesTheGivenValue(
const ValueId & exprId,
NABoolean doNotDigInsideVegRefs = FALSE,
NABoolean doNotDigInsideInstNulls = FALSE) const;
// does this item expression reference one of the set of ValueIds?
NABoolean referencesOneValueFrom(const ValueIdSet & vs) const;
// Is the item exprId the same value id, or if I'm a VEG is it
// contained in my set of values?
NABoolean containsTheGivenValue(const ValueId & exprId) const;
// Constant fold myself by evaluating all constants in the expression
// rooted at myself. During the process, 'this' object is not simplified.
// Return NULL if 'this' contains at least one non-constant or
// the evluation is not successful.
ItemExpr* constFold();
ItemExpr * createMirrorPred(ItemExpr *compColPtr,
ItemExpr *compColExprPtr,
const ValueIdSet &underlyingCols);
//Does 'this' ItemExpr evaluate to constant e.g.
//If we go by the strict definition then
//Sin(Cos(1)+1) will return TRUE.
//Sin(?p) will return FALSE.
//If we don't use the strict definition then
//Sin(?p) would be a constant and therefore
//we will get a return value of TRUE.
//The reason for this is that Sin(?p) is constant
//for a particular execution of a statement as
//?p remains constant for given execution of a statment
//And not only dynamic parameters like ?p but host vars
//like :h also stay constant for a particular execution
//of a query, therefore Sin(:h) will also return TRUE.
NABoolean doesExprEvaluateToConstant(NABoolean strict = TRUE,
NABoolean considerVEG = FALSE) const;
// This method returns TRUE or FALSE depending whether the optimizer
// should use stats to compute selectivity or use default selectivity
NABoolean useStatsForPred();
// get leaf expression if the cardinality for this expression can be
// estimated using histograms
ItemExpr * getLeafValueIfUseStats(NABoolean digIntoInstantiateNull = TRUE);
// get the value ids of all leaf nodes (arity 0) in this expression tree
void getLeafValueIds(ValueIdSet &lv) const;
void getLeafValueIds(ValueIdList &lv) const;
// get the value ids of all leaf nodes (arity 0) in this expression tree
void getLeafValueIdsForCaseExpr(ValueIdSet &lv);
// The following two methods are used during the transformation
// phase of normalization aka transformNode().
// predicateEliminatesNullAugmentedRows() determines whether the
// predicate is capable of discarding null augmented rows
// produced by a left join.
virtual NABoolean predicateEliminatesNullAugmentedRows(NormWA &, ValueIdSet &);
// initiateInnerToLeftJoinTransformation() is invoked when
// a predicateEliminatesNullAugmentedRows().
virtual ItemExpr * initiateLeftToInnerJoinTransformation(NormWA &);
// 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);
virtual ItemExpr * normalizeNode2(NormWA & normWARef);
// A helper function. Used by preCodeGen to convert external types
// to internal types.
ItemExpr * convertExternalType(Generator *);
// virtual method to fixup tree for code generation.
virtual ItemExpr * preCodeGen(Generator *);
// virtual method to do code generation
virtual short codeGen(Generator*);
// virtual method to generate Mdam predicates
virtual short mdamPredGen(Generator * generator,
MdamPred ** head,
MdamPred ** tail,
MdamCodeGenHelper & mdamHelper,
ItemExpr * parent);
// virtual method to get details of an mdam predicate, currently used only by
// BiRelat subclass.
virtual void getMdamPredDetails(Generator* generator,
MdamCodeGenHelper& mdamHelper,
enum MdamPred::MdamPredType& predType,
ex_expr** vexpr)
{ CMPASSERT(FALSE); }
// virtual method to generate MDAM_BETWEEN predicate. Redefined only for
// BiLogic subclass.
virtual void mdamPredGenSubrange(Generator* generator,
MdamPred** head,
MdamPred** tail,
MdamCodeGenHelper& mdamHelper)
{ CMPASSERT(FALSE); }
virtual void codegen_and_set_attributes(Generator *, Attributes **,Lng32);
inline ex_clause * getClause(){return clause_;};
inline void setClause(ex_clause * clause){clause_ = clause;};
// A method that determines if an item expression contains a subquery
virtual NABoolean containsSubquery();
// A method that determines if an item expression contains a UDF
virtual ItemExpr *containsUDF();
// A method that determines if an item expression contains an Isolated
// UDFunction
virtual NABoolean containsIsolatedUDFunction();
// A method that determines if an item expression contains a valueIdProxy
// that is derived from given valueId
virtual NABoolean containsValueIdProxySibling(const ValueIdSet &siblings);
// A method that determines if an item expression contains an aggregate of
// type ITM_ONE_ROW
NABoolean containsOneRowAggregate();
// A method that determines if an item expression contains an opType of
// type OperatorTypeEnum
NABoolean containsOpType(OperatorTypeEnum opType) const;
// A method that determines whether an item expression contains a child
// node (or grandchild node, or ...) that is untransformed. If it does,
// then the node itself, and the path to that child (or children) is
// also marked as untransformed.
NABoolean markPathToUnTransformedNode() ;
// A method that changes OneRow aggregate expression to a list
ItemExpr* transformOneRowAggregate( NormWA &);
ItemExpr* removeOneRowAggregate( ItemExpr *, NormWA &);
// A method to determine whether this is an equijoin predicate
NABoolean isAnEquiJoinPredicate(
const GroupAttributes* const leftGroupAttr,
const GroupAttributes* const rightGroupAttr,
const GroupAttributes* const joinGroupAttr,
ValueId & leftChildValueId,
ValueId & rightChildValueId,
NABoolean & isOrderPreserving) const;
// determines whether this is a join predicate for
// an operator under a nested join
NABoolean isANestedJoinPredicate (
const ValueIdSet& inputValues,
const ValueIdSet& operatorValues) const;
// determines whether a predicate references a constant
// in any of its operands (it may be a complicated
// predicate expression). Also, all the predicates that have
// constants are collected in constExprs.
void accumulateConstExprs (ValueIdSet & constExprs);
// is the predicate an equality predicate equating to a constant:
NABoolean equatesToAConstant () const;
// is the predicate an equality predicate equating to a constant, a
// host variable, or a parameter:
NABoolean equatesToAConstExpr () const;
// A method that determines whether evaluation of this predicate will preserve order
virtual NABoolean isOrderPreserving () const;
// A method that determines if an item expression is a subquery expression
virtual NABoolean isASubquery() const;
// An indicator whether this item expression is an aggregate function
// (aggregate functions can only be evaluated in groupby nodes).
virtual NABoolean isAnAggregate() const;
virtual NABoolean containsAnAggregate() const;
// An indicator whether this item expression is a predicate.
virtual NABoolean isAPredicate() const;
// An indicator whether this item expression is an expansion of a LIKE predicate.
// This is redefined only for class BiLogic.
virtual NABoolean isLike() const { return FALSE; }
// An indicator whether this item expression is a sequence function.
virtual NABoolean isASequenceFunction () const;
virtual NABoolean isOlapFunction () const;
// An indicator whether this item expression contains a THIS function.
virtual NABoolean containsTHISFunction();
// A transformation method that places a "NotTHIS" wrapper around an expression
virtual void transformNotTHISFunction();
// A transformation method for protecting sequence functions from not
// being evaluated due to short-circuit evaluation.
//
virtual void protectiveSequenceFunctionTransformation(Generator *generator);
// A method that returns for "user-given" input values.
// These are values that are either constants, host variables, parameters,
// or even values that are sensed from the environment such as
// current time, the user name, etcetera.
virtual NABoolean isAUserSuppliedInput() const;
// Is this a subclass of GenericUpdateOutputFunction BuildinFunction?
virtual NABoolean isAGenericUpdateOutputFunction() const { return FALSE; }
// a method that finds all occurences of a certain operator in an
// item expression tree
void findAll(OperatorTypeEnum wantedType,
ValueIdSet & result,
NABoolean visitVEGMembers = FALSE,
NABoolean visitIndexColDefs = FALSE);
template <class Result>
void findAllT(OperatorTypeEnum wantedType,
Result& result,
NABoolean visitVEGMembers = FALSE,
NABoolean visitIndexColDefs = FALSE);
// A variation of the above method that saves the matching ItemExprs in a
// ItemExprList. The order of occurences of these ItemExprs is maintained.
void findAll(OperatorTypeEnum wantedType,
ItemExprList& result,
NABoolean visitVEGMembers = FALSE,
NABoolean visitIndexColDefs = FALSE);
// Find the number of elements in the expression tree, and the maximum tree depth.
Lng32 getTreeSize(Lng32& maxDepth, NABoolean giveUpThreshold);
// Find all eqaulity columns in an item expression tree.
void findEqualityCols(ValueIdSet & result);
// execute transformation function f on each node of the tree and
// return the transformed tree
ItemExpr *treeWalk(ItemTreeWalkFunc f,
CollHeap *outHeap = NULL,
enum ItemTreeWalkSeq sequence = ITM_POSTFIX_WALK,
void *context = NULL);
// --------------------------------------------------------------------
// isCovered() : (for a ValueId)
//
// A method to determine whether a given ValueId is covered, i.e,
// it can be satisfied, by
// 1) the ValueIds that appear in the GroupAttributes of a relational
// operator and
// 2) a set of external dataflow inputs that are provided.
//
// An Item Expression isCovered() if each of its children isCovered().
//
// Parameters:
//
// ValueIdSet newExternalInputs
// IN : a read-only reference to a set of new external inputs
// (ValueIds) that will be provided to the new RelExpr anchor
// for evaluating the given predicate factor.
//
// GroupAttributes newRelExprAnchorGA
// IN : the Group Attributes of the new RelExpr anchor for
// the predicate factor.
//
// ValueIdSet referencedInputs
// OUT: a subset of newExternalInputs. It contains the ValueIds
// ValueIds of those inputs that are referenced in this
// ItemExpr.
//
// ValueIdSet coveredSubExpr
// OUT: It contains the ValueIds of all those sub-expressions
// of this item expression that are covered, while the
// containing item expression may not be covered.
//
// ValueIdSet unCoveredExpr
// OUT: If non-null, unCoveredExpr contains the value ids of all
// those expressions and/or subexpressions that could not
// be covered by the group attributes and the new inputs. In
// other words, unCoveredExpr contains the minimum set of
// additional value ids needed to cover the item expression.
//
// Returns TRUE : If ValueId is covered by newRelExprGA and the
// newExternalInputs
// FALSE: Otherwise.
//
// --------------------------------------------------------------------
virtual NABoolean isCovered(const ValueIdSet& newExternalInputs,
const GroupAttributes& newRelExprAnchorGA,
ValueIdSet& referencedInputs,
ValueIdSet& coveredSubExpr,
ValueIdSet& unCoveredExpr) const;
// --------------------------------------------------------------------
// Walk through an ItemExpr tree and gather the ValueIds of those
// expressions that behave as if they are "leaves" for the sake of
// the coverage test, e.g., expressions that have no children, or
// aggregate functions, or instantiate null. These are usually values
// that are produced in one "scope" and referenced above that "scope"
// in the dataflow tree for the query.
// --------------------------------------------------------------------
virtual void getLeafValuesForCoverTest(ValueIdSet & leafValues,
const GroupAttributes& coveringGA,
const ValueIdSet & newExternalInputs) const;
// --------------------------------------------------------------------
// replaceVEGExpressions()
//
// A method for replacing VEGReference and VEGPredicate objects
// with another expression that belongs to the VEG as well as to the
// set of availableValues.
//
// The lookup parameter provides a way to make replaceVEGExpressions
// idempotent when this is desired. This is useful in contexts where
// a VEGPredicate must be evaluated twice but using different physical
// implementations (e.g. when it is used to compute a begin or end key, but
// also must be part of an Executor predicate, all within the same
// scan node). If lookup is NULL, then replaceVEGExpressions is not
// idempotent, and will raise an assertion error when asked to process
// a VEGPredicate twice.
//
// If replicateExpression is set, then a copy of the expression tree
// is returned in which VEGReferences have been replaced.
//
// thisIsAKeyPredicate=TRUE indicates that the rewrite logic must
// make sure that a key predicate is generated from the VEG.
//
// In order to guarantee a keyColumn is returned when the
// thisIsAKeyPredicate flag is set, we also need the indexDesc parameter
//
// The two optional left_ga and right_ga
// are used when we resolve expressions in hash joins as we need to
// guarantee that an expression on the left side of an equipred only
// contains values avaiable on the left and vice versa.
//
// --------------------------------------------------------------------
virtual ItemExpr * replaceVEGExpressions
(const ValueIdSet& availableValues,
const ValueIdSet& inputValues,
NABoolean thisIsAKeyPredicate = FALSE,
VEGRewritePairs * lookup = NULL,
NABoolean replicateExpression = FALSE,
const ValueIdSet *joinInputAndPotentialOutput = NULL,
const IndexDesc *iDesc = NULL,
const GroupAttributes *left_ga = NULL,
const GroupAttributes *right_ga = NULL);
ItemExpr * replaceVEGExpressions1( VEGRewritePairs* lookup );
void replaceVEGExpressions2( Int32 index
, const ValueIdSet& availableValues
, const ValueIdSet& inputValues
, ValueIdSet& currAvailableValues
, const GroupAttributes * left_ga
, const GroupAttributes * right_ga
);
// ---------------------------------------------------------------------
// ItemExpr::replaceOperandsOfInstantiateNull()
// This method is used by the code generator for replacing the
// operands of an ITM_INSTANTIATE_NULL with a value that belongs
// to availableValues.
// ---------------------------------------------------------------------
void replaceOperandsOfInstantiateNull(const ValueIdSet &,
const ValueIdSet & inputValues );
// check whether this item expression delivers its values in the
// same order as another item expression, assuming this is an output
// value in the specified group
virtual OrderComparison sameOrder(ItemExpr *other,
NABoolean askOther = TRUE);
virtual OrderComparison sameOrder(VEGReference *other,
NABoolean askOther = TRUE);
virtual ItemExpr * simplifyOrderExpr(OrderComparison *newOrder = NULL);
// Replace VEG Reference by the constant contained in the VEG.
// This is done for all the VEG References rooted directly or
// indirectly at this. If no constant is found, this expression
// is not simpfified and a NULL is returned.
virtual ItemExpr * simplifyBeforeConstFolding();
// Return the only constant itemexpr contained in a VEG pointed by 'this'.
// If 'this' is not a VEG or has more than one constant, return NULL.
virtual ItemExpr* getConstantInVEG();
virtual ItemExpr * removeInverseOrder();
virtual SimpleHashValue hash(); // from ExprNode
virtual HashValue topHash(); // for this and all subclasses
HashValue treeHash();
virtual NABoolean duplicateMatch(const ItemExpr & other) const;
NABoolean genericDuplicateMatch(const ItemExpr &other) const;
virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
CollHeap* outHeap = 0);
// "virtual copy constructor", provides a generic method to duplicate
// the top node of an expression tree or an entire tree
ItemExpr * copyTree(CollHeap* outHeap=0);
// Is this operator supported by the synthesis functions?
virtual NABoolean synthSupportedOp() const { return FALSE; }
// Return the default selectivity for this predicate
virtual double defaultSel();
// This method will apply the selectivity of default predicate on histograms
virtual NABoolean applyDefaultPred(ColStatDescList & histograms,
OperatorTypeEnum exprOpCode,
ValueId predValueId,
NABoolean & globalPredicate,
CostScalar *maxSelectivity=NULL);
// This method will apply the selectivity of unsupported default predicate on histograms
NABoolean applyUnSuppDefaultPred(ColStatDescList & histograms,
ValueId predValueId,
NABoolean & globalPredicate);
// Helper method for applyDefaultPred methods
NABoolean checkForStats(ColStatDescList & histograms,
CollIndex & columnIndex,
ValueIdSet & leafValues);
NABoolean calculateUecs(ColStatDescList & histograms,
CostScalar & minUec,
CostScalar & maxUec);
void resetRealBigNumFlag(ItemExpr *node);
virtual NABoolean calculateMinMaxUecs(ColStatDescList & histograms,
CostScalar & minUec,
CostScalar & maxUec);
//++MV
// Return the selectivityFactor for this predicate.
// The selectivity factor is initialy set to -1, which means
// that the default selectivity is used. If the selectivity
// factor is set to a number between 0 and 1 , this number
// serves as the selectivity factor for this ItemExpr.
double getSelectivityFactor() const { return selectivityFactor_; }
void setSelectivityFactor(double selectivityFactor)
{ selectivityFactor_ = selectivityFactor; }
//--MV
// Return the inverse of the operator type if any. Otherwise, return its operatorType.
OperatorTypeEnum getInverseOpType () const;
// ---------------------------------------------------------------------
// MDAM Related methods
// ---------------------------------------------------------------------
// This is a recursive
// function that returns the leaf predicates of the tree
// whose root is the ItemExpr into the ValueIdSet&.
void getLeafPredicates(ValueIdSet& leafPredicates);
NABoolean referencesAHostVar() const;
// ---------------------------------------------------------------------
// Utility methods
// ---------------------------------------------------------------------
// Evaluate the exprssion at compile time. Assume all operands are constants.
// Return NULL if the computation fails and CmpCommon::diags() may be side-affected.
ConstValue* evaluate(CollHeap* heap);
// produce an ascii-version of the object (for display or saving into a file)
virtual void unparse(NAString &result,
PhaseEnum phase = DEFAULT_PHASE,
UnparseFormatEnum form = USER_FORMAT,
TableDesc * tabId = NULL) const;
void computeKwdAndFlags( NAString &kwd,
NABoolean &prefixFns,
NABoolean &specialPrefixFns,
PhaseEnum phase,
UnparseFormatEnum form,
TableDesc * tabId) const;
void computeKwdAndPostfix( NAString &kwd, NAString &postfix,
UnparseFormatEnum form = USER_FORMAT ) const ;
virtual void print(FILE * f = stdout,
const char * prefix = "",
const char * suffix = "") const;
void display();
// MDAM related methods
// ---------------------------------------------------------------------
// mdamTreeWalk is a virtual method. It is relevant only for the
// following ItemExprs at the current time:
// - VEGPredicate
// - BiLogic
// - UnLogic
// - BiRelat
//
// This tree walk will build a DisjunctArray for the expression sub-tree
// that it is invoked for. It is a recursive method which recurses down
// the tree and then back up. On its way up is when it returns the
// DisjunctArray built up to that point in the recursion.
//
// VEGPredicate, UnLogic, BiRelat Node Precessing
// ----------------------------------------------
// Predicates are encountered at the VEGPredicate, UnLogic, and BiRelat
// nodes. At these nodes:
// - A DisjunctArray is created.
// - A ValueIdSet is created with the value id of the predicate.
// - The address of the ValueIdSet is inserted into the DisjunctArray.
//
// BiLogic Node Processing
// -----------------------
// The BiLogic node is where all the main processing for MDAM gets done.
// This is where the left and right child of an AND or OR return
// DisjunctArrays. These DisjunctArrays are ANDed or ORed together.
// The resulting DisjunctArray is returned to the previous ItemExpr node
// in the recursion.
// ---------------------------------------------------------------------
virtual DisjunctArray * mdamTreeWalk();
NABoolean containsColumn();
// See coments for previousHostVar_ in private section
NABoolean &previousHostVar()
{
return previousHostVar_;
}
NAString &previousName()
{
return previousName_;
}
CollationAndCoercibility *& collateClause() { return collateClause_; }
static void cleanupPerStatement();
virtual ConstantParameter *castToConstantParameter() { return NULL; }
// perform a safe type cast to RandomNum (return NULL ptr for illegal casts)
virtual RandomNum *castToRandomNum() { return NULL; }
virtual const SelParameter *castToSelParameter() const { return NULL; }
// does this entire ItemExpr qualify query to be cacheable after this phase?
virtual NABoolean isCacheableExpr(CacheWA& cwa);
// is this single ExprNode cacheable after this phase?
NABoolean isCacheableNode(CmpPhase phase) const;
// mark this ExprNode as cacheable for this and later phases
void setCacheableNode(CmpPhase phase);
// is any literal in this expr safely coercible to its target type?
virtual NABoolean isSafelyCoercible(CacheWA& cwa) const;
// append an ascii-version of ItemExpr into cachewa.qryText_
virtual void generateCacheKey(CacheWA& cachewa) const;
// A helper routine for ItemExpr::generateCacheKey()
void addSelectivityFactor( CacheWA& cwa ) const ;
// return a string that identifies the operator. same as getText() except
// we prepend char set to string literals. This is to fix genesis case
// 10-040616-0347 "NF: query cache does not work properly on || for certain
// character set". If we change ConstValue::getText() for this fix, we risk
// breaking QA tests due to expected output diffs.
virtual const NAString getText4CacheKey() const { return getText(); }
// change literals of a cacheable query into constant parameters
virtual ItemExpr* normalizeForCache(CacheWA& cwa, BindWA& bindWA);
// return true if ItemExpr & its descendants have no constants
// and no noncacheable nodes
virtual NABoolean hasNoLiterals(CacheWA& cwa);
// return TRUE if this node can be used in a group by or order by expr.
// returns FALSE otherwise. Optionally sets error in diags area.
virtual NABoolean canBeUsedInGBorOB(NABoolean setErr);
// Defined only for HV's and Dynamic parameters
virtual ComColumnDirection getParamMode () const;
virtual Int32 getOrdinalPosition () const;
virtual Int32 getHVorDPIndex () const;
virtual void setPMOrdPosAndIndex( ComColumnDirection paramMode,
Int32 ordinalPosition,
Int32 index) { CMPASSERT (0);}
NABoolean isARangePredicate() const;
// get and set for flags_. See enum Flags.
NABoolean constFoldingDisabled() { return (flags_ & CONST_FOLDING_DISABLED) != 0; }
void setConstFoldingDisabled(NABoolean v)
{ (v ? flags_ |= CONST_FOLDING_DISABLED : flags_ &= ~CONST_FOLDING_DISABLED); }
// get and set for flags_. See enum Flags.
NABoolean inGroupByOrdinal() { return (flags_ & IN_GROUPBY_ORDINAL) != 0; }
void setInGroupByOrdinal(NABoolean v)
{ (v ? flags_ |= IN_GROUPBY_ORDINAL : flags_ &= ~IN_GROUPBY_ORDINAL); }
NABoolean inOrderByOrdinal() { return (flags_ & IN_ORDERBY_ORDINAL) != 0; }
void setInOrderByOrdinal(NABoolean v)
{ (v ? flags_ |= IN_ORDERBY_ORDINAL : flags_ &= ~IN_ORDERBY_ORDINAL); }
NABoolean isSelectivitySetUsingHint() { return (flags_ & SELECTIVITY_SET_USING_HINT) != 0; }
void setSelectivitySetUsingHint(NABoolean v = TRUE)
{ (v ? flags_ |= SELECTIVITY_SET_USING_HINT : flags_ &= ~SELECTIVITY_SET_USING_HINT); }
// get and set for flags_. See enum Flags.
NABoolean isGroupByExpr() const { return (flags_ & IS_GROUPBY_EXPR) != 0; }
void setIsGroupByExpr(NABoolean v)
{ (v ? flags_ |= IS_GROUPBY_EXPR : flags_ &= ~IS_GROUPBY_EXPR); }
// get and set for IS_RANGESPEC_ITEM_EXPR flag.
NABoolean isRangespecItemExpr() const { return (flags_ & IS_RANGESPEC_ITEM_EXPR) != 0; }
void setRangespecItemExpr(NABoolean v = TRUE)
{ (v ? flags_ |= IS_RANGESPEC_ITEM_EXPR : flags_ &= ~IS_RANGESPEC_ITEM_EXPR); }
NABoolean wasDefaultClause() const { return (flags_ & WAS_DEFAULT_CLAUSE) != 0; }
void setWasDefaultClause(NABoolean v)
{ (v ? flags_ |= WAS_DEFAULT_CLAUSE : flags_ &= ~WAS_DEFAULT_CLAUSE); }
NABoolean isGroupByRollup() const { return (flags_ & IS_GROUPBY_ROLLUP) != 0; }
void setIsGroupByRollup(NABoolean v)
{ (v ? flags_ |= IS_GROUPBY_ROLLUP : flags_ &= ~IS_GROUPBY_ROLLUP); }
virtual QR::ExprElement getQRExprElem() const;
virtual ItemExpr* removeRangeSpecItems(NormWA* normWA = NULL);
// output degree functions for ItemExprs that can have
// multiple outputs (such as scalar UDFs and subqueries).
virtual Int32 getOutputDegree() { return 1; }
virtual ItemExpr *getOutputItem(UInt32 i) { return this; }
protected:
// ---------------------------------------------------------------------
// This function does the real work of bind nodes for an expression.
// It calls bindNode on the tree and then fills any incomplete
// type information. Right now, it takes care of missing charset.
// ---------------------------------------------------------------------
virtual ItemExpr *_bindNodeRoot(BindWA *bindWA);
// A virtual function performing the actual charset matching rule relaxation
// on "this" ItemExpr by adding a translate node on top of "this". Return "this"
// if relaxation is done successfully or not necessary; return NULL if the relaxation
// failed.
virtual ItemExpr* performRelaxation(CharInfo::CharSet csTranslatedTo, BindWA *bindWA);
// A special version of the virtual function performing the actual charset
// matching rule relaxation for two ExprValueIds.
// Returns TRUE if the relaxation is successfully done and one of the ExprValueIds
// is changed, or relaxation is not necessary; return FALSE if the relaxation failed.
virtual NABoolean performRelaxation(ExprValueId* ie1, ExprValueId* ie2, BindWA *bindWA);
private:
enum Flags
{
// if set, then constant folding is disabled for this node.
// The child nodes are folded, if allowed.
CONST_FOLDING_DISABLED = 0x0001,
// if set, then subtree rooted below this ItemExpr has been referenced
// as a group by ordinal.
// Do not validate that all columns that are part of this expr
// need to be specified in the group by list.
IN_GROUPBY_ORDINAL = 0x0002,
// This flag indicates whether selectivity hint was specified
SELECTIVITY_SET_USING_HINT = 0x0004,
// if set, this ItemExpr (and the subtree rooted below)is a grouping
// column. This flag is used to ensure that translate expressions are
// not pushed below a grouping column. A grouping column is an expression
// specified in the GROUP BY clause
IS_GROUPBY_EXPR = 0x0008,
// If set, the subtree rooted by this ItemExpr was derived from a rangespec
// (see OptRangeSpec::getRangeItemExpr()). This flag is consulted to avoid
// repeating the rangespec analysis process when the expression is in more
// than one node.
IS_RANGESPEC_ITEM_EXPR = 0x0010,
// if set, then subtree rooted below this ItemExpr has been referenced
// as an order by ordinal.
IN_ORDERBY_ORDINAL = 0x0020,
// If set, this subtree was created while processing the DEFAULT
// clause in DefaultSpecification::bindNode.
WAS_DEFAULT_CLAUSE = 0x0040,
// if set, the subtree rooted below was part of "groupby rollup" clause.
// Currently used during parsing phase. See parser/sqlparser.y.
IS_GROUPBY_ROLLUP = 0x0080
};
// ---------------------------------------------------------------------
// The value identifier for this expression.
// This value is filled in by the binder for every expression.
// ---------------------------------------------------------------------
ValueId valId_;
// ---------------------------------------------------------------------
// The children of the expression tree (for expressions with more than
// two children, the indexing operator is redefined and uses other
// data members).
// ---------------------------------------------------------------------
ExprValueId inputs_[MAX_ITM_ARITY];
// ---------------------------------------------------------------------
// The index (0-based position) of the child currently being bound;
// after binding, it's one greater than the maximum index,
// i.e. the degree of the item -- see ItemExpr::bindSelf for more notes.
//
// Before transform/normalize, could be reset to 0 and again loop-incremented.
// Should this be made more general and moved to ExprNode?
// ---------------------------------------------------------------------
Lng32 currChildNo_;
// ---------------------------------------------------------------------
// SqlParser lets every value expression be followed by a COLLATE clause.
// When we're binding and have determined the type of the expr,
// we disallow it for non-CHARACTER-type exprs, and apply it to the CharTypes.
// ---------------------------------------------------------------------
CollationAndCoercibility * collateClause_;
// ---------------------------------------------------------------------
// A pointer to the scalar expression that replaces this expression
// during the transformation/normalization phase.
// ---------------------------------------------------------------------
ItemExpr * replacementExpr_;
// ---------------------------------------------------------------------
// A pointer to the generated clause for this ItemExpr.
// Set and used at code generation time to fixup stuff in
// the generated clause after code generation.
// For example, to backpatch branch addresses for boolean clauses.
// ---------------------------------------------------------------------
ex_clause * clause_;
// ---------------------------------------------------------------------
// The optype of the item that the user actually specified;
// it will differ from the item's getOperatorType() only if
// the Binder rewrites the item (usually a function) in terms of other
// item primitives; e.g. for ZZZBinderFunction or Aggregate functions.
// ---------------------------------------------------------------------
OperatorTypeEnum origOpType_;
//static THREAD_P OperatorTypeEnum origOpTypeBeingBound_;
//static THREAD_P Int32 origOpTypeCounter_;
// ------------------
// Object Counter
// ------------------
static THREAD_P ObjectCounter *counter_;
// Indicates if this is an expression that originally was a hostvar but
// got changed to something else after binding (for instance, a column).
// This can happen in a compound statement when we do an INTO :hostvar and
// use that hostvar later on in the same compound statement
NABoolean previousHostVar_;
NAString previousName_;
// an indicator on whether to resolve incomplete types
// in the method BindNodeRoot().
NABoolean resolveIncompleteType_ ;
NABoolean preCodeGenNATypeChange_;
//++MV
// If selectivityFactor_ is not negative, then it contains the assumed selectivity
// for this item expression (known by the optimizer or by inline information).
// The item expression that has a non negative selectivityFactor, will be categorize
// as a Default Predicate and the defaultSel method will return this attribute.
double selectivityFactor_;
//--MV
UInt32 flags_;
}; // class ItemExpr
// -----------------------------------------------------------------------
// Inlines that couldn't be defined till now due to dependencies
// -----------------------------------------------------------------------
inline ItemExpr * ExprValueId::operator ->() const { return getPtr(); }
inline ExprValueId::operator ItemExpr *() const { return getPtr(); }
#endif /* ITEMEXPR_H */