/**********************************************************************
// @@@ 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 */
