/**********************************************************************
// @@@ 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 ITEMFUNC_H
#define ITEMFUNC_H
/* -*-C++-*-
******************************************************************************
*
* File:         ItemFunc.h
* Description:  Functions and Aggregate item expressions
*		Aggregates to be used in groupby rel. operators.
*               Functions (and aggregates?) may be built-ins or user-defined.
* Created:      11/04/94
* Language:     C++
*
*
*
*
******************************************************************************
*/

// -----------------------------------------------------------------------
// When adding new BuiltinFunctions herein,
// take heed of the problem documented at Abs::preCodeGen() ...
// -----------------------------------------------------------------------
#include "IntervalType.h"
#include "CharType.h"
#include "DatetimeType.h"
#include "ItemExpr.h"
#include "NATable.h"
#include "exp_like.h"
#include "QRExprElement.h"
#include "ExpLOBenums.h"

// -----------------------------------------------------------------------
// forward references
// -----------------------------------------------------------------------
class CharType;
class DisjunctArray;
class Generator;
class RangePartitioningFunction;
class IntegerList;
class NARoutine;
class ItemList;
class RoutineDesc;

// -----------------------------------------------------------------------
// aggregate functions
//
// The aggregate functions designed for subquery transformations are:
// ITM_ONE_ROW  :
//   Used for transforming a scalar or a row subquery.
//   Its argument is the select list of the subquery.
//   It returns the first group formed by these values.
//   It returns a null if there are no groups.
//   It issues an error if there is more than one group.
// ITM_ONE_TRUE:
//   Used for transforming an exists subquery
//   Its argument is the select list of the subquery.
//   It returns TRUE if the result of the subquery is not empty
//   It returns FALSE, otherwise.
// ITM_ANY_TRUE:
//   Used in for IN, = ANY, <> ANY, = ALL, <> ALL subqueries.
//   Its argument is a boolean predicate that expresses
//   the original predicate without the quantifier.
//   This aggregate function returns a boolean value.
//   It returns TRUE  its argument evaluates to TRUE for any row in
//                    the group,
//   It returns NULL  if its argument evaluates to NULL for at least one
//                    row in the group and if for no row the argument
//                    evaluates to TRUE,
//   It returns FALSE if its argument evaluates to FALSE for each row in
//                    the group or if the group is empty.
//   In other words, it returns an indication whether it is provable that
//   for any row in the group its boolean argument evaluates to TRUE.
//   For > ANY, < ANY, ... subqueries, more specialized functions can be
//   used that allow MIN/MAX optimizations (see class QuantifiedAggregate).
// -----------------------------------------------------------------------
class Aggregate : public ItemExpr
{
  // ITM_AVG, ITM_MAX, ITM_MIN, ITM_SUM, ITM_COUNT,
  // ITM_ONE_ROW, ITM_ONEROW, ITM_ONE_TRUE, ITM_ANY_TRUE
public:
  Aggregate(OperatorTypeEnum otype,
	    ItemExpr *child0,
	    NABoolean isDistinct,
	    OperatorTypeEnum otypeSpecifiedByUser,
	    char /*just to disambiguate from next ctor!*/)
    : ItemExpr(otype, child0),
      origChild_(child0),
      isDistinct_(isDistinct),
      inScalarGroupBy_(FALSE),
      distinctId_(NULL_VALUE_ID),
      treatAsACount_(FALSE),
      amTopPartOfAggr_(FALSE),
      isOLAP_(FALSE),
      olapPartitionBy_(NULL),
      olapOrderBy_(NULL),
      frameStart_(-INT_MAX),
      frameEnd_(INT_MAX),
      rollupGroupIndex_(-1)
    { setOrigOpType(otypeSpecifiedByUser); }
  Aggregate(OperatorTypeEnum otype,
	    ItemExpr *child0 = NULL,
	    NABoolean isDistinct = FALSE,
	    ValueId distinctId = NULL_VALUE_ID)
    : ItemExpr(otype, child0),
      origChild_(child0),
      isDistinct_(isDistinct),
      inScalarGroupBy_(FALSE),
      distinctId_(distinctId),
      treatAsACount_(FALSE),
      amTopPartOfAggr_(FALSE),
      isOLAP_(FALSE),
      olapPartitionBy_(NULL),
      olapOrderBy_(NULL),
      frameStart_(-INT_MAX),
      frameEnd_(INT_MAX),
      rollupGroupIndex_(-1)
    {}
  Aggregate(OperatorTypeEnum otype,
	    ItemExpr *child0,
	    ItemExpr *child1,
	    NABoolean isDistinct = FALSE,
	    ValueId distinctId = NULL_VALUE_ID)
    : ItemExpr(otype, child0, child1),
      origChild_(child0),
      isDistinct_(isDistinct),
      inScalarGroupBy_(FALSE),
      distinctId_(distinctId),
      treatAsACount_(FALSE),
      amTopPartOfAggr_(FALSE),
      isOLAP_(FALSE),
      olapPartitionBy_(NULL),
      olapOrderBy_(NULL),
      frameStart_(-INT_MAX),
      frameEnd_(INT_MAX),
      rollupGroupIndex_(-1)
    {}

  // virtual destructor
  virtual ~Aggregate();

  // append an ascii-version of ItemExpr into cachewa.qryText_
  virtual void generateCacheKey(CacheWA& cwa) const;

  // get the degree of this node (it is a unary op).
  virtual Int32 getArity() const;

  virtual NABoolean isAnAggregate() const;
  virtual NABoolean containsAnAggregate() const;

  // Are two Aggregates equivalent?
  virtual NABoolean operator == (const ItemExpr& other) const;

  // a virtual function for performing name binding within the query tree
  virtual ItemExpr * bindNode(BindWA *bindWA);

  // a virtual function for type propagating the node
  virtual const NAType * synthesizeType();

  NABoolean isRelaxCharTypeMatchRulesPossible() {return TRUE;};

  // a method for initializing the result
  void setAggrResult(ValueId vid) 		{ result_ = vid; }
  ValueId getAggrResult() 			{ return result_; }

  inline NABoolean isDistinct() const   	{ return isDistinct_; }
  void setDistinct(NABoolean dist = TRUE)
  {
    isDistinct_ = dist;
    distinctId_ = dist ? child(0)->getValueId() : NULL_VALUE_ID;
  }
  inline void setDistinctValueId(ValueId vid)   { distinctId_ = vid; }
  ValueId getDistinctValueId() const	        { return distinctId_; }

  // Agregates in non-Scalar GroupBy cannot evaluate to null
  // if their argument is not nullable
  inline NABoolean inScalarGroupBy() const         { return inScalarGroupBy_;}
  inline void setInScalarGroupBy()                 { inScalarGroupBy_ = TRUE;}

  NABoolean treatAsACount() const { return treatAsACount_;}
  void setTreatAsACount() { treatAsACount_ = TRUE;}

  const OperatorTypeEnum getEffectiveOperatorType() const {
    if(treatAsACount()) {
      return ITM_COUNT_NONULL;
    } 
    return getOperatorType();
  }

  NABoolean topPartOfAggr() const { return amTopPartOfAggr_;}
  void setTopPartOfAggr() { amTopPartOfAggr_ = TRUE;}

  virtual NABoolean isSensitiveToDuplicates() const;

  // Each operator supports a (virtual) method for transforming its
  // scalar expressions to a canonical form
  virtual void transformNode(NormWA & normWARef,
			     ExprValueId & locationOfPointerToMe,
                             ExprGroupId & introduceSemiJoinHere,
			     const ValueIdSet & externalInputs);

  // Each operator supports a (virtual) method for transforming its
  // query tree to a canonical form.
  virtual ItemExpr * normalizeNode(NormWA & normWARef);

  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;

  // method to do code generation
  virtual short codeGen(Generator*);
  virtual void codegen_and_set_attributes(Generator *, Attributes **, Lng32);

  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
				 CollHeap* outHeap = 0);

  // A method for determining whether the evaluation of this aggregate
  // function can be staged.
  virtual NABoolean evaluationCanBeStaged() const;

  // rewriting aggregate functions for elimination, parallelization
  virtual ItemExpr * rewriteForElimination();
  virtual ItemExpr * rewriteForStagedEvaluation(
       ValueIdList &initialAggrs,
       ValueIdList &finalAggrs,
       NABoolean sameFormat = FALSE);

  NABoolean isEquivalentForBinding(const ItemExpr * other);

  virtual ValueId mapAndRewrite(ValueIdMap &map,
				NABoolean mapDownwards = FALSE);

  virtual NABoolean duplicateMatch(const ItemExpr & other) const;

  // get a printable string that identifies the operator
  virtual const NAString getText() const;

  // 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;

  #define ITM_COUNT_STAR__ORIGINALLY	REL_AGGREGATE
  ItemExpr *getOriginalChild() const		   { return origChild_; }
  void setOriginalChild(ItemExpr *c)		   { origChild_ = c; }

  NABoolean isOneRowTransformed_;

  virtual NABoolean hasEquivalentProperties(ItemExpr * other) { return TRUE;}
  NABoolean isOLAP() { return isOLAP_; };

  void setOLAPInfo(ItemExpr *partBy, 
                   ItemExpr *orderBy,
                   Lng32 rowsStart,
                   Lng32 rowsEnd)
  {
    olapPartitionBy_ = partBy;
    olapOrderBy_ = orderBy;
    frameStart_ = rowsStart;
    frameEnd_ = rowsEnd;
    isOLAP_ = TRUE;
  };
  /*
  ItemExpr *getOlapPartitionBy() { return olapPartitionBy_; };
  ItemExpr *getOlapOrderBy() { return olapOrderBy_; };
  */

  Lng32 getframeStart()
  {
    return frameStart_;
  }

  Lng32 getframeEnd()
  {
    return frameEnd_;
  }

    NABoolean isFrameStartUnboundedPreceding() const
  {
    return (frameStart_ == -INT_MAX);
  }

   NABoolean isFrameStartUnboundedFollowing() const
  {
    return (frameStart_ == INT_MAX);
  }
  NABoolean isFrameEndUnboundedPreceding() const
  {
    return (frameEnd_ == -INT_MAX);
  }

  NABoolean isFrameEndUnboundedFollowing() const
  {
    return (frameEnd_ == INT_MAX);
  }

  virtual QR::ExprElement getQRExprElem() const;

  void setRollupGroupIndex(Int16 v) { rollupGroupIndex_ = v; }
  Int16 getRollupGroupIndex() { return rollupGroupIndex_; }

private:

  // The ValueId of the Item Expression that represents the result.
  // For example, if T(a int not null, b int not null), then the
  // result of sum(a,b) are the expressions a', b' where a' and b'
  // are both nullable.
  ValueId  result_;

  // indicate whether this is a DISTINCT aggregate
  NABoolean isDistinct_;

  // indicate whether this aggregate is for a scalar group by
  NABoolean inScalarGroupBy_;

  // ValueId of the distinct expression. usually, this is the
  // valueId of the child itemExpr, but in cases such as Variance,
  // it could be something different.
  ValueId distinctId_;

  // The original child specified by the user, before Parser and/or Binder
  // transformed it to something else.
  ItemExpr *origChild_;


  void setOlapOrderBy(ItemExpr *orderBy) { olapOrderBy_ = orderBy;};

  ItemExpr *removeOlapOrderBy()
  {
    ItemExpr *orderBy = olapOrderBy_;
    olapOrderBy_ = NULL;
    return orderBy;
  };

  ItemExpr *transformOlapFunction( BindWA *bindWA );
  OperatorTypeEnum mapOperTypeToRunning() const;
  OperatorTypeEnum mapOperTypeToOlap() const;
  OperatorTypeEnum mapOperTypeToMoving() const;

  // OLAP Info
  NABoolean isOLAP_;

  ItemExpr *olapPartitionBy_;
  ItemExpr *olapOrderBy_;

  Lng32 frameStart_;
  Lng32 frameEnd_;

  // true iff am top part of a rewritten COUNT aggregate
  NABoolean treatAsACount_;

  // true iff am top part of a rewritten aggregate
  NABoolean amTopPartOfAggr_;

  // this field indicates the index into rollupGroupExprList of GroupByAgg
  // that corresponds to the child of GROUPING aggr.
  Int16 rollupGroupIndex_;
}; // class Aggregate


// Variance -  Variance is an aggregate itemExpr derived from the
// Aggregate class.  This class implements the compiler side of the Variance
// and Stddev aggregates. This new class redefines the {con,de}structor, the
// bindNode method, and the getText method.  The other methods are NEVER called
// for this class and have (for now) been redefined to ASSERT if called.
//
// This node will be replaced during binding by an ItemExpr tree rooted
// by a ScalarVariance node. This new tree is bound and returned as the
// result of Variance::bindNode(). Because of this, the Variance node
// should never appear after binding.
//
class Variance : public Aggregate
{
public:
  // Variance implements the Item types ITM_VARIANCE, ITM_STDDEV
  // These Item types are also used by the ScalarVariance node and the
  // ExFunctionVariance and ExFunctionStddev builtin functions.

  // Constructor. - This aggregate can have one or two children.
  // The optional second parameter (child) is the weighting factor.
  //
  Variance(OperatorTypeEnum otype,
		  ItemExpr *child0 = NULL,
		  ItemExpr *child1 = NULL,
		  NABoolean isDistinct = FALSE)
    : Aggregate(otype, child0, child1, isDistinct)
  {}

  // virtual destructor
  virtual ~Variance();

  // a virtual function for performing name binding within the query tree.
  // This method will replace the Variance node with a tree of nodes rooted
  // by a ScalarVariance node. This new tree is bound and returned as the
  // result of bindNode of Variance. Because of this, the Variance node
  // should never appear after binding.
  //
  virtual ItemExpr * bindNode(BindWA *bindWA);

  // MV --
  // In multi-delta refresh, copyTopNode() is called to dulicate the
  // unbound expression.
  virtual ItemExpr * copyTopNode(ItemExpr * = NULL, CollHeap* = 0);

  // The following virtual methods should never be called on the Variance
  // node.  They have been redefined to ASSERT if called.
  //
  virtual void transformNode(NormWA & normWARef,
			     ExprValueId & locationOfPointerToMe,
                             ExprGroupId & introduceSemiJoinHere,
			     const ValueIdSet & externalInputs)  {CMPASSERT(0)}
  virtual ItemExpr * normalizeNode(NormWA & normWARef){CMPASSERT(0); return 0;}
  virtual NABoolean isCovered(const ValueIdSet& newExternalInputs,
			      const GroupAttributes& newRelExprAnchorGA,
	   	              ValueIdSet& referencedInputs,
			      ValueIdSet& coveredSubExpr,
			      ValueIdSet& unCoveredExpr) const
  						  {CMPASSERT(0); return TRUE;}
  virtual void getLeafValuesForCoverTest(ValueIdSet & leafValues, 
                      const GroupAttributes& coveringGA, const ValueIdSet & newExternalInputs
		      ) const {CMPASSERT(0);}
  virtual short codeGen(Generator*)		  {CMPASSERT(0); return 0;}
  virtual NABoolean evaluationCanBeStaged() const {CMPASSERT(0); return TRUE;}
  virtual ItemExpr * rewriteForElimination()	  {CMPASSERT(0); return 0;}
  virtual ItemExpr * rewriteForStagedEvaluation(
       ValueIdList &initialAggrs,
       ValueIdList &finalAggrs,
       NABoolean sameFormat = FALSE)		  {CMPASSERT(0); return 0;}


private:
}; // class Variance

class PivotGroup : public Aggregate
{
public:
  enum PivotOptionType
  {
    DELIMITER_,
    ORDER_BY_,
    MAX_LENGTH_
  };

  enum {
    DEFAULT_MAX_LEN = 1024
  };

  class PivotOption
  {
    friend class PivotGroup;
  public:
  PivotOption(PivotOptionType option, 
              void * optionNode = NULL,
              char * stringVal = NULL,
              Long numericVal = 0)
    : option_(option), 
      optionNode_(optionNode),
      stringVal_(stringVal),
      numericVal_(numericVal)
    {}
    
  private:
    PivotOptionType option_;
    void * optionNode_;
    Long   numericVal_;
    char * stringVal_;
  };

  // PivotGroup implements the Item ITM_PIVOT_GROUP.
  // This is used to implement pivot groups.

  // Constructor. - This aggregate can have one or two children.
  // The optional second parameter (child) is the weighting factor.
  //
  PivotGroup(OperatorTypeEnum otype,
             ItemExpr *child0,
             NAList<PivotOption*> * pivotOptionsList,
             NABoolean isDistinct = FALSE);

  PivotGroup(OperatorTypeEnum otype,
             ItemExpr *child0,
             NAString &delim,
             NABoolean orderBy,
             ValueIdList &reqdOrder,
             Lng32 maxLen,
             NABoolean isDistinct = FALSE)
  : Aggregate(otype, child0, NULL, isDistinct),
    delim_(delim),
    orderBy_(orderBy),
    reqdOrder_(reqdOrder),
    maxLen_(maxLen)
    {}
  
  // virtual destructor
  virtual ~PivotGroup();

  const NAType *synthesizeType();

  // a virtual function for performing name binding within the query tree.
  virtual ItemExpr * bindNode(BindWA *bindWA);

  virtual ItemExpr * copyTopNode(ItemExpr * = NULL, CollHeap* = 0);

  virtual ItemExpr * preCodeGen(Generator * generator);

  virtual short codeGen(Generator*);

  // append an ascii-version of BETWEEN into cachewa.qryText_
  virtual void generateCacheKey(CacheWA& cwa) const;

  virtual NABoolean evaluationCanBeStaged() const {return TRUE;}
  virtual ItemExpr * rewriteForStagedEvaluation(
       ValueIdList &initialAggrs,
       ValueIdList &finalAggrs,
       NABoolean sameFormat = FALSE);

  NAString &delim() { return delim_; }
  NABoolean orderBy() { return orderBy_;}
  ValueIdList &reqdOrder() { return reqdOrder_; }
  Lng32 maxLen() { return maxLen_; }
  ItemExpr *getOrderbyItemExpr() { return orgReqOrder_; } 
private:
  NAList<PivotOption*> * pivotOptionsList_;

  NAString delim_;

  NABoolean orderBy_;
  ValueIdList reqdOrder_;   	// ORDER BY list
  ItemExpr *orgReqOrder_;
  
  Lng32 maxLen_;
}; // class PivotGroup

// -----------------------------------------------------------------------
// Function operators supporting a variable number of children
// -----------------------------------------------------------------------
class Function : public ItemExpr
{
  // ITM_BETWEEN, ITM_LIKE, ITM_USER_DEF_FUNCTION
public:

  Function(OperatorTypeEnum otype = ITM_USER_DEF_FUNCTION,
           NAMemory *h = CmpCommon::statementHeap(),
	   Lng32 argumentCount = 0,
	   ItemExpr *child0 = NULL,
	   ItemExpr *child1 = NULL,
	   ItemExpr *child2 = NULL,
	   ItemExpr *child3 = NULL,
	   ItemExpr *child4 = NULL,
	   ItemExpr *child5 = NULL);
  
  Function(OperatorTypeEnum otype,
           const LIST(ItemExpr *) &children,
           CollHeap *h=CmpCommon::statementHeap());
  
  //Function(OperatorTypeEnum otype, NABoolean isLeaf)
  //  : ItemExpr(otype),
  //    children_(CmpCommon::statementHeap()),
  //    allowsSQLnullArg_(TRUE)
  //{};
  
  // virtual destructor
  virtual ~Function();

  // ## This should be moved to ExprNode.h.
  // ## See how Aggregate::getArity() duplicates its logic...
  Lng32 getNumChildren() const;

  NABoolean &allowsSQLnullArg()		     	{ return allowsSQLnullArg_; }

  // a virtual function for performing name binding within the query tree
  virtual ItemExpr * bindNode(BindWA *bindWA);

  // a virtual function for type propagating the node
  virtual const NAType * synthesizeType();

  virtual NABoolean duplicateMatch(const ItemExpr & other) const;

  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
				 CollHeap* outHeap = 0);

  // since this operator may have variable arity, the access operators
  // to its children are overloaded and use a private child list
  virtual ExprValueId & operator[] (Lng32 ix);
  virtual const ExprValueId & operator[] (Lng32 ix) const;

  // 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); }

  ARRAY(ExprValueId) &children()  { return children_; }

  virtual NABoolean isOrderPreserving() const;

  // by default, we do NOT want Function itemexprs to be cacheable as a
  // guard against false cache hits. However, we selectively override this
  // in derived classes after guarding against false cache hits there.
  virtual NABoolean isCacheableExpr(CacheWA& cwa) { return FALSE; }

  // append an ascii-version of ItemExpr into cachewa.qryText_
  virtual void generateCacheKey(CacheWA& cwa) const
    { ItemExpr::generateCacheKey(cwa); }

  virtual QR::ExprElement getQRExprElem() const;

private:

  // Whether the SQL NULL keyword (our NULL ConstValue) may appear
  // in the argument list of this function.
  NABoolean allowsSQLnullArg_;

  ARRAY(ExprValueId) children_;

};

// -----------------------------------------------------------------------
// Built-in functions
// -----------------------------------------------------------------------
class BuiltinFunction : public Function
{
  // ITM_BETWEEN, ITM_LIKE, ITM_CURRENT and more
public:
  BuiltinFunction(OperatorTypeEnum otype,
                  NAMemory *h = CmpCommon::statementHeap(),
		  Lng32  argumentCount = 0,
		  ItemExpr *child0 = NULL,
		  ItemExpr *child1 = NULL,
		  ItemExpr *child2 = NULL,
		  ItemExpr *child3 = NULL,
		  ItemExpr *child4 = NULL,
		  ItemExpr *child5 = NULL);
  
  BuiltinFunction(OperatorTypeEnum otype,
                  NAMemory *h,
		  const LIST(ItemExpr *) &children)
       : Function(otype,children,h) {}
  
  // virtual destructor
  virtual ~BuiltinFunction();

  // get the degree of this node (it depends on the type of the operator)
  virtual Int32 getArity() const;

  // a virtual function for performing name binding within the query tree
  virtual ItemExpr * bindNode(BindWA *bindWA);

  // Each operator supports a (virtual) method for transforming its
  // scalar expressions to a canonical form
  virtual void transformNode(NormWA & normWARef,
			     ExprValueId & locationOfPointerToMe,
                             ExprGroupId & introduceSemiJoinHere,
			     const ValueIdSet & externalInputs);

  // Each operator supports a (virtual) method for transforming its
  // query tree to a canonical form.
  virtual ItemExpr * normalizeNode(NormWA & normWARef);

  virtual NABoolean isCovered(const ValueIdSet& newExternalInputs,
			      const GroupAttributes& newRelExprAnchorGA,
	   	              ValueIdSet& referencedInputs,
			      ValueIdSet& coveredSubExpr,
			      ValueIdSet& unCoveredExpr) const;

  virtual NABoolean isCacheableExpr(CacheWA& cwa);

  // a virtual function for type propagating the node
  virtual const NAType * synthesizeType();

  // method to do precode generation
  virtual ItemExpr * preCodeGen(Generator*);

  // method to do code generation
  virtual short codeGen(Generator*);

  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
				 CollHeap* outHeap = 0);

  // get a printable string that identifies the operator
  virtual const NAString getText() const;

  // see ExprNode.h for explanation.
  virtual const NAString getTextForError() const;

  // This method tells if a VEG transformation can potentially
  // change the result of this function.
  // For ex., a query "select char_length(a) from t where a = 'v'"
  // where column 'a' is 2 bytes, will return 1 if column 'a' in
  // char_length function is replaced by constant "v".
  // This method must be redefined to return TRUE for
  // any function that can get changed by a VEG transformation.
  // See BuiltinFunction::bindNode in BindItemExpr.cpp on
  // how these functions are protected.
  virtual NABoolean protectFromVEGs()
  {
    return FALSE;
  }

  // append an ascii-version of ItemExpr into cachewa.qryText_
  virtual void generateCacheKey(CacheWA& cwa) const
    { Function::generateCacheKey(cwa); }

  virtual NABoolean calculateMinMaxUecs(ColStatDescList & histograms,
					       CostScalar & minUec,
					       CostScalar & maxUec);

private:

}; // class BuiltinFunction

class CacheableBuiltinFunction : public BuiltinFunction
{
public:
  CacheableBuiltinFunction
    (OperatorTypeEnum otype,
     Lng32  argumentCount = 0,
     ItemExpr *child0 = NULL,
     ItemExpr *child1 = NULL,
     ItemExpr *child2 = NULL,
     ItemExpr *child3 = NULL,
     ItemExpr *child4 = NULL,
     ItemExpr *child5 = NULL)
    : BuiltinFunction
      (otype,CmpCommon::statementHeap(),
       argumentCount,child0,child1,child2,child3,child4,child5) {}

  // classes derived from CacheableBuiltinFunction are cacheable
  virtual NABoolean isCacheableExpr(CacheWA& cwa)
    { return ItemExpr::isCacheableExpr(cwa); }

  // -----------------------------------------------------------------
  // NB: By default, we want to parameterize us and our children. This 
  // is accomplished by inheriting our base class' normalizeForCache.
  // If it is unsafe to parameterize, we (the derived class)
  // must supply its own implementation of normalizeForCache.
  // -----------------------------------------------------------------

  // -----------------------------------------------------------------------
  // NB: If derived class has its own data member(s), we must make its data
  // member(s) contribute to its cache key via our own generateCacheKey here.
  // ------------------------------------------------------------------------
}; // class CacheableBuiltinFunction

//++Triggers,
//
// Built in function that should be evaluate only once
class EvaluateOnceBuiltinFunction : public BuiltinFunction
{
public:
  EvaluateOnceBuiltinFunction(OperatorTypeEnum otype,
			 Lng32  argumentCount = 0,
			 ItemExpr *child0 = NULL,
			 ItemExpr *child1 = NULL,
			 ItemExpr *child2 = NULL,
			 ItemExpr *child3 = NULL,
			 ItemExpr *child4 = NULL,
			 ItemExpr *child5 = NULL)
    : BuiltinFunction(otype,CmpCommon::statementHeap(),argumentCount,
                      child0,child1,child2,child3,child4,child5)
     {}

  inline EvaluateOnceBuiltinFunction(OperatorTypeEnum otype,
			 const LIST(ItemExpr *) &children)
			 : BuiltinFunction(otype,
                                           CmpCommon::statementHeap(),
                                           children) {}

  // virtual destructor
  virtual ~EvaluateOnceBuiltinFunction();

  // should return always true
  virtual NABoolean isAUserSuppliedInput() const;

  // should return always false
  virtual NABoolean isCovered(const ValueIdSet& newExternalInputs,
			      const GroupAttributes& newRelExprAnchorGA,
	   	          ValueIdSet& referencedInputs,
			      ValueIdSet& coveredSubExpr,
			      ValueIdSet& unCoveredExpr) const;

}; // class EvaluateOnceBuiltinFunction


class UniqueExecuteId : public EvaluateOnceBuiltinFunction
{
public:
  UniqueExecuteId()
	: EvaluateOnceBuiltinFunction(ITM_UNIQUE_EXECUTE_ID) {}

  // virtual destructor
  virtual ~UniqueExecuteId();

  // a virtual function for performing name binding within the query tree
  virtual ItemExpr * bindNode(BindWA *bindWA);


  // a virtual function for type propagating the node
  virtual const NAType * synthesizeType();

  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
				 CollHeap* outHeap = 0);

}; // class UniqueExecuteId

class GetTriggersStatus : public EvaluateOnceBuiltinFunction
{
public:
  GetTriggersStatus()
	: EvaluateOnceBuiltinFunction(ITM_GET_TRIGGERS_STATUS) {}

  // virtual destructor
  virtual ~GetTriggersStatus();

  // a virtual function for performing name binding within the query tree
  virtual ItemExpr * bindNode(BindWA *bindWA);


  // a virtual function for type propagating the node
  virtual const NAType * synthesizeType();

  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
				 CollHeap* outHeap = 0);

}; // class GetTriggersStatus

class GetBitValueAt : public BuiltinFunction
{
public:
  GetBitValueAt(ItemExpr *val1Ptr, ItemExpr *val2Ptr)
       : BuiltinFunction(ITM_GET_BIT_VALUE_AT, CmpCommon::statementHeap(), 
                         2, val1Ptr, val2Ptr)
	 { allowsSQLnullArg() = FALSE; }

  // virtual destructor
  virtual ~GetBitValueAt();

  // a virtual function for type propagating the node
  virtual const NAType * synthesizeType();

  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
				 CollHeap* outHeap = 0);

}; // class GetBitValueAt
//--Triggers,

// MV,
// Functions that are additional outputs of GenericUpdate nodes.
// Used for MV Inlining.
// Supported functions: ITM_CURRENTEPOCH, ITM_VSBBROWTYPE, ITM_VSBBROWCOUNT.
class GenericUpdateOutputFunction : public BuiltinFunction
{
public:
  GenericUpdateOutputFunction(OperatorTypeEnum otype,
			 Lng32  argumentCount = 0,
			 ItemExpr *child0 = NULL,
			 ItemExpr *child1 = NULL,
			 ItemExpr *child2 = NULL,
			 ItemExpr *child3 = NULL,
			 ItemExpr *child4 = NULL,
			 ItemExpr *child5 = NULL)
    : BuiltinFunction(otype,CmpCommon::statementHeap(),
                      argumentCount,child0,child1,child2,child3,child4,child5)
     {}

  inline GenericUpdateOutputFunction(OperatorTypeEnum otype,
			 const LIST(ItemExpr *) &children)
			 : BuiltinFunction(otype,
                                           CmpCommon::statementHeap(),
                                           children) {}

  // virtual destructor
  virtual ~GenericUpdateOutputFunction() {}

  // should return always false
  virtual NABoolean isCovered(const ValueIdSet& newExternalInputs,
			      const GroupAttributes& newRelExprAnchorGA,
	   	          ValueIdSet& referencedInputs,
			      ValueIdSet& coveredSubExpr,
			      ValueIdSet& unCoveredExpr) const
  { return FALSE; }

  // a virtual function for type propagating the node
  virtual const NAType * synthesizeType();

  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
				 CollHeap* outHeap = 0);

  // Is this a subclass of GenericUpdateOutput BuildinFunction?
  virtual NABoolean isAGenericUpdateOutputFunction() const
  { return TRUE; }

}; // class GenericUpdateOutputFunction

//++MV
class IsBitwiseAndTrue : public BuiltinFunction
{
public:
  IsBitwiseAndTrue(ItemExpr *val1Ptr, ItemExpr *val2Ptr)
       : BuiltinFunction(ITM_IS_BITWISE_AND_TRUE, CmpCommon::statementHeap(),
                         2, val1Ptr, val2Ptr)
	 { allowsSQLnullArg() = FALSE; }

  // virtual destructor
  virtual ~IsBitwiseAndTrue();

  // a virtual function for type propagating the node
  virtual const NAType * synthesizeType();

  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
				 CollHeap* outHeap = 0);

}; // class GetBitValueAt
//--MV

class CodeVal : public CacheableBuiltinFunction
{
public:
  CodeVal(OperatorTypeEnum op, ItemExpr *val1Ptr)
    : CacheableBuiltinFunction(op, 1, val1Ptr)
    { allowsSQLnullArg() = FALSE; }

  // a virtual function for type propagating the node
  virtual const NAType * synthesizeType();

  // method to do code generation
  virtual short codeGen(Generator*);

  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
				 CollHeap* outHeap = 0);

  ItemExpr* tryToRelaxCharTypeMatchRules(BindWA *bindWA);
  NABoolean isRelaxCharTypeMatchRulesPossible() {return TRUE;};

  // special version of getText() that can handle NO_OPERATOR_TYPE opertor type.
  const NAString getText() const;

  virtual NABoolean hasEquivalentProperties(ItemExpr * other) { return TRUE;}

}; // class CodeVal

/////////////////////////////////////////////////////////////////
// This function is created by generator and is used to
// evaluate MIN and MAX aggr functions. It is created based
// on the original Aggregate node created by the parser.
// The first child points to
// the child of original Aggregate node. The second child points
// to an expression whose result, if TRUE, indicates that the first
// child is the new aggregate value.
// For MIN, the second child is:   "child1 < min-aggr"
// For MAX, the second child is:   "child1 > max-aggr".
// See generateAggrExpr in GenExpGenerator.C for details.
/////////////////////////////////////////////////////////////////
class AggrMinMax : public BuiltinFunction
{
public:
  AggrMinMax(ItemExpr *val1Ptr, ItemExpr *val2Ptr)
    : BuiltinFunction(ITM_AGGR_MIN_MAX, CmpCommon::statementHeap(),
                      2, val1Ptr, val2Ptr) {}

  // a virtual function for type propagating the node
  virtual const NAType * synthesizeType();

  // method to do precode generation
  virtual ItemExpr * preCodeGen(Generator*);

  // method to do code generation
  virtual short codeGen(Generator*);

  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
				 CollHeap* outHeap = 0);

}; // class AggrMinMax

/////////////////////////////////////////////////////////////////
// This function is created by generator and is used to
// evaluate GROUPING function.
/////////////////////////////////////////////////////////////////
class AggrGrouping : public BuiltinFunction
{
public:
  AggrGrouping(Int16 rollupGroupIndex = -1)
       : BuiltinFunction(ITM_AGGR_GROUPING_FUNC, CmpCommon::statementHeap()),
         rollupGroupIndex_(rollupGroupIndex)
  {}

  // a virtual function for type propagating the node
  virtual const NAType * synthesizeType();

  // method to do code generation
  virtual short codeGen(Generator*);

  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
				 CollHeap* outHeap = 0);

private:
  // this field indicates the index into rollupGroupExprList of GroupByAgg
  // that corresponds to the child of GROUPING aggr.
  Int16 rollupGroupIndex_;

}; // class AggrGrouping

class AnsiUSERFunction : public BuiltinFunction
{
public:
  AnsiUSERFunction(OperatorTypeEnum oper)
         : BuiltinFunction(oper) {}

  // virtual destructor
  virtual ~AnsiUSERFunction();

  virtual NABoolean isAUserSuppliedInput() const;

  virtual ItemExpr * bindNode(BindWA *bindWA);
  virtual const NAType * synthesizeType();
  virtual short codeGen(Generator*);

  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
				 CollHeap* outHeap = 0);

}; // class AnsiUSERFunction

// Tandem extension, USER(stringArg),
// as opposed to the Ansi USER keyword (no parens).
class MonadicUSERFunction : public BuiltinFunction
{
public:
  MonadicUSERFunction(ItemExpr *val1Ptr,OperatorTypeEnum otype = ITM_USER)
       : BuiltinFunction(otype, CmpCommon::statementHeap(),
                         1, val1Ptr) {}

  // virtual destructor
  virtual ~MonadicUSERFunction();

  virtual NABoolean isAUserSuppliedInput() const;

  virtual ItemExpr * bindNode(BindWA *bindWA);
  virtual const NAType * synthesizeType();

  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
				 CollHeap* outHeap = 0);

  virtual NABoolean isCovered(const ValueIdSet& newExternalInputs,
			      const GroupAttributes& newRelExprAnchorGA,
	   	              ValueIdSet& referencedInputs,
			      ValueIdSet& coveredSubExpr,
			      ValueIdSet& unCoveredExpr) const;


}; // class MonadicUSERFunction

// Tandem extension, OS_USERID(stringArg),
class MonadicUSERIDFunction : public BuiltinFunction
{
public:
  MonadicUSERIDFunction(ItemExpr *val1Ptr)
       : BuiltinFunction(ITM_USERID, CmpCommon::statementHeap(),
                         1, val1Ptr) {}

  // virtual destructor
  virtual ~MonadicUSERIDFunction();

  virtual const NAType * synthesizeType();

  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
				 CollHeap* outHeap = 0);

}; // class MonadicUSERIDFunction

class Between : public CacheableBuiltinFunction
{
public:

  // boundriesIncluded for values L,R meens [L,R]. not meens (L,R).
  // the direction vector is for the ASC/DESC attributes of the values item
  Between(ItemExpr *colPtr,
	  ItemExpr *val1Ptr,
	  ItemExpr *val2Ptr,
	  NABoolean leftBoundryIncluded = TRUE, //++ MV OZ
	  NABoolean rightBoundryIncluded = TRUE //++ MV OZ
	  )
         : leftBoundryIncluded_(leftBoundryIncluded),
	   rightBoundryIncluded_(rightBoundryIncluded),
	   pDirectionVector_(NULL),
	   CacheableBuiltinFunction(ITM_BETWEEN, 3, colPtr, val1Ptr, val2Ptr)
  {
    allowsSQLnullArg() = FALSE;
  }

  // virtual destructor
  virtual ~Between();

  // a virtual function for performing name binding within the query tree
  virtual ItemExpr * bindNode(BindWA * bindWA);

  // if we are allowing certain incompatible comparisons handle them.
  // currently the following incompatible comparisons are supported:
  // 1. Date and Character literal
  // This returns a pointer to itself if everything goes fine
  // otherwise it returns NULL
  Between * handleIncompatibleComparison(BindWA *bindWA);

  //++ MV OZ
  void setDirectionVector(const IntegerList & directionVector,
			  CollHeap* heap);

  // a virtual function for type propagating the node
  virtual const NAType * synthesizeType();

  NABoolean isRelaxCharTypeMatchRulesPossible() {return TRUE;};

  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
				 CollHeap* outHeap = 0);

  virtual NABoolean isAPredicate() const { return TRUE; }

  // check and apply substr transformation
  ItemExpr* checkAndApplySubstrTransformation();

  // Each operator supports a (virtual) method for transforming its
  // scalar expressions to a canonical form
  virtual void transformNode(NormWA & normWARef,
			     ExprValueId & locationOfPointerToMe,
                             ExprGroupId & introduceSemiJoinHere,
			     const ValueIdSet & externalInputs);

  // A method for inverting (finding the inverse of) the operators
  // in a subtree that is rooted in a NOT.
  virtual ItemExpr * transformSubtreeOfNot(NormWA & normWARef,
                                           OperatorTypeEnum falseOrNot);

  // A virtual method for transforming this predicate
  // if all children (by default; can be any one child) are ItemList.
  // Returns NULL if no transformation was necessary.
  virtual ItemExpr * transformMultiValuePredicate(
				    NABoolean flattenSubqueries = TRUE,
				    ChildCondition condBiRelat = ANY_CHILD);

  ItemExpr * transformIntoTwoComparisons();

  // 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;

  // method to do precode generation
  virtual ItemExpr * preCodeGen(Generator*);

  // for now, do NOT change literals of BETWEEN into constant parameters
  virtual ItemExpr* normalizeForCache(CacheWA& cwa, BindWA& bindWA)
    { return this; } 

  // append an ascii-version of BETWEEN into cachewa.qryText_
  virtual void generateCacheKey(CacheWA& cwa) const;

  virtual NABoolean hasEquivalentProperties(ItemExpr * other);

private:

  NABoolean    leftBoundryIncluded_;
  NABoolean    rightBoundryIncluded_;
  IntegerList *pDirectionVector_;

}; // class Between

class BoolResult : public BuiltinFunction
{
  // Evaluates the final boolean result value for a predicate.
  // A NULL or FALSE final result becomes FALSE.
  // TRUE final result remains TRUE.
public:
  BoolResult(ItemExpr *val1Ptr)
       : BuiltinFunction(ITM_BOOL_RESULT, CmpCommon::statementHeap(),
                         1, val1Ptr)
      {}

  // virtual destructor
  virtual ~BoolResult();

  // a virtual function for type propagating the node
  virtual const NAType * synthesizeType();

  // method to do code generation
  virtual short codeGen(Generator*);

  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
				 CollHeap* outHeap = 0);

}; // class BoolResult

class CharFunc : public BuiltinFunction
{
public:
  CharFunc(CharInfo::CharSet cs, ItemExpr *val1Ptr)
    : BuiltinFunction((cs == CharInfo::UNICODE) ? ITM_UNICODE_CHAR : ITM_CHAR,
                      CmpCommon::statementHeap(),
                      1, val1Ptr),
      charSet_(cs)
    { allowsSQLnullArg() = FALSE; }

  // a virtual function for performing name binding within the query tree
  virtual ItemExpr * bindNode(BindWA *bindWA);

  // a virtual function for type propagating the node
  virtual const NAType * synthesizeType();

  virtual ItemExpr * preCodeGen(Generator*);

  // method to do code generation
  virtual short codeGen(Generator*);

  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
				 CollHeap* outHeap = 0);

private:
  CharInfo::CharSet charSet_;

  virtual NABoolean protectFromVEGs() { return TRUE; };

}; // class CharFunc


class PatternMatchingFunction : public CacheableBuiltinFunction
{
public:
  PatternMatchingFunction(OperatorTypeEnum optype, ItemExpr *matchValue, ItemExpr *pattern)
  : CacheableBuiltinFunction(optype, 2, matchValue, pattern),
   numberOfNonWildcardChars_(-1), patternAStringLiteral_(FALSE),
   bytesInNonWildcardChars_(-1),
   oldDefaultSelForLikeWildCardUsed_(FALSE), beginEndKeysApplied_(FALSE)
  { 
    allowsSQLnullArg() = FALSE;
    setCollation(CharInfo::DefaultCollation);
  }

  PatternMatchingFunction(OperatorTypeEnum optype, ItemExpr *matchValue, ItemExpr *pattern, ItemExpr *escapeChar)
  : CacheableBuiltinFunction(optype, 3, matchValue, pattern, escapeChar),
   numberOfNonWildcardChars_(-1), patternAStringLiteral_(FALSE),
   bytesInNonWildcardChars_(-1),
   oldDefaultSelForLikeWildCardUsed_(FALSE), beginEndKeysApplied_(FALSE)
  { 
    allowsSQLnullArg() = FALSE; 
    setCollation(CharInfo::DefaultCollation);
  }

  PatternMatchingFunction(OperatorTypeEnum optype,ItemExpr *matchValue, ItemExpr *pattern, Int32 numNonWild, Int32 bytesInNonWild,
    NABoolean stringPattern, NABoolean oldDefaultUsed, 
    NABoolean beginEndKeysApplied)
  : CacheableBuiltinFunction(optype, 2, matchValue, pattern),
   numberOfNonWildcardChars_(numNonWild), 
   bytesInNonWildcardChars_(bytesInNonWild),
   patternAStringLiteral_(stringPattern),
   oldDefaultSelForLikeWildCardUsed_(oldDefaultUsed),
   beginEndKeysApplied_(beginEndKeysApplied)
  { 
    allowsSQLnullArg() = FALSE;
    setCollation(CharInfo::DefaultCollation);
  }

  PatternMatchingFunction(OperatorTypeEnum optype,ItemExpr *matchValue, ItemExpr *pattern, ItemExpr *escapeChar,  
    Int32 numNonWild, Int32 bytesInNonWild,NABoolean stringPattern, NABoolean oldDefaultUsed,
    NABoolean beginEndKeysApplied)
  : CacheableBuiltinFunction(optype, 3, matchValue, pattern, escapeChar),
   numberOfNonWildcardChars_(numNonWild), 
   bytesInNonWildcardChars_(bytesInNonWild),
   patternAStringLiteral_(stringPattern),
   oldDefaultSelForLikeWildCardUsed_(oldDefaultUsed),
   beginEndKeysApplied_(beginEndKeysApplied)
  { 
    allowsSQLnullArg() = FALSE; 
    setCollation(CharInfo::DefaultCollation);
  }

  // virtual destructor
  virtual ~PatternMatchingFunction();

  // a virtual function for performing name binding within the query tree
  virtual ItemExpr * bindNode(BindWA *bindWA);

  // change only constant matchValue of a PatternMatchingFunction into ConstantParameter
  virtual ItemExpr* normalizeForCache(CacheWA& cwa, BindWA& bindWA);

  // append an ascii-version of PatternMatchingFunction into cachewa.qryText_
  virtual void generateCacheKey(CacheWA& cwa) const;

  // a virtual function for type propagating the node
  virtual const NAType * synthesizeType();

  NABoolean isRelaxCharTypeMatchRulesPossible() {return TRUE;};

  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
				 CollHeap* outHeap = 0) { return NULL; }

  // predicateEliminatesNullAugmentedRows() determines whether the
  // the predicate is capable of discarding null augmented rows 
  // produced by a left join.

  virtual NABoolean predicateEliminatesNullAugmentedRows(NormWA &, ValueIdSet &);

  virtual NABoolean isAPredicate() const { return TRUE; }

  // The 'LIKE' builtin function doesn't override the virtual function
  // synthSupportedOp, because it doesn't have shape-changing impact on
  // histograms.  But, it does override the virtual function defaultSel,
  // because a LIKE's default selectivity varies based on the pattern
  // being matched.
  virtual double defaultSel();

  NABoolean beginEndKeysApplied(CollHeap *outHeap);
  Int32 getNoOfNonWildcardChars()    { return numberOfNonWildcardChars_ ; };
  Int32 getBytesInNonWildcardChars()    { return bytesInNonWildcardChars_ ; };

  virtual NABoolean protectFromVEGs() { return TRUE; };

  double computeSelForNonWildcardChars();

  NABoolean isPatternAStringLiteral() { return patternAStringLiteral_ ;}
  void setPatternAStringLiteral(NABoolean flag = TRUE) 
      { patternAStringLiteral_ = flag; }

  CharInfo::Collation getCollation()
  {
    return collation_;
  }

  void setCollation(CharInfo::Collation c)
  {
    collation_ = c;
  }
  virtual NABoolean hasEquivalentProperties(ItemExpr * other);

   virtual void unparse(NAString &result,
     PhaseEnum phase = DEFAULT_PHASE,
     UnparseFormatEnum form = USER_FORMAT,
     TableDesc * tabId = NULL) const;


  virtual ItemExpr *applyBeginEndKeys(BindWA *bindWA, ItemExpr *boundExpr, CollHeap *h) { return NULL; }
protected:
  void setNumberOfNonWildcardChars(const LikePatternString &pattern);

  Int32 numberOfNonWildcardChars_;
  Int32 bytesInNonWildcardChars_;

  NABoolean patternAStringLiteral_;

  NABoolean oldDefaultSelForLikeWildCardUsed_;

  NABoolean beginEndKeysApplied_;

  CharInfo::Collation collation_;
  
}; // class PatternMatchingFunction


class Like : public PatternMatchingFunction
{
public:
  Like(ItemExpr *matchValue, ItemExpr *pattern)
  : PatternMatchingFunction(ITM_LIKE, matchValue, pattern)
  { 
    allowsSQLnullArg() = FALSE;
    setCollation(CharInfo::DefaultCollation);
  }

  Like(ItemExpr *matchValue, ItemExpr *pattern, ItemExpr *escapeChar)
  : PatternMatchingFunction(ITM_LIKE, matchValue, pattern, escapeChar)
  { 
    allowsSQLnullArg() = FALSE; 
    setCollation(CharInfo::DefaultCollation);
  }

  Like(ItemExpr *matchValue, ItemExpr *pattern, Int32 numNonWild, Int32 bytesInNonWild,
    NABoolean stringPattern, NABoolean oldDefaultUsed, 
    NABoolean beginEndKeysApplied)
  : PatternMatchingFunction(ITM_LIKE, matchValue, pattern,numNonWild,bytesInNonWild,
     stringPattern,oldDefaultUsed, beginEndKeysApplied)
  { 
    allowsSQLnullArg() = FALSE;
    setCollation(CharInfo::DefaultCollation);
  }

  Like(ItemExpr *matchValue, ItemExpr *pattern, ItemExpr *escapeChar,  
    Int32 numNonWild, Int32 bytesInNonWild,NABoolean stringPattern, NABoolean oldDefaultUsed,
    NABoolean beginEndKeysApplied)
  : PatternMatchingFunction(ITM_LIKE, matchValue, pattern, escapeChar,numNonWild,bytesInNonWild,
     stringPattern,oldDefaultUsed,beginEndKeysApplied) 
  { 
    allowsSQLnullArg() = FALSE; 
    setCollation(CharInfo::DefaultCollation);
  }

  // virtual destructor
  virtual ~Like();
  ItemExpr *applyBeginEndKeys(BindWA *bindWA, ItemExpr *boundExpr, CollHeap *h);
  ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
				 CollHeap* outHeap = 0);
}; // class Like

class Regexp : public PatternMatchingFunction
{
public:
  Regexp(ItemExpr *matchValue, ItemExpr *pattern)
  : PatternMatchingFunction(ITM_REGEXP, matchValue, pattern)
  { 
    allowsSQLnullArg() = FALSE;
    setCollation(CharInfo::DefaultCollation);
  }

  Regexp(ItemExpr *matchValue, ItemExpr *pattern, Int32 numNonWild, Int32 bytesInNonWild,
    NABoolean stringPattern, NABoolean oldDefaultUsed, 
    NABoolean beginEndKeysApplied)
  : PatternMatchingFunction(ITM_REGEXP, matchValue, pattern,numNonWild,bytesInNonWild,
     stringPattern,oldDefaultUsed, beginEndKeysApplied)
  { 
    allowsSQLnullArg() = FALSE;
    setCollation(CharInfo::DefaultCollation);
  }

  // virtual destructor
  virtual ~Regexp();
  ItemExpr *applyBeginEndKeys(BindWA *bindWA, ItemExpr *boundExpr, CollHeap *h);
  ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
				 CollHeap* outHeap = 0);
}; // class Regexp
 
class NoOp : public BuiltinFunction
{
  // Does nothing. An ItemExpr place holder. Used by
  // generator to indicate the end of genrated clauses.
public:
  NoOp(ItemExpr *val1Ptr)
       : BuiltinFunction(ITM_NO_OP, CmpCommon::statementHeap(),
                         1, val1Ptr)
      {};

  // virtual destructor
  virtual ~NoOp();

  // method to do code generation
  virtual short codeGen(Generator*);

  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
				 CollHeap* outHeap = 0);

}; // class NoOp

// this class return the specified boolean value (TRUE, FALSE, or NULL).
class BoolVal : public BuiltinFunction
{
public:
  BoolVal(OperatorTypeEnum bool_type)
         : BuiltinFunction(bool_type) {}
  BoolVal(OperatorTypeEnum bool_type, ItemExpr *val1Ptr)
         : BuiltinFunction(bool_type,  CmpCommon::statementHeap(),
                           1, val1Ptr) {}

  // virtual destructor
  virtual ~BoolVal();

  virtual NABoolean isCovered(const ValueIdSet& newExternalInputs,
			      const GroupAttributes& newRelExprAnchorGA,
	   	              ValueIdSet& referencedInputs,
			      ValueIdSet& coveredSubExpr,
			      ValueIdSet& unCoveredExpr) const;

  // a virtual function for type propagating the node
  virtual const NAType * synthesizeType();

  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
				 CollHeap* outHeap = 0);
  
  virtual NABoolean hasEquivalentProperties(ItemExpr * other) { return TRUE;}
  // MDAM related methods
  // Performs the MDAM tree walk.  See ItemExpr.h for a detailed description.
  DisjunctArray * mdamTreeWalk();

private:

}; // class BoolVal

class In : public CacheableBuiltinFunction
{
public:
  In(ItemExpr *leftPtr, ItemExpr *rightPtr)
         : CacheableBuiltinFunction(ITM_IN, 2, leftPtr, rightPtr) {}

  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
				 CollHeap* outHeap = 0);

  NABoolean isRelaxCharTypeMatchRulesPossible() {return TRUE;};

  virtual NABoolean hasEquivalentProperties(ItemExpr * other) { return TRUE;}

}; // class In


class Concat : public CacheableBuiltinFunction
{
public:
  Concat(ItemExpr *val1Ptr, ItemExpr *val2Ptr)
         : CacheableBuiltinFunction(ITM_CONCAT, 2, val1Ptr, val2Ptr)
	 { allowsSQLnullArg() = FALSE; }

  // virtual destructor
  virtual ~Concat();

  // do not change literals of a cacheable query into constant parameters
  virtual ItemExpr* normalizeForCache(CacheWA& cwa, BindWA& bindWA)
    { return this; }

  // The following method enables expressions such as
  // iso88591_column = :ucs2_hv1 || :ucs2_hv2
  NABoolean isCharTypeMatchRulesRelaxable()
  { return child(0)->isCharTypeMatchRulesRelaxable() &&
           child(1)->isCharTypeMatchRulesRelaxable();
  } ;

  // a virtual function for performing name binding within the query tree
  virtual ItemExpr * bindNode(BindWA *bindWA);

  // a virtual function for type propagating the node
  virtual const NAType * synthesizeType();

  NABoolean isRelaxCharTypeMatchRulesPossible() {return TRUE;};

  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
				 CollHeap* outHeap = 0);

  virtual NABoolean protectFromVEGs() { return TRUE; };

  virtual NABoolean hasEquivalentProperties(ItemExpr * other) { return TRUE;}

}; // class Concat

class ConvertHex : public CacheableBuiltinFunction
{
public:
  ConvertHex(OperatorTypeEnum op, ItemExpr *val1Ptr)
         : CacheableBuiltinFunction(op, 1, val1Ptr)
	 { allowsSQLnullArg() = FALSE; }

  // virtual destructor
  virtual ~ConvertHex();

  // do not change literals of a cacheable query into constant parameters
  virtual ItemExpr* normalizeForCache(CacheWA& cwa, BindWA& bindWA)
    { return this; }

  // a virtual function for type propagating the node
  virtual const NAType * synthesizeType();

  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
				 CollHeap* outHeap = 0);

  // method to do code generation
  virtual short codeGen(Generator*);

  virtual NABoolean protectFromVEGs() { return TRUE; };

  virtual NABoolean hasEquivalentProperties(ItemExpr * other) { return TRUE;}

}; // class ConvertHex

class CharLength : public CacheableBuiltinFunction
{
public:
  CharLength(ItemExpr *val1Ptr)
         : CacheableBuiltinFunction(ITM_CHAR_LENGTH, 1, val1Ptr)
	 { allowsSQLnullArg() = FALSE; }

  // virtual destructor
  virtual ~CharLength();

  // a virtual function for type propagating the node
  virtual const NAType * synthesizeType();

  // a virtual function for performing name binding within the query tree
  virtual ItemExpr * bindNode(BindWA *bindWA);

  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
				 CollHeap* outHeap = 0);

  virtual NABoolean protectFromVEGs() { return TRUE; };

  virtual NABoolean hasEquivalentProperties(ItemExpr * other) { return TRUE;}

}; // class CharLength

class OctetLength : public CacheableBuiltinFunction
{
public:
  OctetLength(ItemExpr *val1Ptr)
         : CacheableBuiltinFunction(ITM_OCTET_LENGTH, 1, val1Ptr)
	 { allowsSQLnullArg() = FALSE; }

  // virtual destructor
  virtual ~OctetLength();

  // a virtual function for type propagating the node
  virtual const NAType * synthesizeType();

  // a virtual function for performing name binding within the query tree
  virtual ItemExpr * bindNode(BindWA *bindWA);

  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
				 CollHeap* outHeap = 0);
  virtual NABoolean protectFromVEGs() { return TRUE; };

  virtual NABoolean hasEquivalentProperties(ItemExpr * other) { return TRUE;}

}; // class OctetLength

class PositionFunc : public CacheableBuiltinFunction
{
public:
  PositionFunc(ItemExpr *val1Ptr, ItemExpr *val2Ptr, ItemExpr *val3Ptr,
               ItemExpr *val4Ptr)
         : CacheableBuiltinFunction(ITM_POSITION, 4, 
                                    val1Ptr, val2Ptr, val3Ptr, val4Ptr)
	 { allowsSQLnullArg() = FALSE; }

  // virtual destructor
  virtual ~PositionFunc();

  // a virtual function for type propagating the node
  virtual const NAType * synthesizeType();

  // a virtual function for performing name binding within the query tree
  virtual ItemExpr * bindNode(BindWA *bindWA);

  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
				 CollHeap* outHeap = 0);
  virtual ItemExpr * preCodeGen(Generator*);


  virtual NABoolean protectFromVEGs() { return TRUE; };

  NABoolean isRelaxCharTypeMatchRulesPossible() {return TRUE;};

  void setCollation(CharInfo::Collation  v) 
  {
    collation_= v;
  }
  
  CharInfo::Collation getCollation() 
  { 
    return collation_;
  }


private:
  CharInfo::Collation collation_;

  virtual NABoolean hasEquivalentProperties(ItemExpr * other) { return TRUE;}

  

}; // class PositionFunc

class Substring : public CacheableBuiltinFunction
{
public:
  Substring(ItemExpr *val1Ptr, ItemExpr *val2Ptr)
         : CacheableBuiltinFunction(ITM_SUBSTR, 2, val1Ptr, val2Ptr)
	 { allowsSQLnullArg() = FALSE; }
  Substring(ItemExpr *val1Ptr, ItemExpr *val2Ptr, ItemExpr *val3Ptr)
         : CacheableBuiltinFunction(ITM_SUBSTR, 3, val1Ptr, val2Ptr, val3Ptr)
	 { allowsSQLnullArg() = FALSE; }

  // virtual destructor
  virtual ~Substring();

  // change literals of a cacheable query into constant parameters
  virtual ItemExpr* normalizeForCache(CacheWA& cwa, BindWA& bindWA);

  // a virtual function for performing name binding within the query tree
  virtual ItemExpr * bindNode(BindWA *bindWA);

  // a virtual function for type propagating the node
  virtual const NAType * synthesizeType();

  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
				 CollHeap* outHeap = 0);

  NABoolean isCharTypeMatchRulesRelaxable()
  { return child(0)->isCharTypeMatchRulesRelaxable(); } ;

  virtual ItemExpr * preCodeGen(Generator*);

  virtual NABoolean protectFromVEGs() { return TRUE; };
  virtual NABoolean calculateMinMaxUecs(ColStatDescList & histograms,
					       CostScalar & minUec,
					       CostScalar & maxUec);

  
  virtual NABoolean hasEquivalentProperties(ItemExpr * other) { return TRUE;}
  

  

}; // class Substring

class ConvertTimestamp : public CacheableBuiltinFunction
{
public:
  ConvertTimestamp(ItemExpr *val1Ptr)
	: CacheableBuiltinFunction(ITM_CONVERTTIMESTAMP, 1, val1Ptr)
	{ allowsSQLnullArg() = FALSE; }

  // virtual destructor
  virtual ~ConvertTimestamp();

  // a virtual function for type propagating the node
  virtual const NAType * synthesizeType();

  // method to do code generation
  virtual ItemExpr * preCodeGen(Generator*);

  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
				 CollHeap* outHeap = 0);
  

  virtual NABoolean hasEquivalentProperties(ItemExpr * other) { return TRUE;}
}; // class ConvertTimestamp

class SleepFunction : public CacheableBuiltinFunction
{
public:

  SleepFunction( ItemExpr *val1Ptr )
   : CacheableBuiltinFunction(ITM_SLEEP, 1, val1Ptr)
  {}
  // virtual destructor
  virtual ~SleepFunction();

  // 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;

  // a virtual function for performing name binding within the query tree
  virtual ItemExpr * bindNode(BindWA *bindWA);

  // a virtual function for type propagating the node
  virtual const NAType * synthesizeType();

  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
				 CollHeap* outHeap = 0);

  virtual NABoolean hasEquivalentProperties(ItemExpr * other) { return TRUE;}

}; // class SleepFunction 

class UnixTimestamp : public CacheableBuiltinFunction
{
public:
  UnixTimestamp()
   : CacheableBuiltinFunction(ITM_UNIX_TIMESTAMP)
  {}

  UnixTimestamp( ItemExpr *val1Ptr )
   : CacheableBuiltinFunction(ITM_UNIX_TIMESTAMP, 1, val1Ptr)
  {}
  // virtual destructor
  virtual ~UnixTimestamp();

  // 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;

  // a virtual function for performing name binding within the query tree
  virtual ItemExpr * bindNode(BindWA *bindWA);

  // a virtual function for type propagating the node
  virtual const NAType * synthesizeType();

  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
				 CollHeap* outHeap = 0);

  virtual NABoolean hasEquivalentProperties(ItemExpr * other) { return TRUE;}

}; // class UnixTimestamp

class CurrentTimestamp : public CacheableBuiltinFunction
{
public:
 CurrentTimestamp(DatetimeType::Subtype dtCode = DatetimeType::SUBTYPE_SQLTimestamp,
                  Lng32 fractPrec = SQLTimestamp::DEFAULT_FRACTION_PRECISION)
   : CacheableBuiltinFunction(ITM_CURRENT_TIMESTAMP),
    dtCode_(dtCode),
    fractPrec_(fractPrec)
  {}

  // virtual destructor
  virtual ~CurrentTimestamp();

  // 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;

  // a virtual function for performing name binding within the query tree
  virtual ItemExpr * bindNode(BindWA *bindWA);

  // a virtual function for type propagating the node
  virtual const NAType * synthesizeType();

  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
				 CollHeap* outHeap = 0);

  virtual NABoolean hasEquivalentProperties(ItemExpr * other) { return TRUE;}

  static ItemExpr * construct
    (CollHeap * heap, 
     DatetimeType::Subtype dtCode = DatetimeType::SUBTYPE_SQLTimestamp,
     Lng32 fractPrec = SQLTimestamp::DEFAULT_FRACTION_PRECISION);

 private:
  DatetimeType::Subtype dtCode_;
  Lng32 fractPrec_;
}; // class CurrentTimestamp

class CurrentTimestampRunning : public CacheableBuiltinFunction
{
public:
  CurrentTimestampRunning()
	: CacheableBuiltinFunction(ITM_CURRENT_TIMESTAMP_RUNNING) {}

  // virtual destructor
  virtual ~CurrentTimestampRunning();

  // a virtual function for performing name binding within the query tree
  virtual ItemExpr * bindNode(BindWA *bindWA);

  // a virtual function for type propagating the node
  virtual const NAType * synthesizeType();

  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
				 CollHeap* outHeap = 0);
  
  

  virtual NABoolean hasEquivalentProperties(ItemExpr * other) { return TRUE;}
}; // class CurrentTimestampRunning

class DateFormat : public CacheableBuiltinFunction
{
public:
  enum FormatType
  {
    FORMAT_GENERIC = 0,
    FORMAT_TO_DATE,
    FORMAT_TO_TIME,
    FORMAT_TO_CHAR
  };

  enum 
  { 
    DATE_FORMAT_NONE = 0,
    DATE_FORMAT_STR,       // formatStr_ contains date format    
    TIME_FORMAT_STR,       // formatStr_ contains time format
    TIMESTAMP_FORMAT_STR   // formatStr_ contains timestamp format
  };

  DateFormat(ItemExpr *val1Ptr, const NAString &formatStr,
             Lng32 formatType, NABoolean wasDateformat = FALSE);

  // virtual destructor
  virtual ~DateFormat();

  // accessor functions
  Int32 getDateFormat() const { return dateFormat_; }

  Int32 getExpDatetimeFormat() const { return frmt_; }

  // do not change format literals of DateFormat into constant parameters
  virtual ItemExpr* normalizeForCache(CacheWA& cwa, BindWA& bindWA)
    { return this; } 

  // append an ascii-version of ItemExpr into cachewa.qryText_
  virtual void generateCacheKey(CacheWA& cwa) const;

  NABoolean errorChecks(Lng32 frmt, BindWA *bindWA, const NAType* opType);

  ItemExpr * quickDateFormatOpt(BindWA * bindWA);

  ItemExpr * bindNode(BindWA * bindWA);

  void setOriginalString(NAString &s) {origString_ = s; }
  const NAString & getOriginalString() const { return origString_; }

  // a virtual function for type propagating the node
  virtual const NAType * synthesizeType();

  // method to do code generation
  virtual short codeGen(Generator*);

  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
				 CollHeap* outHeap = 0);
  
  void unparse(NAString &result,
               PhaseEnum phase,
               UnparseFormatEnum form,
               TableDesc * tabId) const;
    
  virtual NABoolean hasEquivalentProperties(ItemExpr * other);

  virtual QR::ExprElement getQRExprElem() const
  { 
    return QR::QRFunctionWithParameters; 
  }

private:
  // string contains user specified format string
  NAString formatStr_;

  // TO_DATE or TO_CHAR
  Lng32 formatType_;

  // DATE, TIME or TIMESTAMP
  Int32 dateFormat_;

  // original function was DATEFORMAT
  NABoolean wasDateformat_; 

  // actual datetime format (defined in class ExpDatetime in exp_datetime.h)
  Lng32 frmt_;

  //original string
  NAString origString_;
}; // class DateFormat

class DayOfWeek : public CacheableBuiltinFunction
{
public:
  DayOfWeek(ItemExpr *val1Ptr)
	: CacheableBuiltinFunction(ITM_DAYOFWEEK, 1, val1Ptr)
	{ allowsSQLnullArg() = FALSE; }

  // virtual destructor
  virtual ~DayOfWeek();

  // a virtual function for type propagating the node
  virtual const NAType * synthesizeType();

  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
				 CollHeap* outHeap = 0);
  

  virtual NABoolean hasEquivalentProperties(ItemExpr * other) { return TRUE;}

  virtual NABoolean calculateMinMaxUecs(ColStatDescList & histograms,
					       CostScalar & minUec,
					       CostScalar & maxUec);

}; // class DayOfWeek

///////////////////////////////////////////////////////////////////
// This class explodes or fixes up a varchar for insert or updates.
// It does the following:
//   If forInsert is TRUE, then:
//      -- if the source is a NULL value, then the null indicator
//         is set and the length bytes of varchar are set to 0.
//      -- if the source is non-null, then they are moved as packed
//         format and the length bytes contain the actual length.
//
//  If forInsert is FALSE, then:
//     -- if the source is NULL, then null indicator bytes are set
//        to non-zero, the length bytes are set to the max length.
//     -- if source is non-null, then the source is blankpadded to
//        max value and then moved in. Length bytes are set to max.
////////////////////////////////////////////////////////////////////
class ExplodeVarchar : public BuiltinFunction
{
public:
  ExplodeVarchar(ItemExpr *val1Ptr, const NAType * type,
		 NABoolean forInsert = FALSE)
        : BuiltinFunction(ITM_EXPLODE_VARCHAR,  CmpCommon::statementHeap(),
                          1, val1Ptr),
          type_(type), forInsert_(forInsert)
  {}

  // virtual destructor
  virtual ~ExplodeVarchar();

  // a virtual function for type propagating the node
  virtual const NAType * synthesizeType();
  const NAType *getType() const { return type_; }

  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
				 CollHeap* outHeap = 0);

  // method to do code generation
  virtual short codeGen(Generator*);

  virtual NABoolean protectFromVEGs() { return TRUE; };

private:
  const NAType *type_;

  NABoolean forInsert_;
}; // class ExplodeVarchar

class Extract : public CacheableBuiltinFunction
{
public:
  Extract(rec_datetime_field extractField, ItemExpr *val1Ptr,
	  NABoolean fieldFunction)
	: CacheableBuiltinFunction(ITM_EXTRACT, 1, val1Ptr),
	  extractField_(extractField),
	  fieldFunction_(fieldFunction)
	  { allowsSQLnullArg() = FALSE; }

  Extract(OperatorTypeEnum op,
	  rec_datetime_field extractField, ItemExpr *val1Ptr,
	  NABoolean fieldFunction)
       : CacheableBuiltinFunction(op, 1, val1Ptr),
	 extractField_(extractField),
	 fieldFunction_(fieldFunction)
         { allowsSQLnullArg() = FALSE; }

  // virtual destructor
  virtual ~Extract();

  // accessor functions
  rec_datetime_field getExtractField() const	{ return extractField_; }

  NABoolean getFieldFunction() const { return fieldFunction_; }

  // append an ascii-version of ItemExpr into cachewa.qryText_
  virtual void generateCacheKey(CacheWA& cwa) const;

  // a virtual function for type propagating the node
  virtual const NAType * synthesizeType();

  // method to do code generation
  virtual ItemExpr * preCodeGen(Generator*);
  virtual short codeGen(Generator*);

  // returns TRUE for Extract(cast(CurrentTimeStamp))) otherwise FALSE.
  virtual NABoolean isAUserSuppliedInput() 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. In this case expressions of the type
  // extract(cast(current_timestamp))  will be treated like a leaf.
  // --------------------------------------------------------------------
  virtual void getLeafValuesForCoverTest(ValueIdSet & leafValues, 
                                         const GroupAttributes& coveringGA,
                                         const ValueIdSet & newExternalInputs) const;

  virtual NABoolean duplicateMatch(const ItemExpr & other) const;
  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
				 CollHeap* outHeap = 0);

  virtual NABoolean hasEquivalentProperties(ItemExpr * other);

  virtual NABoolean calculateMinMaxUecs(ColStatDescList & histograms,
					       CostScalar & minUec,
					       CostScalar & maxUec);

  virtual QR::ExprElement getQRExprElem() const;
  

private:

  rec_datetime_field extractField_;

  // set to TRUE if the original function specified was a datetime
  // field function that was translated to an EXTRACT function.
  // Ex.  DAY(<value>)  gets translated to EXTRACT(DAY from <value>).
  // Used for correct error reporting.
  NABoolean fieldFunction_;
}; // class Extract

class ExtractOdbc : public Extract
{
public:
  ExtractOdbc(rec_datetime_field extractField, ItemExpr *val1Ptr,
	      NABoolean fieldFunction)
       : Extract(ITM_EXTRACT_ODBC, extractField, val1Ptr, fieldFunction)
  { allowsSQLnullArg() = FALSE; }

  // a virtual function for performing name binding within the query tree
  virtual ItemExpr * bindNode(BindWA *bindWA);

  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
				 CollHeap* outHeap = 0);
}; // class ExtractOdbc

class JulianTimestamp : public CacheableBuiltinFunction
{
public:
  JulianTimestamp(ItemExpr *val1Ptr)
	: CacheableBuiltinFunction(ITM_JULIANTIMESTAMP, 1, val1Ptr)
	{ allowsSQLnullArg() = FALSE; }

  // virtual destructor
  virtual ~JulianTimestamp();

  // 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.
  // Fix for cr 10-010718-3967
  // don't need this method since this method is hardcoded to return TRUE
  // and JulianTimestamp is not a user supplied input, therefore we should
  // just be fine calling ItemExpr::isAUserSuppliedInput which always returns
  // FALSE
  // virtual NABoolean isAUserSuppliedInput() const;

  // a virtual function for type propagating the node
  virtual const NAType * synthesizeType();

  // method to do code generation
  virtual ItemExpr * preCodeGen(Generator*);

  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
				 CollHeap* outHeap = 0);
  
  
  virtual NABoolean hasEquivalentProperties(ItemExpr * other) { return TRUE;}
  
}; // class JulianTimestamp

// supplied by the root node, a count of statement executions
class StatementExecutionCount : public BuiltinFunction
{
public:
  StatementExecutionCount() : BuiltinFunction(ITM_EXEC_COUNT) {}

  virtual NABoolean isAUserSuppliedInput() const;
  virtual const NAType * synthesizeType();
  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
				 CollHeap* outHeap = 0);
};

// supplied by the root node, the current transaction id, if any
class CurrentTransId : public BuiltinFunction
{
public:
  CurrentTransId() : BuiltinFunction(ITM_CURR_TRANSID) {}

  virtual NABoolean isAUserSuppliedInput() const;
  virtual const NAType * synthesizeType();
  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
				 CollHeap* outHeap = 0);
};

class Upper : public CacheableBuiltinFunction
{
public:
  Upper(ItemExpr *val1Ptr)
         : CacheableBuiltinFunction(ITM_UPPER, 1, val1Ptr)
	 { allowsSQLnullArg() = FALSE; }

  // virtual destructor
  virtual ~Upper();

  // a virtual function for performing name binding within the query tree
  virtual ItemExpr * bindNode(BindWA *bindWA);

  // do not change literals of a cacheable query into constant parameters
  virtual ItemExpr* normalizeForCache(CacheWA& cwa, BindWA& bindWA)
    { return this; }

  NABoolean isCharTypeMatchRulesRelaxable()
  { return child(0)->isCharTypeMatchRulesRelaxable(); } ;

  // a virtual function for type propagating the node
  virtual const NAType * synthesizeType();

  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
				 CollHeap* outHeap = 0);

  virtual NABoolean protectFromVEGs() { return TRUE; };

  virtual NABoolean hasEquivalentProperties(ItemExpr * other) { return TRUE;}

}; // class Upper

class Lower : public CacheableBuiltinFunction
{
public:
  Lower(ItemExpr *val1Ptr)
         : CacheableBuiltinFunction(ITM_LOWER, 1, val1Ptr)
	 { allowsSQLnullArg() = FALSE; }

  // virtual destructor
  virtual ~Lower();

  // do not change literals of a cacheable query into constant parameters
  virtual ItemExpr* normalizeForCache(CacheWA& cwa, BindWA& bindWA)
    { return this; }

  NABoolean isCharTypeMatchRulesRelaxable()
  { return child(0)->isCharTypeMatchRulesRelaxable(); } ;

  // a virtual function for type propagating the node
  virtual const NAType * synthesizeType();

  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
				 CollHeap* outHeap = 0);

  virtual NABoolean protectFromVEGs() { return TRUE; };

  virtual NABoolean hasEquivalentProperties(ItemExpr * other) { return TRUE;}

}; // class Lower

class Trim : public CacheableBuiltinFunction
{
public:
  enum    { TRAILING, LEADING, BOTH};

  Trim(Int32  mode, ItemExpr *val1Ptr, ItemExpr *val2Ptr)
         : CacheableBuiltinFunction(ITM_TRIM, 2, val1Ptr, val2Ptr),
           mode_(mode)
	   { allowsSQLnullArg() = FALSE; }

  // virtual destructor
  virtual ~Trim();

  // for now, do NOT change literals of Trim into constant parameters
  virtual ItemExpr* normalizeForCache(CacheWA& cwa, BindWA& bindWA)
    { return this; } 

  // append an ascii-version of ItemExpr into cachewa.qryText_
  virtual void generateCacheKey(CacheWA& cwa) const;

  inline Int32 getTrimMode() const { return mode_; }

  // a virtual function for performing name binding within the query tree
  virtual ItemExpr * bindNode(BindWA *bindWA);

  // method to do code generation
  virtual short codeGen(Generator*);

  virtual ItemExpr * preCodeGen(Generator*);

  // a virtual function for type propagating the node
  virtual const NAType * synthesizeType();

  NABoolean isRelaxCharTypeMatchRulesPossible() {return TRUE;};

  // The following method enables expressions such as
  // iso88591_column = trim(BOTH :ucs2_hv1 FROM :ucs2_hv2)
  NABoolean isCharTypeMatchRulesRelaxable()
  { return child(0)->isCharTypeMatchRulesRelaxable() &&
           child(1)->isCharTypeMatchRulesRelaxable();
  } ;

  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
				 CollHeap* outHeap = 0);
  virtual NABoolean protectFromVEGs() { return TRUE; };

  void setCollation(CharInfo::Collation  v) 
  {
    collation_= v;
  }
  
  CharInfo::Collation getCollation() 
  { 
    return collation_;
  }
  virtual NABoolean hasEquivalentProperties(ItemExpr * other);

  virtual QR::ExprElement getQRExprElem() const
  { 
    return QR::QRFunctionWithParameters; 
  }

private:
  Int32    mode_;  // holds a value from one of the enum members shown above.
  CharInfo::Collation collation_;

}; // class Trim

class Translate: public CacheableBuiltinFunction
{
public:
  enum {/*UCS2*/UNICODE_TO_SJIS, /*UCS2*/UNICODE_TO_ISO88591,
        ISO88591_TO_UNICODE/*UCS2*/, SJIS_TO_UNICODE/*UCS2*/,
        UCS2_TO_SJIS, SJIS_TO_UCS2,
        UCS2_TO_UTF8, UTF8_TO_UCS2,
        UTF8_TO_SJIS, SJIS_TO_UTF8, UTF8_TO_ISO88591,
        ISO88591_TO_UTF8,
        KANJI_MP_TO_ISO88591, KSC5601_MP_TO_ISO88591,
        GBK_TO_UTF8,
        UNKNOWN_TRANSLATION};

  Translate(ItemExpr *valPtr, NAString* map_table_name);
  Translate(ItemExpr *valPtr, Int32 map_table_id);

  // virtual destructor
  virtual ~Translate() {};

  // for now, do NOT change literals of Translate into constant parameters
  virtual ItemExpr* normalizeForCache(CacheWA& cwa, BindWA& bindWA)
    { return this; } 

  // append an ascii-version of ItemExpr into cachewa.qryText_
  virtual void generateCacheKey(CacheWA& cwa) const;

  inline Int32 getTranslateMapTableId() const { return map_table_id_; }

  // a virtual function for type propagating the node
  virtual const NAType * synthesizeType();

  NABoolean isRelaxCharTypeMatchRulesPossible() {return TRUE;}
  ItemExpr* tryToRelaxCharTypeMatchRules(BindWA *bindWA);

  NABoolean  isCharTypeMatchRulesRelaxable();

  virtual short codeGen(Generator*);

  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
                                 CollHeap* outHeap = 0);

  virtual NABoolean protectFromVEGs() { return TRUE; };

  virtual QR::ExprElement getQRExprElem() const
   { return QR::QRFunctionWithParameters; }

  virtual void unparse(NAString &result,
		       PhaseEnum phase = DEFAULT_PHASE,
		       UnparseFormatEnum form = USER_FORMAT,
		       TableDesc * tabId = NULL) const;
private:
  Int32 map_table_id_;  // holds a value from one of the enum members shown above.

}; // class Translate

Int32 find_translate_type( CharInfo::CharSet src_cs,   // Source charset
                           CharInfo::CharSet dest_cs ); // Destination charset


// The CASE statement has an operand which is not one of its children,
// which introduces a few special cases in Binder and in Codegen type-synth...
class Case : public CacheableBuiltinFunction
{
public:
  Case(ItemExpr *val1Ptr, ItemExpr *val2Ptr)
  : CacheableBuiltinFunction(ITM_CASE, 1, val2Ptr),
    caseOperand_(val1Ptr),
    caseOperandWasNullable_(FALSE)
    {}

  // virtual destructor
  virtual ~Case();

  // accessor functions
  ItemExpr *removeCaseOperand()
  {
    ItemExpr *caseOperand = caseOperand_;
    caseOperand_ = NULL;
    return caseOperand;
  }

  ItemExpr *getCaseOperand()		     { return caseOperand_; }

  void setCaseOperand(ItemExpr *newOperand)  { caseOperand_ = newOperand; }

  NABoolean &caseOperandWasNullable()	     { return caseOperandWasNullable_; }

  // a virtual function for performing name binding within the query tree
  virtual ItemExpr * bindNode(BindWA *bindWA);

  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
				 CollHeap* outHeap = 0);

  // A transformation method for protecting sequence functions from not
  // being evaluated due to short-circuit evaluation.
  //
  virtual void protectiveSequenceFunctionTransformation(Generator *generator);

  // method to do code generation
  virtual short codeGen(Generator*);

  // we want Case to be cacheable
  virtual NABoolean isCacheableExpr(CacheWA& cwa);

  // change literals of a cacheable query into input parameters
  virtual ItemExpr* normalizeForCache(CacheWA& cachewa, BindWA& bindWA);

  // append an ascii-version of ItemExpr into cachewa.qryText_
  virtual void generateCacheKey(CacheWA& cachewa) const;

  virtual NABoolean isCovered(const ValueIdSet& newExternalInputs,
			      const GroupAttributes& newRelExprAnchorGA,
	   	              ValueIdSet& referencedInputs,
			      ValueIdSet& coveredSubExpr,
			      ValueIdSet& unCoveredExpr) const;

  // This method recursively removes from coveredSubExpr,
  // all IfThenElse nodes that are part of 'expr' and for those IfThenElse
  // nodes, adds its children to coveredSubExpr.
  // input: expr, a non-null IfThenElse node.
  void fixIfThenElse(ItemExpr * expr, ValueIdSet& coveredSubExpr, NABoolean ifThenElseExists = FALSE) const;

  virtual void unparse(NAString &result,
		       PhaseEnum phase = DEFAULT_PHASE,
		       UnparseFormatEnum form = USER_FORMAT,
		       TableDesc * tabId = NULL) const;

  virtual void getLeafValuesForCoverTest(ValueIdSet & leafValues, 
                                         const GroupAttributes& coveringGA,
                                         const ValueIdSet & newExternalInputs) const;

  virtual NABoolean hasEquivalentProperties(ItemExpr * other);

  virtual NABoolean calculateMinMaxUecs(ColStatDescList & histograms,
					       CostScalar & minUec,
					       CostScalar & maxUec);
private:
  ItemExpr *caseOperand_;
  NABoolean caseOperandWasNullable_;
}; // class Case

class IfThenElse : public CacheableBuiltinFunction
{
public:
  IfThenElse(ItemExpr *val1Ptr, ItemExpr *val2Ptr, ItemExpr *val3Ptr)
  : CacheableBuiltinFunction(ITM_IF_THEN_ELSE, 3, val1Ptr, val2Ptr, val3Ptr) {}

  // virtual destructor
  virtual ~IfThenElse();

  // for now, do NOT change literals of IfThenElse into constant parameters
  virtual ItemExpr* normalizeForCache(CacheWA& cwa, BindWA& bindWA)
    { return this; } 

  // set else clause
  void setElse(ItemExpr *elseClause) { child(2) = elseClause; }

  // a virtual function for type propagating the node
  virtual const NAType * synthesizeType();

  NABoolean isRelaxCharTypeMatchRulesPossible() {return TRUE;};

  NABoolean isCharTypeMatchRulesRelaxable();

  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
				 CollHeap* outHeap = 0);

  short codeGen(Generator*);

  virtual void unparse(NAString &result,
		       PhaseEnum phase = DEFAULT_PHASE,
		       UnparseFormatEnum form = USER_FORMAT,
		       TableDesc * tabId = NULL) const;

  virtual NABoolean calculateMinMaxUecs(ColStatDescList & histograms,
					       CostScalar & minUec,
					       CostScalar & maxUec);

  virtual NABoolean hasEquivalentProperties(ItemExpr * other) { return TRUE;}
}; // class IfThenElse


// The RaiseError class is introduced to raise an error
// given the errorCode and the message. This expression
// will create an error in the Diagnostics area and
// return EXPR_ERROR. Currently this ItemExpr is used
// to raise errors for constraint failures.
//
class RaiseError : public BuiltinFunction
{
public:
  // -- Triggers
  // This Ctor is used for SIGNAL statements with a string expression.
  RaiseError (Lng32 sqlcode,
	      NAString SqlState,
		  ItemExpr *messageExpr,
          CollHeap * h=0)
    : BuiltinFunction(ITM_RAISE_ERROR,  CmpCommon::statementHeap(),
                      1, messageExpr),
      theSQLCODE_(sqlcode),
      constraintName_(SqlState, h),
      tableName_("", h)
    {};

  RaiseError (Lng32 sqlcode = 0,
	      const NAString & constraintName = "",
	      const NAString & tableName = "",
              CollHeap * h=0)
    : BuiltinFunction(ITM_RAISE_ERROR),
      theSQLCODE_(sqlcode),
      constraintName_(constraintName, h),
      tableName_(tableName, h)
    {};

  // copy ctor
  RaiseError (const RaiseError &, CollHeap * h=0) ; // not written

  virtual ~RaiseError();

  const NAType *synthesizeType();
  short codeGen (Generator*);
  ItemExpr *copyTopNode (ItemExpr *derivedNode = NULL, CollHeap *outHeap =NULL);
  virtual const NAString getText() const;

  const NAString &getConstraintName() const	{ return constraintName_; }
  const NAString &getTableName() const		{ return tableName_; }
  Int32 getSQLCODE() const			{ return theSQLCODE_; }
  void setSQLCODE(Lng32 sqlcode) 		{ theSQLCODE_ = sqlcode; }

private:
  Lng32     theSQLCODE_;
  NAString constraintName_;
  NAString tableName_;

}; // class RaiseError


class Cast : public CacheableBuiltinFunction
{
public:
  Cast(ItemExpr *val1Ptr, const NAType *type,
       OperatorTypeEnum otype = ITM_CAST, NABoolean checkForTrunc = FALSE,
       NABoolean noStringTruncationWarnings = FALSE);

  Cast(ItemExpr *val1Ptr, ItemExpr *errorOutPtr, const NAType *type,
       OperatorTypeEnum otype /* today, should be ITM_NARROW always */,
       NABoolean checkForTrunc = FALSE,
       NABoolean reverseDataErrorConversionFlag = FALSE,
       NABoolean noStringTruncationWarnings = FALSE);

  // virtual destructor
  virtual ~Cast();

  // accessor functions
  ItemExpr * getExpr() const { return child(0).getPtr(); }

  const NAType *getType() const { return type_; }
  void changeType(NAType * newType) { type_ = newType; }

  virtual NABoolean isEquivalentForCodeGeneration(const ItemExpr * other);

  virtual ConstValue *castToConstValue(NABoolean & negate);

  // a virtual function for performing name binding within the query tree
  virtual ItemExpr * bindNode(BindWA *bindWA);

  // append an ascii-version of ItemExpr into cachewa.qryText_
  virtual void generateCacheKey(CacheWA& cwa) const;

  // a virtual function for type propagating the node
  virtual const NAType * synthesizeType();

  // determine whether the output of the cast can be type relaxed
  NABoolean isCharTypeMatchRulesRelaxable()
  { return child(0)->isCharTypeMatchRulesRelaxable(); } ;

  // convert a cast on top of a constant into a new constant with
  // the correct type
  virtual ItemExpr *foldConstants(ComDiagsArea *diagsArea,
				  NABoolean newTypeSynthesis = FALSE);

  virtual NABoolean isCovered(const ValueIdSet& newExternalInputs,
			      const GroupAttributes& newRelExprAnchorGA,
	   	              ValueIdSet& referencedInputs,
			      ValueIdSet& coveredSubExpr,
			      ValueIdSet& unCoveredExpr) const;

  // is any literal in this expr safely coercible to its target type?
  virtual NABoolean isSafelyCoercible(CacheWA& cwa) const;

  // MVs --
  virtual void getLeafValuesForCoverTest(ValueIdSet & leafValues, 
                                         const GroupAttributes& coveringGA,
                                         const ValueIdSet & newExternalInputs) const;

  // Is this a subclass of GenericUpdateOutputFunction BuildinFunction?
  virtual NABoolean isAGenericUpdateOutputFunction() const
    { return child(0)->isAGenericUpdateOutputFunction(); }

  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
				 CollHeap* outHeap = 0);

  // method to do code generation
  virtual ItemExpr * preCodeGen(Generator*);
  virtual short codeGen(Generator*);

  NABoolean checkTruncationError()	{ return checkForTruncation_; }
  void setCheckTruncationError(NABoolean v) { checkForTruncation_ = v; }

  // get and set for flags_. See enum Flags.
  NABoolean matchChildType()   { return (flags_ & MATCH_CHILD_TYPE) != 0; }
  void setMatchChildType(NABoolean v)
  { (v ? flags_ |= MATCH_CHILD_TYPE : flags_ &= ~MATCH_CHILD_TYPE); }

  NABoolean treatAllSpacesAsZero()
  { return ((flags_ & TREAT_ALL_SPACES_AS_ZERO) != 0); };
  
  void setTreatAllSpacesAsZero(NABoolean v)
  { (v) ? flags_ |= TREAT_ALL_SPACES_AS_ZERO : flags_ &= ~TREAT_ALL_SPACES_AS_ZERO; }

  NABoolean tgtCharSetSpecified()   { return (flags_ & TGT_CHAR_SET_SPECIFIED) != 0; }
  void setTgtCSSpecified(NABoolean v)
       { (v ? flags_ |= TGT_CHAR_SET_SPECIFIED : flags_ &= ~TGT_CHAR_SET_SPECIFIED); }

  NABoolean srcIsVarcharPtr()   { return (flags_ & SRC_IS_VARCHAR_PTR) != 0; }
  void setSrcIsVarcharPtr(NABoolean v)
       { (v ? flags_ |= SRC_IS_VARCHAR_PTR : flags_ &= ~SRC_IS_VARCHAR_PTR); }

  NABoolean allowSignInInterval()
    { return ((flags_ & ALLOW_SIGN_IN_INTERVAL) != 0); };

  void setAllowSignInInterval(NABoolean v)
    { (v) ? flags_ |= ALLOW_SIGN_IN_INTERVAL : flags_ &= ~ALLOW_SIGN_IN_INTERVAL; }

  NABoolean convertNullWhenError() 
  { return (flags_ & CONV_NULL_WHEN_ERROR) != 0; }
  void setConvertNullWhenError(NABoolean v)
  { (v ? flags_ |= CONV_NULL_WHEN_ERROR : flags_ &= ~CONV_NULL_WHEN_ERROR); }

  NABoolean noStringTruncationWarnings() 
  { return (flags_ & NO_STRING_TRUNC_WARNINGS) != 0; }
  void setNoStringTruncationWarnings(NABoolean v)
  { (v ? flags_ |= NO_STRING_TRUNC_WARNINGS: flags_ &= ~NO_STRING_TRUNC_WARNINGS); }

  const NAType * pushDownType(NAType& desiredType,
                      enum NABuiltInTypeEnum defaultQualifier);

  virtual NABoolean hasEquivalentProperties(ItemExpr * other);

  UInt16 getFlags() { return flags_; }
  void setFlags(UInt16 f) { flags_ = f; }

private:

  enum Flags
  {
    // if set, then do not generate code if child's type attributes match
    // my type attributes.
    MATCH_CHILD_TYPE = 0x0001,

    // when converting string to numeric, if input string contains only
    // spaces or is a null string(length of zero), then the result becomes
    // zero(numeric value of 0).
    TREAT_ALL_SPACES_AS_ZERO  = 0x0002,

    // Did user specify the target character set?  0=No, 1=Yes
    TGT_CHAR_SET_SPECIFIED = 0x0004,

    // source is a varchar value which is a pointer to the actual data.
    SRC_IS_VARCHAR_PTR = 0x0008,

    ALLOW_SIGN_IN_INTERVAL             = 0x0010,

    // convert error will not be returned, null will be moved into target
    CONV_NULL_WHEN_ERROR               = 0x0020,

    // string truncation warnings are not to be returned
    NO_STRING_TRUNC_WARNINGS           = 0x0040
  
  };

  const NAType *type_;

  // Does the ex_conv_clause generated by this cast node need to
  // check for truncation error?
  NABoolean checkForTruncation_;

  // If true, the run-time data error conversion flag must be reversed.
  // This is a Narrow-only issue.
  NABoolean reverseDataErrorConversionFlag_;

  UInt32 flags_;

}; // class Cast

class CastConvert : public Cast
{
public:
  CastConvert(ItemExpr *val1Ptr, const NAType *type)
    : Cast(val1Ptr, type, ITM_CAST_CONVERT)
  {}

  // copyTopNode method
  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
				 CollHeap* outHeap = 0);

  // a virtual function for type propagating the node
  virtual const NAType * synthesizeType();

  virtual NABoolean hasEquivalentProperties(ItemExpr * other) { return TRUE;}

}; // CastConvert

class CastType : public Cast
{
public:
  CastType(ItemExpr *val1Ptr, const NAType *type)
       : Cast(val1Ptr, type, ITM_CAST_TYPE),
         makeNullable_(FALSE)
  {}

  CastType(ItemExpr *val1Ptr, NABoolean makeNullable)
       : Cast(val1Ptr, NULL, ITM_CAST_TYPE),
         makeNullable_(makeNullable)
  {}

  // copyTopNode method
  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
				 CollHeap* outHeap = 0);

  // a virtual function for type propagating the node
  virtual const NAType * synthesizeType();

  virtual short codeGen(Generator*);

private:
  // if set, then cast child to nullable type
  NABoolean makeNullable_;
}; // CastType

class Narrow : public Cast
{
public:
  // Begin_Fix 10-040114-2431
  // 02/18/2004
  // Add initialization for matchChildNullability_
  Narrow(ItemExpr * val1Ptr, ItemExpr * errorOutPtr, const NAType * type,
       OperatorTypeEnum otype = ITM_NARROW,
       NABoolean reverseDataErrorConversionFlag = FALSE,
       NABoolean matchChildNullability = FALSE)
         : Cast(val1Ptr, errorOutPtr, type, otype, FALSE,
                reverseDataErrorConversionFlag),
           matchChildNullability_(matchChildNullability){}
  // End_Fix 10-040114-2431

  // virtual destructor
  virtual ~Narrow();

  // copyTopNode method
  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
				 CollHeap* outHeap = 0);

  // a virtual function for type propagating the node
  virtual const NAType *synthesizeType();

  // method to do code generation
  // virtual ItemExpr * preCodeGen(Generator*); -- we use Cast::preCodeGen
  virtual short codeGen(Generator*);

  virtual NABoolean hasEquivalentProperties(ItemExpr * other);

private:

  // Begin_Fix 10-040114-2431
  // 02/18/2004
  //Force by nullability to be the same as my child's nullability
  NABoolean matchChildNullability_;
  // End_Fix 10-040114-2431
}; // class Narrow

class InstantiateNull : public Cast
{
public:
  InstantiateNull(ItemExpr * valuePtr, const NAType * typePtr)
               : Cast(valuePtr, typePtr, ITM_INSTANTIATE_NULL),
                 beginLOJTransform_(FALSE),
                 NoCheckforLeftToInnerJoin(FALSE){}

  virtual ~InstantiateNull();

  // Each operator supports a (virtual) method for transforming its
  // scalar expressions to a canonical form
  virtual void transformNode(NormWA & normWARef,
			     ExprValueId & locationOfPointerToMe,
                             ExprGroupId & introduceSemiJoinHere,
			     const ValueIdSet & externalInputs);

  // 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.
  virtual ItemExpr * normalizeNode(NormWA & normWARef);

  virtual ItemExpr * getReplacementExpr() const;

  //10-060105-3714-Begin
  virtual ItemExpr * getReplacementExpr(NABoolean forceNavigate) const; 
  //10-060105-3714-End
  // --------------------------------------------------------------------
  // 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;

  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
				 CollHeap* outHeap = 0);

  NABoolean NoCheckforLeftToInnerJoin;
  NABoolean lojTransformInProgress() {return beginLOJTransform_;}
  void setLOJTransformComplete() {beginLOJTransform_ = FALSE;}
  virtual NABoolean isAColumnReference( );

  virtual NABoolean hasEquivalentProperties(ItemExpr * other);
  virtual NABoolean isEquivalentForCodeGeneration(const ItemExpr * other);

private:
  NABoolean beginLOJTransform_;
}; // class InstantiateNull

// used to format source values to ascii representation.
//
// And source ascii values to specified target datatype.
// This is only suppported to convert to DATE datatype and if
// 'formatCharToDate' parameter is set to TRUE. 
class Format : public BuiltinFunction
{
  NAString formatStr_;
public:
  enum FormatType
  {
    FORMAT_GENERIC = 0,
    FORMAT_TO_DATE,
    FORMAT_TO_CHAR
  };

  Format(ItemExpr *val1Ptr, const NAString &formatStr, 
	 NABoolean formatCharToDate, Lng32 formatType = FORMAT_GENERIC)
       : BuiltinFunction(ITM_FORMAT,  CmpCommon::statementHeap(),
                         1, val1Ptr),
	 formatStr_(formatStr),
	 formatType_(formatType),
	 formatCharToDate_(formatCharToDate)
  {
    formatStr_.strip(NAString::leading);
    formatStr_.strip(NAString::trailing);
    formatStr_.toUpper();
  }
  
  // virtual destructor
  virtual ~Format();

  // method to do precode generation
  virtual ItemExpr * bindNode(BindWA *bindWA);

  // method to do precode generation
  virtual ItemExpr * preCodeGen(Generator*);

  // a virtual function for type propagating the node
  virtual const NAType * synthesizeType();

  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
				 CollHeap* outHeap = 0);

  ItemExpr * quickDateFormatOpt(BindWA * bindWA);

  const NAString& getFormatStr() const
  {
    return formatStr_;
  }

  Lng32 getFormatType() const
  {
    return formatType_;
  }

  NABoolean getFormatCharToDate() const
  {
    return formatCharToDate_;
  }

  virtual QR::ExprElement getQRExprElem() const
  { 
    return QR::QRFunctionWithParameters; 
  }

private:
  Lng32 formatType_;
  NABoolean formatCharToDate_;
}; // class Format


class LOBoper : public BuiltinFunction
{
public:

 enum ObjectType
 {
   STRING_, FILE_, BUFFER_, CHUNK_, STREAM_, LOB_, LOAD_, EXTERNAL_, 
   EXTRACT_, EMPTY_LOB_,NOOP_
 };

 LOBoper(OperatorTypeEnum otype,
	 ItemExpr *val1Ptr=NULL, ItemExpr *val2Ptr = NULL,ItemExpr *val3Ptr = NULL, 
	 ObjectType obj = NOOP_)
   : BuiltinFunction(otype,  CmpCommon::statementHeap(),
                     3, val1Ptr, val2Ptr,val3Ptr),
   obj_(obj),
   lobNum_(-1),
   lobStorageType_(Lob_Invalid_Storage),
     lobMaxSize_((Int64)CmpCommon::getDefaultNumeric(LOB_MAX_SIZE)*1024*1024),
     lobMaxChunkMemSize_((Int64)CmpCommon::getDefaultNumeric(LOB_MAX_CHUNK_MEM_SIZE)*1024*1024),
     lobGCLimit_((Int64) CmpCommon::getDefaultNumeric(LOB_GC_LIMIT_SIZE)*1024*1024),
     hdfsPort_((Lng32)CmpCommon::getDefaultNumeric(LOB_HDFS_PORT)),
     hdfsServer_( CmpCommon::getDefaultString(LOB_HDFS_SERVER))
   {
     if ((obj == STRING_) || (obj == BUFFER_) || (obj == FILE_) || (obj ==LOB_) )
       lobStorageType_ = Lob_HDFS_File;
     else if (obj == EXTERNAL_)
       lobStorageType_ = Lob_External_HDFS_File;
     else if (obj == EMPTY_LOB_)
       lobStorageType_ = Lob_Empty;
     else
       lobStorageType_ = Lob_Invalid_Storage;
    
   }

 // copyTopNode method
  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
				 CollHeap* outHeap = 0);

  // a virtual function for type propagating the node
  virtual const NAType * synthesizeType();

  virtual NABoolean hasEquivalentProperties(ItemExpr * other) { return TRUE;}

  virtual NABoolean isCovered
    (const ValueIdSet& newExternalInputs,
     const GroupAttributes& coveringGA,
     ValueIdSet& referencedInputs,
     ValueIdSet& coveredSubExpr,
     ValueIdSet& unCoveredExpr) const;
  
  // method to do precode generation
  virtual ItemExpr * preCodeGen(Generator*);

  ObjectType getObj() { return obj_; }

  short &lobNum() {return lobNum_; }
  LobsStorage &lobStorageType() { return lobStorageType_; }
  NAString &lobStorageLocation() { return lobStorageLocation_; }
  Int64 getLobMaxSize() {return lobMaxSize_; }
  Int64 getLobMaxChunkMemSize() { return lobMaxChunkMemSize_;}
  Int64 getLobGCLimit() 
  { 
    if (lobGCLimit_>0) 
      return (Int64)lobGCLimit_;
    else
      return -1;
  }
  Int32 getLobHdfsPort() { return hdfsPort_;}
  NAString &getLobHdfsServer(){return hdfsServer_;}
 protected:
  ObjectType obj_;

  short lobNum_;
  LobsStorage lobStorageType_;
  NAString lobStorageLocation_;
  Int64 lobMaxSize_; // In byte units
  Int64 lobMaxChunkMemSize_; //In MB Units
  Int64 lobGCLimit_ ;//In MB Units
  Int32 hdfsPort_;
  NAString hdfsServer_;
  
}; // LOBoper

class LOBinsert : public LOBoper
{
 public:
  
 LOBinsert(ItemExpr *val1Ptr, 
	   ItemExpr *val2Ptr,
	   ObjectType fromObj, 
	   NABoolean isAppend = FALSE,
           NABoolean treatLobAsVarchar =FALSE,
	   OperatorTypeEnum otype = ITM_LOBINSERT)
   : LOBoper(otype, val1Ptr, val2Ptr,NULL,fromObj),
    objectUID_(-1),
    append_(isAppend),
    lobAsVarchar_(treatLobAsVarchar),
     lobSize_((Int64)CmpCommon::getDefaultNumeric(LOB_MAX_SIZE)*1024*1024),
    fsType_(REC_BLOB)
    {};
  
  // copyTopNode method
  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
				 CollHeap* outHeap = 0);

  ItemExpr *bindNode(BindWA *bindWA);

  // a virtual function for type propagating the node
  virtual const NAType * synthesizeType();
  
  // method to do code generation
  virtual short codeGen(Generator*);

  // returns TRUE so this could be evaluated in master.
  virtual NABoolean isAUserSuppliedInput() const { return TRUE; };

  Int64 & insertedTableObjectUID() { return objectUID_; }
  
  NAString &insertedTableSchemaName() { return schName_; }

  //  Lng32 & lobNum() { return lobNum_; }

  Int64 & lobSize() { return lobSize_; }

  Lng32 & lobFsType() { return fsType_; }
  NABoolean lobAsVarchar() const { return lobAsVarchar_;}
 protected:
  // ---------------------------------------------------------------//
  // ObjectUID of the table this blob is being inserted into
  // -------------------------------------------------------------- //
  Int64 objectUID_;

  // schemaname of the table
  NAString schName_;

  // column this blob is being inserted into.
  //  Lng32 lobNum_;

  Int64 lobSize_;

  Lng32 fsType_;

  NABoolean append_;
  NABoolean lobAsVarchar_;//This means this lob insert will get it's input data 
                          // in varchar format
}; // class LOBinsert

class LOBselect : public LOBoper
{
 public:
  
 LOBselect(ItemExpr *val1Ptr, ItemExpr *val2Ptr, ObjectType toObj)
   : LOBoper(ITM_LOBSELECT, val1Ptr, val2Ptr,NULL,toObj)
    {
    };
  
  // copyTopNode method
  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
				 CollHeap* outHeap = 0);
  
  ItemExpr *bindNode(BindWA *bindWA);
 
  // a virtual function for type propagating the node
 
  // method to do code generation
  virtual short codeGen(Generator*);
  
 private:
 
}; // class LOBselect

class LOBdelete : public LOBoper
{
 public:
  
 LOBdelete(ItemExpr *val1Ptr)
   : LOBoper(ITM_LOBDELETE, val1Ptr)
    {};
  
  // copyTopNode method
  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
				 CollHeap* outHeap = 0);
  
  // method to do code generation
  virtual short codeGen(Generator*);

 private:
}; // class LOBdelete


class LOBupdate : public LOBoper
{
 public:
  
  LOBupdate(ItemExpr *val1Ptr,
	    ItemExpr *val2Ptr,
	    ItemExpr *val3Ptr,
	    ObjectType fromObj, 
	    NABoolean isAppend = FALSE,
            NABoolean treatLobAsVarchar =FALSE)
    : LOBoper(ITM_LOBUPDATE, val1Ptr, val2Ptr,val3Ptr,fromObj),
      objectUID_(-1),
      lobSize_((Int64)CmpCommon::getDefaultNumeric(LOB_MAX_SIZE)*1024*1024),
      append_(isAppend),
      lobAsVarchar_(treatLobAsVarchar)
    {};
  
  // copyTopNode method
  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
				 CollHeap* outHeap = 0);

  // a virtual function for type propagating the node
  virtual const NAType * synthesizeType();
  
  // method to do code generation
  virtual short codeGen(Generator*);
  // method to do precode generation
  virtual ItemExpr * preCodeGen(Generator*);
  // virtual Int32 getArity() const;
  NABoolean isAppend() { return append_; };

  Int64 & updatedTableObjectUID() { return objectUID_; }
  
  NAString &updatedTableSchemaName() { return schName_; }
  Int64 & lobSize() { return lobSize_; }
  NABoolean lobAsVarchar() const { return lobAsVarchar_;}
 private:
  // ---------------------------------------------------------------//
  // ObjectUID of the table this blob is being inserted into
  // -------------------------------------------------------------- //
  Int64 objectUID_;

  // schemaname of the table
  NAString schName_;


  NABoolean append_;
  Int64 lobSize_;
  NABoolean lobAsVarchar_;//This means this lob insert will get it's input data 
                          // in varchar format
}; // class LOBupdate

class LOBconvert : public LOBoper
{
 public:
  
 LOBconvert(ItemExpr *val1Ptr, ObjectType toObj,  Lng32 tgtSize= CmpCommon::getDefaultNumeric(LOB_OUTPUT_SIZE) ) 
   : LOBoper(ITM_LOBCONVERT, val1Ptr, NULL,NULL,toObj),
    tgtSize_(tgtSize)     
    {};
  
  // copyTopNode method
  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
				 CollHeap* outHeap = 0);
  
  // a virtual function for type propagating the node
  virtual const NAType * synthesizeType();

  // method to do precode generation
  virtual ItemExpr * preCodeGen(Generator*);

  // method to do code generation
  virtual short codeGen(Generator*);

  Lng32 getTgtSize() { return tgtSize_; }
 private:
  Lng32 tgtSize_;
 
}; // class LOBconvert

class LOBconvertHandle : public LOBoper
{
 public:
  
 LOBconvertHandle(ItemExpr *val1Ptr, ObjectType toObj)
   : LOBoper(ITM_LOBCONVERTHANDLE, val1Ptr, NULL,NULL,toObj)
    {};
  
  // copyTopNode method
  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
				 CollHeap* outHeap = 0);
  
  // a virtual function for type propagating the node
  virtual const NAType * synthesizeType();

  // method to do code generation
  virtual short codeGen(Generator*);

 private:
}; // class LOBconvertHandle


class LOBextract : public LOBoper
{
 public:
  
 LOBextract(ItemExpr *val1Ptr, Lng32 tgtSize = 1000)
   : LOBoper(ITM_LOBEXTRACT, val1Ptr, NULL,NULL,EXTRACT_),
    tgtSize_(tgtSize)
    {};
  
  // copyTopNode method
  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
				 CollHeap* outHeap = 0);
  
  // a virtual function for type propagating the node
  virtual const NAType * synthesizeType();

  // method to do code generation
  //virtual short codeGen(Generator*);
  
  Lng32 getTgtSize() { return tgtSize_; }
 private:
  Lng32 tgtSize_;
}; // class LOBext

class CompEncode : public BuiltinFunction
{
protected:

  // Encodes operand so it could be compared using a byte
  // comparison.
  short descFlag_; // if TRUE, encoding to be done for descending comparison.

  // encode so case insensitive comparisons could be done.
  // Valid for char/varchar datatypes only.
  NABoolean caseinsensitiveEncode_;

  CharInfo::Collation encodedCollation_;

  CollationInfo::CollationType collationType_;

  // length of encoded result, if passed in to the constructor.
  // If not passed in, or passed in and is -1, then the total
  // size of child is the length of CompEncode result.
  Lng32 length_;

  // if set, then result is nullable if child is nullable (same as other exprs and function).
  // Only the data bytes are encoded in this case.
  NABoolean regularNullability_;

  // Constructor used by derived class
  CompEncode(ItemExpr *val1Ptr, 
	     short descFlag,
	     Lng32 length,
	     CollationInfo::CollationType collType,
	     NABoolean regularNullability,
	     OperatorTypeEnum operType,
             NAMemory *h)
    : BuiltinFunction(operType, h, 1, val1Ptr),
    descFlag_(descFlag), 
    caseinsensitiveEncode_(FALSE),
    encodedCollation_(CharInfo::DefaultCollation),
    length_(length),
    collationType_(collType),
    regularNullability_(regularNullability)
      {}

public:
  CompEncode(ItemExpr *val1Ptr, 
	     short descFlag = FALSE,
	     Lng32 length = -1,
	     CollationInfo::CollationType collType = CollationInfo::Sort,
	     NABoolean regularNullability = FALSE,
             NAMemory *h = CmpCommon::statementHeap())
    : BuiltinFunction(ITM_COMP_ENCODE, h, 1, val1Ptr),
    descFlag_(descFlag), 
    caseinsensitiveEncode_(FALSE),
    encodedCollation_(CharInfo::DefaultCollation),
    length_(length),
    collationType_(collType),
    regularNullability_(regularNullability)
      {}

  // virtual destructor
  virtual ~CompEncode();

  // method to do precode generation
  virtual ItemExpr * preCodeGen(Generator*);

  // method to do code generation
  virtual short codeGen(Generator*);

  // a virtual function for type propagating the node
  virtual const NAType * synthesizeType();

  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
				 CollHeap* outHeap = 0);

  void setCaseinsensitiveEncode(NABoolean v) {caseinsensitiveEncode_ = v;}

  void setEncodedCollation(CharInfo::Collation v) {encodedCollation_ = v;}

  void setCollationType(CollationInfo::CollationType v) { collationType_ = v;}

  short getDescFlag() const { return descFlag_;}

  NABoolean getCaseInsensitiveEncode() const { return caseinsensitiveEncode_;}

  Int32 getEncodedCollation() const { return encodedCollation_;}

  NABoolean getCollationType() const { return collationType_;}

  NABoolean isDecode() const { return getOperatorType() == ITM_COMP_DECODE; }

  static Lng32  getEncodedLength( const CharInfo::Collation collation,
						 const CollationInfo::CollationType ct,
						 const Lng32 srcLength,
						 const NABoolean nullable); 

  virtual QR::ExprElement getQRExprElem() const {return QR::QRFunctionWithParameters;}

}; // class CompEncode

class CompDecode : public CompEncode
{
public:
  CompDecode(ItemExpr *val1Ptr, 
             const NAType *unencodedType,
	     short descFlag = FALSE,
	     Lng32 length = -1,
	     CollationInfo::CollationType collType = CollationInfo::Sort,
	     NABoolean regularNullability = TRUE,
            NAMemory *h = CmpCommon::statementHeap())
    : CompEncode(val1Ptr, descFlag, length, collType, regularNullability, 
		 ITM_COMP_DECODE, h),
    unencodedType_(unencodedType)
    {}

  // virtual destructor
  virtual ~CompDecode();

  // method to do precode generation
  virtual ItemExpr * preCodeGen(Generator*);

  // method to do code generation
  virtual short codeGen(Generator*);

  // a virtual function for type propagating the node
  virtual const NAType * synthesizeType();

  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
				 CollHeap* outHeap = 0);

 private:
  const NAType * unencodedType_;
}; // class CompDecode

// -----------------------------------------------------------------------
// Built-in functions
// -----------------------------------------------------------------------
class HashCommon : public BuiltinFunction
{
  enum
  {
    CASESENSITIVE_HASH_ = 0x0001
  };

public:
  HashCommon(OperatorTypeEnum otype,
	     Lng32  argumentCount = 0,
	     ItemExpr *child0 = NULL,
	     ItemExpr *child1 = NULL,
	     ItemExpr *child2 = NULL,
	     ItemExpr *child3 = NULL,
	     ItemExpr *child4 = NULL,
	     ItemExpr *child5 = NULL)
       : BuiltinFunction(otype, CmpCommon::statementHeap(), argumentCount, 
			 child0, child1, child2, child3, child4, child5),
	 flags_(0)
  {
  }

  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
				 CollHeap* outHeap = 0);

  void setCasesensitiveHash(NABoolean v)      
  { (v ? flags_ |= CASESENSITIVE_HASH_ : flags_ &= ~CASESENSITIVE_HASH_); }
  NABoolean casesensitiveHash() {return (flags_ & CASESENSITIVE_HASH_) != 0;}

protected:
  NABoolean areChildrenExactNumeric(Lng32 left, Lng32 right);

private:
  UInt32 flags_;
};

class Hash : public HashCommon
{
  // Defined for all data types, returns a 32 bit non-nullable
  // hash value for the data item.
public:
  Hash(ItemExpr *val1Ptr)
         : HashCommon(ITM_HASH, 1, val1Ptr) {}

  // virtual destructor
  virtual ~Hash();

  // a virtual function for type propagating the node
  virtual const NAType * synthesizeType();

  // generator methods
  virtual ItemExpr * preCodeGen(Generator*);
  virtual short codeGen(Generator*);

  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
				 CollHeap* outHeap = 0);

  virtual NABoolean protectFromVEGs() { return TRUE; };

  // get a printable string that identifies the operator
  //
  virtual const NAString getText() const { return "Hash"; };
}; // class Hash

class HashComb : public HashCommon
{
  // Defined for two operands of type UNSIGNED INTEGER
  // Returns a value of type UNSIGNED INTEGER
public:
  HashComb(ItemExpr *val1Ptr, ItemExpr *val2Ptr)
    : HashCommon(ITM_HASHCOMB, 2, val1Ptr, val2Ptr) {}

  // virtual destructor
  virtual ~HashComb();

  // a virtual function for type propagating the node
  virtual const NAType * synthesizeType();

  // method to do code generation
  virtual short codeGen(Generator*);

  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
				 CollHeap* outHeap = 0);

  // get a printable string that identifies the operator
  //
  virtual const NAString getText() const { return "HashComb"; };
}; // class HashComb

class HiveHashComb : public HashCommon
{
  // Defined for two operands of type UNSIGNED INTEGER
  // Returns a value of type UNSIGNED INTEGER
public:
  HiveHashComb(ItemExpr *val1Ptr, ItemExpr *val2Ptr)
    : HashCommon(ITM_HIVE_HASHCOMB, 2, val1Ptr, val2Ptr) {}

  // virtual destructor
  virtual ~HiveHashComb() {};

  // a virtual function for type propagating the node
  virtual const NAType * synthesizeType();

  // method to do code generation
  virtual short codeGen(Generator*);

  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
                                 CollHeap* outHeap = 0);

  // get a printable string that identifies the operator
  //
  virtual const NAString getText() const { return "HiveHashComb"; };
}; // class HiveHashComb


// The following two classes (HashDistPartHash and
// HashDistPartHashComb) are used by the HashDistPartitioningFunction.
// They are isolated from the other general purpose versions of these
// functions so that they won't be inadvertently altered.  Any changes
// these functions that results in a different runtime behavior will
// cause existing hash partitioned tables to be invalid.
//
class HashDistPartHash : public HashCommon
{
  // Hash Function used by Hash Partitioning. This function
  // cannot change once Hash Partitioning is released!
  // Defined for all data types, returns a 32 bit non-nullable
  // hash value for the data item.
public:
  HashDistPartHash(ItemExpr *val1Ptr)
         : HashCommon(ITM_HDPHASH, 1, val1Ptr) {}

  // virtual destructor
  virtual ~HashDistPartHash();

  // a virtual function for type propagating the node
  virtual const NAType * synthesizeType();

  // generator methods
  virtual ItemExpr * preCodeGen(Generator*);
  virtual short codeGen(Generator*);

  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
				 CollHeap* outHeap = 0);

  virtual NABoolean protectFromVEGs() { return TRUE; };

  // get a printable string that identifies the operator
  //
  virtual const NAString getText() const { return "HashDistPartHash"; };
}; // class HashDistPartHash

class HashDistPartHashComb : public HashCommon
{
  // This function is used to combine two hash values to produce a new
  // hash value. Used by Hash Partitioning. This function cannot
  // change once Hash Partitioning is released!  Defined for all data
  // types, returns a 32 bit non-nullable hash value for the data
  // item.

  // Defined for two operands of type UNSIGNED INTEGER
  // Returns a value of type UNSIGNED INTEGER
public:
  HashDistPartHashComb(ItemExpr *val1Ptr, ItemExpr *val2Ptr)
    : HashCommon(ITM_HDPHASHCOMB, 2, val1Ptr, val2Ptr) {}

  // virtual destructor
  virtual ~HashDistPartHashComb();

  // a virtual function for type propagating the node
  virtual const NAType * synthesizeType();

  // method to do code generation
  virtual short codeGen(Generator*);

  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
				 CollHeap* outHeap = 0);

  virtual NABoolean protectFromVEGs() { return TRUE; };

  // get a printable string that identifies the operator
  //
  virtual const NAString getText() const { return "HashDistPartHashComb"; };
}; // class HashDistPartHashComb

class HiveHash : public HashCommon
{
  // Defined for all data types, returns a 32 bit non-nullable
  // hash value for the data item.
public:
  HiveHash(ItemExpr *val1Ptr)
         : HashCommon(ITM_HIVE_HASH, 1, val1Ptr) {}

  // virtual destructor
  virtual ~HiveHash() {};

  // a virtual function for type propagating the node
  virtual const NAType * synthesizeType();

  // generator methods
  virtual ItemExpr * preCodeGen(Generator*);
  virtual short codeGen(Generator*);

  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
                                 CollHeap* outHeap = 0);

  virtual NABoolean protectFromVEGs() { return TRUE; };

  // get a printable string that identifies the operator
  //
  virtual const NAString getText() const { return "HiveHash"; };
}; // class HiveHash


////////////////////////////////////////////////////////////////
// Various Math functions are represented by this operator.
// The operatorType() tells which math function it is.
////////////////////////////////////////////////////////////////
class MathFunc : public CacheableBuiltinFunction
{
public:
  MathFunc(OperatorTypeEnum oper,
	   ItemExpr *val1Ptr = NULL, ItemExpr *val2Ptr = NULL)
         : CacheableBuiltinFunction(oper, 2, val1Ptr, val2Ptr)
  { allowsSQLnullArg() = FALSE; }

  // get the degree of this node (it depends on the type of the operator)
  virtual Int32 getArity() const;

  // a virtual function for type propagating the node
  virtual const NAType * synthesizeType();

  // method to do pre code generation
  virtual ItemExpr * preCodeGen(Generator*);

  // method to do code generation
  virtual short codeGen(Generator*);

  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
				 CollHeap* outHeap = 0);

  // get a printable string that identifies the operator
  virtual const NAString getText() const;

  virtual NABoolean hasEquivalentProperties(ItemExpr * other) { return TRUE;}
  
  virtual NABoolean calculateMinMaxUecs(ColStatDescList & histograms,
					       CostScalar & minUec,
					       CostScalar & maxUec);

  NAType* findReturnTypeForFloorCeil(NABoolean nullable);
};

class Abs : public MathFunc
{
public:
  Abs(ItemExpr *val1Ptr)
    : MathFunc(ITM_ABS, val1Ptr)
    { allowsSQLnullArg() = FALSE; }

  // a virtual function for type propagating the node
  virtual const NAType * synthesizeType();

  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
				 CollHeap* outHeap = 0);

  virtual ItemExpr * bindNode(BindWA *bindWA);

  // method to do pre code generation
  virtual ItemExpr * preCodeGen(Generator*);

  // method to do code generation
  virtual short codeGen(Generator*);

  virtual NABoolean hasEquivalentProperties(ItemExpr * other) { return TRUE;}

}; // class Abs

////////////////////////////////////////////////////////////////
// Various bit functions are represented by this operator.
// The operatorType() tells which bit function it is.
////////////////////////////////////////////////////////////////
class BitOperFunc : public CacheableBuiltinFunction
{
public:
  BitOperFunc(OperatorTypeEnum oper,
	      ItemExpr *val1Ptr = NULL, ItemExpr *val2Ptr = NULL,
	      ItemExpr *val3Ptr = NULL)
       : CacheableBuiltinFunction(oper, 3, val1Ptr, val2Ptr, val3Ptr)
  { allowsSQLnullArg() = FALSE; }
  
  // get the degree of this node (it depends on the type of the operator)
  virtual Int32 getArity() const;

  // a virtual function for type propagating the node
  virtual const NAType * synthesizeType();

  // a virtual function for performing name binding within the query tree
  virtual ItemExpr * bindNode(BindWA *bindWA);

  // method to do pre code generation
  virtual ItemExpr * preCodeGen(Generator*);

  // method to do code generation
  virtual short codeGen(Generator*);

  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
				 CollHeap* outHeap = 0);

  // get a printable string that identifies the operator
  virtual const NAString getText() const;

  virtual NABoolean hasEquivalentProperties(ItemExpr * other) { return TRUE;}

};

class Modulus : public CacheableBuiltinFunction
{
  // Defined for two operands of exact numeric data types with scale 0.
  // Returns a value of the data type of the second operand.
public:
  Modulus(ItemExpr *val1Ptr, ItemExpr *val2Ptr)
         : CacheableBuiltinFunction(ITM_MOD, 2, val1Ptr, val2Ptr)
  { allowsSQLnullArg() = FALSE; }

  // virtual destructor
  virtual ~Modulus();

  // a virtual function for type propagating the node
  virtual const NAType * synthesizeType();

  // method to do pre code generation
  virtual ItemExpr * preCodeGen(Generator*);

  // method to do code generation
  virtual short codeGen(Generator*);

  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
				 CollHeap* outHeap = 0);

  virtual NABoolean calculateMinMaxUecs(ColStatDescList & histograms,
					       CostScalar & minUec,
					       CostScalar & maxUec);

}; // class Modulus

/////////////////////////////////////////////////////////////////////
// Returns a string composed of val1ptr repeated val2ptr times.
/////////////////////////////////////////////////////////////////////
class Repeat : public BuiltinFunction
{
public:
  Repeat(ItemExpr *val1Ptr, ItemExpr *val2Ptr, Int32 maxLength = -1)
       : BuiltinFunction(ITM_REPEAT, CmpCommon::statementHeap(),
                         2, val1Ptr, val2Ptr),
         maxLength_(maxLength),
         maxLengthWasExplicitlySet_(FALSE)
  { 
    allowsSQLnullArg() = FALSE; 
    if (maxLength > 0)
      maxLengthWasExplicitlySet_ = TRUE;
  }

  // a virtual function for type propagating the node
  virtual const NAType * synthesizeType();

  virtual ItemExpr * preCodeGen(Generator*);

  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
				 CollHeap* outHeap = 0);

  NABoolean isCharTypeMatchRulesRelaxable()
  { return child(0)->isCharTypeMatchRulesRelaxable(); } ;

  virtual NABoolean protectFromVEGs() { return TRUE; };

  const Int32 getMaxLength() { return maxLength_ ;} ;
  void setMaxLength(Int32 val) {maxLength_ = val;} ;

 private:

  // max length of Repeat expression. 
  // If not passed in during constrtuctor, then it is set only when Repeat
  // is used certain expansions of LPAD and RPAD. 
  // It is initialized to the value -1, which indicates that maxLength 
  // has not been computed or passed in.
  Int32 maxLength_;

  // if max length was specified in REPEAT function 
  // and passed in during constructor.
  NABoolean maxLengthWasExplicitlySet_;

  virtual NABoolean hasEquivalentProperties(ItemExpr * other) { return TRUE;}

}; // class Repeat


/////////////////////////////////////////////////////////////////////
// Replaces all occurances of string val2ptr in string val1Ptr with
// string val3Ptr.
/////////////////////////////////////////////////////////////////////
class Replace : public CacheableBuiltinFunction
{
public:
  Replace(ItemExpr *val1Ptr, ItemExpr *val2Ptr, ItemExpr *val3Ptr)
       : CacheableBuiltinFunction(ITM_REPLACE, 3, val1Ptr, val2Ptr, val3Ptr)
  { allowsSQLnullArg() = FALSE; }

  // a virtual function for type propagating the node
  virtual const NAType * synthesizeType();

  // a virtual function for performing name binding within the query tree
  virtual ItemExpr * bindNode(BindWA *bindWA);

  NABoolean isRelaxCharTypeMatchRulesPossible() {return TRUE;};

  // The following method enables expressions such as
  // iso88591_column = replace(:ucs2_hv1,:ucs2_hv2, :ucs2_hv3)
  NABoolean isCharTypeMatchRulesRelaxable()
  { return child(0)->isCharTypeMatchRulesRelaxable() &&
           child(1)->isCharTypeMatchRulesRelaxable() &&
           child(2)->isCharTypeMatchRulesRelaxable();
  } ;

  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
				 CollHeap* outHeap = 0);

  virtual NABoolean protectFromVEGs() { return TRUE; };

  virtual NABoolean hasEquivalentProperties(ItemExpr * other) { return TRUE;}

}; // class Replace


class ReplaceNull : public BuiltinFunction
{
  // Returns third argument if first argument is null,
  // Otherwise returns second argument.
  // Defined for all types.
public:
  ReplaceNull(ItemExpr *val1Ptr, ItemExpr *val2Ptr, ItemExpr *val3Ptr)
         : BuiltinFunction(ITM_REPLACE_NULL, CmpCommon::statementHeap(),
                           3, val1Ptr, val2Ptr, val3Ptr) {}

  // virtual destructor
  virtual ~ReplaceNull();

  // a virtual function for type propagating the node
  virtual const NAType * synthesizeType();

  // generator methods
  virtual ItemExpr * preCodeGen(Generator*);
  virtual short codeGen(Generator*);

  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
				 CollHeap* outHeap = 0);

}; // class ReplaceNull

class HashDistrib : public HashCommon
{
  // Defined for two operands with scale 0.
  // The first operand is the a arbitrary integer value.
  // The second operand is the number of mapped values.
  // Returns a value of the data type of the second operand.
  // The result is a value in the range 0 - (<number of mapped values> - 1)
  // distributed in a way that is useful for Hash Partitioning.
  //
public:
  HashDistrib(OperatorTypeEnum otype, ItemExpr *val1Ptr, ItemExpr *val2Ptr)
    : HashCommon(otype, 2, val1Ptr, val2Ptr) {}

  // virtual destructor
  virtual ~HashDistrib();

  // a virtual function for type propagating the node
  virtual const NAType * synthesizeType();

  // generator methods
  virtual ItemExpr * preCodeGen(Generator*);
  virtual short codeGen(Generator*);

  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
				 CollHeap* outHeap = 0);

  // get a printable string that identifies the operator
  //
  virtual const NAString getText() const { return "HashDistrib"; };

}; // class HashDistrib;

class Hash2Distrib : public HashDistrib
{
  // Defined for two operands with scale 0.
  // The first operand is the a arbitrary integer value.
  // The second operand is the number of mapped values.
  // Returns a value of the data type of the second operand.
  // The result is a value in the range 0 - (<number of mapped values> - 1)
  // distributed in a way that is useful for Hash Partitioning.
  //
public:
  Hash2Distrib(ItemExpr *val1Ptr, ItemExpr *val2Ptr)
    : HashDistrib(ITM_HASH2_DISTRIB, val1Ptr, val2Ptr) {}

  // virtual destructor
  virtual ~Hash2Distrib();

  virtual short codeGen(Generator*);

  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
                                 CollHeap* outHeap = 0);

  // get a printable string that identifies the operator
  //
  virtual const NAString getText() const { return "Hash2Distrib"; };

}; // class Hash2Distrib;

class ProgDistrib : public HashDistrib
{
  // Defined for two operands with scale 0.
  // The first operand is the a arbitrary integer value.
  // The second operand is the number of mapped values.
  // Returns a value of the data type of the second operand.
  // The result is a value in the range 0 - (<number of mapped values> - 1)
  // distributed in a way that is useful for Hash Partitioning.
  //
public:
  ProgDistrib(ItemExpr *val1Ptr, ItemExpr *val2Ptr)
    : HashDistrib(ITM_PROGDISTRIB, val1Ptr, val2Ptr) {}

  // virtual destructor
  virtual ~ProgDistrib();

  virtual short codeGen(Generator*);

  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
                                 CollHeap* outHeap = 0);

  // get a printable string that identifies the operator
  //
  virtual const NAString getText() const { return "ProgDistrib"; };

}; // class ProgDistrib;

class ProgDistribKey : public BuiltinFunction
{
public:
  ProgDistribKey(ItemExpr *value,
                 ItemExpr *offset,
                 ItemExpr *totalNumValues)
    : BuiltinFunction(ITM_PROGDISTRIBKEY, CmpCommon::statementHeap(),
                      3, value, offset, totalNumValues) {}

  // virtual destructor
  virtual ~ProgDistribKey();

  // a virtual function for type propagating the node
  virtual const NAType * synthesizeType();

  // generator methods
  virtual ItemExpr * preCodeGen(Generator*);
  virtual short codeGen(Generator*);

  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
				 CollHeap* outHeap = 0);

  // get a printable string that identifies the operator
  //
  virtual const NAString getText() const { return "ProgDistribKey"; };

}; // class ProgDistribKey;

class PAGroup : public BuiltinFunction
{
  // Defined for three operands with scale 0.  The first operand is
  // the an integer value representing the partition number (before
  // grouping).  The second operand is the number of groups and the
  // third is the number of partitions before grouping.  Returns a
  // value of the data type of the first operand.  The result is a
  // value in the range 0 - (<number of groups> - 1).
  //
public:
  PAGroup(ItemExpr *val1Ptr, ItemExpr *val2Ptr, ItemExpr *val3Ptr)
    : BuiltinFunction(ITM_PAGROUP, CmpCommon::statementHeap(),
                      3, val1Ptr, val2Ptr, val3Ptr) {}

  // virtual destructor
  virtual ~PAGroup();

  // a virtual function for type propagating the node
  virtual const NAType * synthesizeType();

  // generator methods
  virtual ItemExpr * preCodeGen(Generator*);
  virtual short codeGen(Generator*);

  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
				 CollHeap* outHeap = 0);

  // get a printable string that identifies the operator
  //
  virtual const NAString getText() const { return "PAGroup"; };

}; // class PAGroup;

class InverseOrder : public BuiltinFunction
{
  // Defined for all data types that can be used in an ORDER BY clause.
  // This function returns a result that has the same data type as its
  // input and has the following property:
  //     if a > b then inverse(a) < inverse(b)
  // (for numeric data types this is similar to the unary "-" operator)
  // This function is not usually needed in the executor, it is mainly
  // for the optimizer to indicate descending order. For example, the
  // SQL syntax "order by t1.a desc" is internally represented as
  // "order by inverse(t1.a)".
public:
  InverseOrder(ItemExpr *val1Ptr)
         : BuiltinFunction(ITM_INVERSE, CmpCommon::statementHeap(),
                           1, val1Ptr) {}

  // virtual destructor
  virtual ~InverseOrder();

  // a virtual function for type propagating the node
  virtual const NAType * synthesizeType();

  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
				 CollHeap* outHeap = 0);

  virtual ItemExpr * simplifyOrderExpr(OrderComparison *newOrder = NULL);

  virtual ItemExpr * removeInverseOrder();

  virtual NABoolean hasEquivalentProperties(ItemExpr * other) { return TRUE;}


}; // class InverseOrder

// Defined for all data types.
// Increments the value that is its operand by one.
// It is used for transforming a > comparison in an index search key
// to a >= comparison.
// Increment(MaxValue for a datatype) causes an overflow.
class Increment : public BuiltinFunction
{
public:
  Increment(ItemExpr *val1Ptr)
         : BuiltinFunction(ITM_INCREMENT, CmpCommon::statementHeap(),
                           1, val1Ptr) {}

  // virtual destructor
  virtual ~Increment();

  // a virtual function for type propagating the node
  virtual const NAType * synthesizeType();

  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
				 CollHeap* outHeap = 0);

}; // class Increment

// Defined for all data types.
// Decrements the value that is its operand by one.
// It is used for transforming a < comparison in an index search key
// to a <= comparison.
// Decrement(MinValue for a datatype) causes an underflow.
class Decrement : public BuiltinFunction
{
public:
  Decrement(ItemExpr *val1Ptr)
         : BuiltinFunction(ITM_DECREMENT, CmpCommon::statementHeap(),
                           1, val1Ptr) {}

  // virtual destructor
  virtual ~Decrement();

  // a virtual function for type propagating the node
  virtual const NAType * synthesizeType();

  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
				 CollHeap* outHeap = 0);

}; // class Decrement

// A ternary version of the comparison operator from class BiRelat. The
// first two operands <op1> and <op2> are two values to be compared,
// the boolean third operand <op3>, together with the operator type,
// indicates the type of comparison:
//
//   Operator type          op3 is FALSE             op3 is TRUE
// -----------------   ----------------------  ---------------------
//  ITM_LESS_OR_LE           op1 <= op2               op1 < op2
// ITM_GREATER_OR_GE         op1 >= op2               op1 > op2
//
// ITM_LESS_OR_LE is simply a shortcut for
//            case when op3 then op1 < op2 else op1 <= op2 end
// and ITM_GREATER_OR_GE is a shortcut for
//            case when op3 then op1 > op2 else op1 >= op2 end
//
// The TriRelational operator is used for cases where it is not known
// at compile time whether a greater or less comparison includes or
// excludes the case that both values are equal. In all practical cases,
// this is used for key predicates and is translated into an appropriate
// flag for the file system. In the unlikely case that this has to be
// evaluated for a non-key predicate, it gets transformed into an
// IfThenElse executor predicate: if (op3) then op1 < op2 else op1 <= op2
// or if (op3) then op1 > op2 else op1 >= op2, respectively.
class TriRelational : public BuiltinFunction
{
public:
  TriRelational(OperatorTypeEnum optype,
		ItemExpr *val1Ptr,
		ItemExpr *val2Ptr,
		ItemExpr *val3Ptr);

  // virtual destructor
  virtual ~TriRelational();

  // a virtual function for type propagating the node
  virtual const NAType * synthesizeType();

  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
				 CollHeap* outHeap = 0);

  virtual ItemExpr * preCodeGen(Generator*);

  // method to generate Mdam predicates
  short mdamPredGen(Generator * generator,
                    MdamPred ** head,
                    MdamPred ** tail,
                    MdamCodeGenHelper & mdamHelper,
                    ItemExpr * parent);
  inline NABoolean getSpecialNulls()             { return specialNulls_; }
  inline void setSpecialNulls(NABoolean flag)    { specialNulls_ = flag; }

private:

  // the next field, if set, indicates that 'nulls are values'.
  // That means that nulls are equal to other nulls, and they
  // sort higher than other values. Used for groupby, order
  // by, hashing, or any other operation where nulls are NOT
  // to be ignored.
  NABoolean specialNulls_;

}; // class TriRelational

class RangeLookup : public BuiltinFunction
{
public:
  RangeLookup(ItemExpr *val1Ptr,
	      const RangePartitioningFunction *partFunc);

  virtual ~RangeLookup();

  // a virtual function for type propagating the node
  virtual const NAType * synthesizeType();

  // method to do code generation
  virtual short codeGen(Generator*);

  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
				 CollHeap* outHeap = 0);

private:

  // private methods to avoid teaching the expression generator about
  // partitioning functions
  Lng32 splitKeysLen();
  void copySplitKeys(char *tgt, Lng32 tgtLen);
  Lng32 getNumOfPartitions();
  Lng32 getEncodedBoundaryKeyLength();

  // private data members

  const RangePartitioningFunction *partFunc_;
}; // class RangeLookup

class ScalarVariance : public CacheableBuiltinFunction
{
public:
  ScalarVariance(OperatorTypeEnum opType,  // ITM_VARIANCE or ITM_STDDEV
		 ItemExpr *SumOfValSquared,
		 ItemExpr *SumOfVal,
		 ItemExpr *CountOfVal)
    : CacheableBuiltinFunction(opType, 3, SumOfValSquared, SumOfVal, CountOfVal) {}

  // virtual destructor
  virtual ~ScalarVariance();

  // a virtual function for type propagating the node
  virtual const NAType * synthesizeType();

  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
				 CollHeap* outHeap = 0);
  // method to do code generation
  virtual short codeGen(Generator*);

  virtual ItemExpr * preCodeGen(Generator*);

  // get a printable string that identifies the operator
  virtual const NAString getText() const
  {
    switch(getOperatorType())
      {
      case ITM_VARIANCE:
	return "Scalar Variance";
      case ITM_STDDEV:
	return "Scalar Stddev";
      default:
	return "Unknown Scalar Variance Function";
      }
  };

  virtual NABoolean hasEquivalentProperties(ItemExpr * other) { return TRUE;}

}; // class ScalarVariance

// Class RowsetArrayScan
// This built in function is used to extract an element of a Rowset array
// Both the Rowset array and the index value are provided at run time.
// Items of type ArrayIndex are attached to an UnpackRows node at compile
// time. When the generator finds an UnpackRows node, it creates an
// PhysUnPackRows, and when it finds an ArrayIndex item, it generates a
// ex_RowsetArrayScan node. At run time, each ExRowsetArrayScan node is
// evaluated and the corresponding array element is returned by the
// PhysUnPackRows node to its parent.
//
// opType == ITM_ROWSETARRAY_SCAN to access the elements of the array
//        == ITM_ROWSETARRAY_INDEX to retrieve the current index

class RowsetArrayScan : public BuiltinFunction
{
public:
  RowsetArrayScan(ItemExpr     *source,
                  ItemExpr     *index,
                  Lng32         maxNumElem,
                  Lng32         elemSize,
                  NABoolean    elemNullInd,
                  const NAType *elemType,
                  OperatorTypeEnum opType = ITM_ROWSETARRAY_SCAN)
    : BuiltinFunction(opType, CmpCommon::statementHeap(), 2, source, index),
    maxNumElem_(maxNumElem),
    elemSize_(elemSize),
    elemNullInd_(elemNullInd),
    elemType_(elemType)
    {
    };

  // virtual destructor
  virtual ~RowsetArrayScan();

  // a virtual function for type propagating the node
  //
  virtual const NAType * synthesizeType();

  // allow relaxation for rowset array scan (similary to a regular hostvar)
  NABoolean isCharTypeMatchRulesRelaxable();

  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
                                 CollHeap* outHeap = 0);

  // RowsetArrayScan behaves as an Aggregate, which is NOT covered even
  // if its children are.
  virtual NABoolean isCovered(const ValueIdSet& newExternalInputs,
                              const GroupAttributes& newRelExprAnchorGA,
                              ValueIdSet& referencedInputs,
                              ValueIdSet& coveredSubExpr,
                              ValueIdSet& unCoveredExpr) const;

  // RowsetArrayScan is considered a leaf node for cover test.
  virtual void getLeafValuesForCoverTest(ValueIdSet & leafValues, 
                                         const GroupAttributes& coveringGA,
                                         const ValueIdSet & newExternalInputs) const;

  // Return the type of the array elements
  const NAType *getType() const { return elemType_; }

  // method to do code generation
  //
  virtual short codeGen(Generator*);

  // get a printable string that identifies the operator
  //
  virtual const NAString getText() const
  {
    return "RowsetArrayScan";
  };

  // This method is used to figure out the type of the array elements in case
  // they were not specified. This may happen in a dynamic rowset query that
  // contains unspecified parameters, like for instance "insert into t values(?)"
  const NAType * pushDownType(NAType& desiredType,
                        enum NABuiltInTypeEnum defaultQualifier);

private:
  Lng32         maxNumElem_;      // Maximum number of elements
  Lng32         elemSize_;        // Element storage length in bytes
  NABoolean    elemNullInd_;     // Null Indicator ?
  const NAType *elemType_;       // The datatype of the array elements

};

class RowsetArrayInto : public BuiltinFunction
{
public:
  RowsetArrayInto(ItemExpr     *source,
                  ItemExpr     *numElemExpr,
                  Lng32         maxNumElem,
                  Lng32         elemSize,
                  NABoolean    elemNullInd,
                  const NAType *hostVarType,
                  OperatorTypeEnum opType = ITM_ROWSETARRAY_INTO)
    : BuiltinFunction(opType, CmpCommon::statementHeap(),
                      2, source, numElemExpr),
      maxNumElem_(maxNumElem),
      elemSize_(elemSize),
      elemNullInd_(elemNullInd),
      hostVarType_(hostVarType)
    {
    };

  // virtual destructor
  virtual ~RowsetArrayInto();

  // a virtual function for type propagating the node
  //
  virtual const NAType * synthesizeType();

  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
                                 CollHeap* outHeap = 0);

  // RowsetArrayInto behaves as an Aggregate, which is NOT covered even
  // if its children are.
  virtual NABoolean isCovered(const ValueIdSet& newExternalInputs,
                              const GroupAttributes& newRelExprAnchorGA,
                              ValueIdSet& referencedInputs,
                              ValueIdSet& coveredSubExpr,
                              ValueIdSet& unCoveredExpr) const;

  // RowsetArrayInto is considered a leaf node for cover test.
  virtual void getLeafValuesForCoverTest(ValueIdSet & leafValues, 
                                         const GroupAttributes& coveringGA,
                                         const ValueIdSet & newExternalInputs) const;

  // Return the type of the array elements
  const NAType *getType() const { return hostVarType_; }

  // method to do code generation
  //
  virtual short codeGen(Generator*);

  // get a printable string that identifies the operator
  //
  virtual const NAString getText() const
  {
    return "RowsetArrayInto";
  };

private:
  Lng32         maxNumElem_;      // Maximum number of elements
  Lng32         elemSize_;        // Element storage length in bytes
  NABoolean    elemNullInd_;     // Null Indicator ?
  const NAType *hostVarType_;    // The datatype of the array elements

};


// Class unPackCol ------------------------------------------------
// This built in function is used to 'unpack' the values in a packed
// row.
//
class UnPackCol : public BuiltinFunction
{
public:
  UnPackCol(ItemExpr *source,
	    ItemExpr *index,
	    Lng32 width,
	    Lng32 base,
	    NABoolean nullsPresent,
	    const NAType *type,
	    OperatorTypeEnum opType = ITM_UNPACKCOL)
    : BuiltinFunction(opType, CmpCommon::statementHeap(), 2, source, index),
      width_(width),
      base_(base),
      nullsPresent_(nullsPresent),
      type_(type)
  {
  };

  // virtual destructor
  virtual ~UnPackCol();

  // Return the type of the original unpacked column.
  //
  const NAType *getType() const { return type_; }

  // a virtual function for type propagating the node
  //
  virtual const NAType * synthesizeType();

  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
				 CollHeap* outHeap = 0);
  // method to do code generation
  //
  virtual short codeGen(Generator*);

  // get a printable string that identifies the operator
  //
  virtual const NAString getText() const
  {
    return "UnPackCol";
  };

  // UnPackCol behaves like an Aggregate, which is NOT covered even if its
  // children are.
  virtual NABoolean isCovered(const ValueIdSet& newExternalInputs,
                              const GroupAttributes& newRelExprAnchorGA,
                              ValueIdSet& referencedInputs,
                              ValueIdSet& coveredSubExpr,
                              ValueIdSet& unCoveredExpr) const;

  // UnPackCol is considered a leaf node for cover test.
  virtual void getLeafValuesForCoverTest(ValueIdSet & leafValues, 
                                         const GroupAttributes& coveringGA,
                                         const ValueIdSet & newExternalInputs) const;

private:
  // The width of the packed column in bits.
  //
  Lng32 width_;

  // The base offset of the packed data in bytes.
  //
  Lng32 base_;

  // If TRUE, then a null bitmap is present in the packed row.
  //
  NABoolean nullsPresent_;

  // The datatype of the original unpacked column.
  //
  const NAType *type_;

}; // class UnPackCol

// Function to generate a random 32 bit unsigned integer.  Each
// instance of this function maintains a seed internally, which gets
// automatically set to a random value the first time the function is
// called.  In the future there may be a requirement to allow the
// caller to manage the seed, but for now this simpler approach of
// having the callee do it is sufficient.
// The future is here: adding support for user specified seed.
//
class RandomNum : public BuiltinFunction
{
public:
  RandomNum(ItemExpr * seed = NULL, NABoolean simpleRandom = FALSE) 
       : BuiltinFunction(ITM_RANDOMNUM, CmpCommon::statementHeap(), 1, seed),
	 simpleRandom_(simpleRandom)
         { allowsSQLnullArg() = FALSE; }

  virtual ~RandomNum();

  virtual Int32 getArity() const { return (child(0) ? 1 : 0); };

  virtual const NAType * synthesizeType();

  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
				 CollHeap* outHeap = 0);

  virtual ItemExpr * preCodeGen(Generator*);

  virtual short codeGen(Generator*);

  virtual RandomNum *castToRandomNum() { return this; }

private:
  NABoolean simpleRandom_;
}; // class RandomNum

// Function to right/left shift a 32 or 64 bit integer.
//
class Shift : public BuiltinFunction
{
public:
  Shift(OperatorTypeEnum otype, // ITM_SHIFT_RIGHT || ITM_SHIFT_LEFT
        ItemExpr *child0,
        ItemExpr *child1)
    : BuiltinFunction(otype, CmpCommon::statementHeap(), 2, child0, child1) {}

  virtual ~Shift();

  virtual const NAType * synthesizeType();

  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
				 CollHeap* outHeap = 0);

  virtual short codeGen(Generator*);

  // get a printable string that identifies the operator
  virtual const NAString getText() const
  {
    switch(getOperatorType())
      {
      case ITM_SHIFT_RIGHT:
	return "Right Shift";
      case ITM_SHIFT_LEFT:
	return "Left Shift";
      default:
	return "Unknown Shift Operation";
      }
  };

}; // class Shift

// InternalTimestamp is a version of CurrentTimestamp that is evaluated
// again on every call
class InternalTimestamp : public BuiltinFunction
{
public:
  InternalTimestamp(): BuiltinFunction(ITM_INTERNALTIMESTAMP) {}

  // virtual destructor
  virtual ~InternalTimestamp();

  // a virtual function for type propagating the node
  virtual const NAType * synthesizeType();

  virtual NABoolean isCovered(const ValueIdSet& newExternalInputs,
			      const GroupAttributes& newRelExprAnchorGA,
	   	              ValueIdSet& referencedInputs,
			      ValueIdSet& coveredSubExpr,
			      ValueIdSet& unCoveredExpr) const
  { return TRUE; };

  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
				 CollHeap* outHeap = 0);


}; // class InternalTimestamp

// Function to mask (clear, set) bits in a 32 or 64 bit integer.
//
class Mask : public BuiltinFunction
{
public:
  Mask(OperatorTypeEnum otype,
       ItemExpr *child0,
       ItemExpr *child1)
    : BuiltinFunction(otype, CmpCommon::statementHeap(), 2, child0, child1) {}

  virtual ~Mask();

  virtual const NAType * synthesizeType();

  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
				 CollHeap* outHeap = 0);

  virtual short codeGen(Generator*);

  // get a printable string that identifies the operator
  virtual const NAString getText() const
  {
    switch(getOperatorType())
      {
      case ITM_MASK_SET:
	return "Mask Set";
      case ITM_MASK_CLEAR:
	return "Mask Clear";
      default:
	return "Unknown Mask Operation";
      }
  };

}; // class Mask

// -----------------------------------------------------------------------
// PackFunc is a built-in function to support packing (of multiple rows
// into one row). It takes two parameters. One is an ItemExpr specifying
// the row to be packed. The other is the packing factor which says how
// many rows are to be packed into one row.
// -----------------------------------------------------------------------
class PackFunc : public BuiltinFunction
{
  // ITM_PACK_FUNC
public:

  // Constructor.
  PackFunc(ItemExpr* val1Ptr, ItemExpr* pf)
   : BuiltinFunction(ITM_PACK_FUNC,CmpCommon::statementHeap(),2,val1Ptr,pf),
     isFormatInfoValid_(FALSE)                                          {}

  // This constructor is used when format is predetermined.
  PackFunc(ItemExpr* val1Ptr,
           ItemExpr* pf,
           Lng32 base,
           Lng32 width,
           NABoolean nullsPresent);

  // The type given is the type of one logical row before packing is done.
  PackFunc(ItemExpr* val1Ptr,
           ItemExpr* pf,
           const NAType* unpackType);

  // Destructor.
  virtual ~PackFunc();

  // Allow setting and clearing of format information after construction.
  void setFormatInfo(Lng32 base,
                     Lng32 width,
                     NABoolean nullsPresent,
                     const NAType* type)
  {
    base_ = base;
    width_ = width;
    nullsPresent_ = nullsPresent,
    type_ = type;
    isFormatInfoValid_ = TRUE;
  }

  void clearFormatInfo()                   { isFormatInfoValid_ = FALSE; }

  // Derive type from base, width and nullsPresent information.
  void deriveTypeFromFormatInfo();

  // Derive type, base, width and nullsPresent information from unpack type.
  void deriveFormatInfoFromUnpackType(const NAType* unpackType);

  // Needn't refine bindNode(). Default suffice. Refine synthesizeType().
  virtual const NAType* synthesizeType();

  // Transform node eliminates subqueries from the expression trees.
  // virtual void transformNode(NormWA& normWARef,
  //                         ExprValueId& locationOfPointerToMe,
  //                         ExprGroupId& introduceSemiJoinHere,
  //                         const ValueIdSet& externalInputs);

  // Normalize node rewrites some sub-expressions into VEGRef.
  // virtual ItemExpr* normalizeNode(NormWA& normWARef);

  // PackFunc behaves like an Aggregate, which is NOT covered even if its
  // children are.
  virtual NABoolean isCovered(const ValueIdSet& newExternalInputs,
			      const GroupAttributes& newRelExprAnchorGA,
	   	              ValueIdSet& referencedInputs,
			      ValueIdSet& coveredSubExpr,
			      ValueIdSet& unCoveredExpr) const;

  virtual void getLeafValuesForCoverTest(ValueIdSet & leafValues, 
                                         const GroupAttributes& coveringGA,
                                         const ValueIdSet & newExternalInputs) const;
  // Code Generation.
  virtual short codeGen(Generator*);

  // Make a copy of the operator.
  virtual ItemExpr* copyTopNode(ItemExpr* derivedNode = NULL,
                                 CollHeap* outHeap = 0);
private:

  // Whether the format information below are valid or not. If not, PackFunc
  // will compute these information based on its first operand.
  NABoolean isFormatInfoValid_;

  // Offset of where packed data begin.
  Lng32 base_;

  // Width of one logical row. Negative means bits; Positive means bytes.
  Lng32 width_;

  // Whether the null bit map is going to be present in the packed record.
  NABoolean nullsPresent_;

  // Type of logical row stored.
  const NAType* type_;

}; // class PackFunc

///////////////////////////////////////////////////////////////////
// This function only exists upto the bindNode phase.
// The bindNode method returns a new tree depending on
// the oper. This new tree uses the existing operators to
// perform this function. Some of this kind of transformation
// could and is done in the parser. But for complicated expressions
// it is easier to use Parser::parseDML method as an internal
// expression by passing it a string instead of creating the
// complicated tree in the parser. The parseDML could not be called
// from the parser since it in not a reentrant code (parser uses
// globals).
///////////////////////////////////////////////////////////////////
class ZZZBinderFunction : public BuiltinFunction
{
public:
  ZZZBinderFunction(OperatorTypeEnum oper,
		    ItemExpr *val1Ptr = NULL, ItemExpr *val2Ptr = NULL,
		    ItemExpr *val3Ptr = NULL, ItemExpr *val4Ptr = NULL,
		    ItemExpr *val5Ptr = NULL)
       : BuiltinFunction(oper, CmpCommon::statementHeap(), 5,
			 val1Ptr, val2Ptr, val3Ptr, val4Ptr, val5Ptr) {}

  // a virtual function for performing name binding within the query tree
  virtual ItemExpr * bindNode(BindWA *bindWA);
  
  // helper function used by bindNode; returns true if there is an error
  bool enforceDateOrTimestampDatatype(BindWA *bindWA, CollIndex child, int operand);

  // the synthesizeType method is needed only when we process an item
  // expression at DDL time, for DML the function gets transformed into
  // another function before we reach type synthesis
  virtual const NAType * synthesizeType();

  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
                                 CollHeap* outHeap = 0);

  // No transformation for this node. Raise an error, if transformation
  // is reached. This is the next step after bindNode.
  virtual void transformNode(NormWA & normWARef,
			     ExprValueId & locationOfPointerToMe,
                             ExprGroupId & introduceSemiJoinHere,
			     const ValueIdSet & externalInputs);
  
  Int32 getPadLength (ItemExpr* padLengthExpr, BindWA* bindWA);
  Int32 getPadStringLength (ItemExpr* padLengthExpr, BindWA* bindWA);
  NABoolean isPadWithSpace (ExprValueId& padExpr, CharInfo::CharSet cs);

  static ItemExpr *tryToUndoBindTransformation(ItemExpr *expr);

};

// --------------------------------------------------------------------------
//
// Sequence functions. These perform running and moving aggregates
// based on a defined sort order
//
// --------------------------------------------------------------------------
// Sequence function base class
//
// Allows for up to 3 function arguments.
// --------------------------------------------------------------------------
//
class ItmSequenceFunction : public BuiltinFunction
{
public:
  ItmSequenceFunction(OperatorTypeEnum itemType, ItemExpr *val1Ptr, ItemExpr *val2Ptr=NULL, ItemExpr *val3Ptr=NULL)
    : BuiltinFunction(itemType, CmpCommon::statementHeap(),
                      3, val1Ptr, val2Ptr, val3Ptr),
      isOLAP_(FALSE),
      olapPartitionBy_(NULL),
      olapOrderBy_(NULL),
      isTDFunction_(FALSE)
      {  }

  // virtual destructor
  virtual ~ItmSequenceFunction();

  // get a printable string that identifies the operator
  virtual const NAString getText() const;

  // a virtual function for performing name binding within the query tree
  virtual ItemExpr * bindNode(BindWA *bindWA);

  // method to do precode generation
  // virtual ItemExpr * preCodeGen(Generator*);

  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
                                 CollHeap* outHeap = 0);

  virtual  NABoolean isASequenceFunction() const ;  // virtual method
  virtual NABoolean containsTHISFunction();

  //  Sequence functions behave like an Aggregate, which is NOT covered even if its
  // children are.
  virtual NABoolean isCovered(const ValueIdSet& newExternalInputs,
                              const GroupAttributes& newRelExprAnchorGA,
                              ValueIdSet& referencedInputs,
                              ValueIdSet& coveredSubExpr,
                              ValueIdSet& unCoveredExpr) const;

  // A sequence function is considered a leaf node for cover test.
  virtual void getLeafValuesForCoverTest(ValueIdSet & leafValues, 
                                         const GroupAttributes& coveringGA,
                                         const ValueIdSet & newExternalInputs) const;

  virtual NABoolean calculateMinMaxUecs(ColStatDescList & histograms,
					       CostScalar & minUec,
					       CostScalar & maxUec);

  NABoolean isOLAP() { return isOLAP_; };
  void setIsOLAP( NABoolean v ) { isOLAP_ = v; }

  void setOlapPartitionBy(ItemExpr *partBy) { olapPartitionBy_ = partBy;};

  ItemExpr *getOlapPartitionBy() { return olapPartitionBy_; };
  ItemExpr *removeOlapPartitionBy()
  {
    ItemExpr *partBy = olapPartitionBy_;
    olapPartitionBy_ = NULL;
    return partBy;
  };

  void setOlapOrderBy(ItemExpr *orderBy) { olapOrderBy_ = orderBy;};

  ItemExpr *getOlapOrderBy() { return olapOrderBy_; };
  ItemExpr *removeOlapOrderBy()
  {
    ItemExpr *orderBy = olapOrderBy_;
    olapOrderBy_ = NULL;
    return orderBy;
  };

  void setOLAPInfo(ItemExpr *partBy, 
                   ItemExpr *orderBy,                   
                   NABoolean isTDFunction=FALSE)
  {
    olapPartitionBy_ = partBy;
    olapOrderBy_ = orderBy;

    // default is that the isOLAP flag is ON here unless
    // its a TD function, then its OFF
    isOLAP_ = (isTDFunction) ? FALSE : TRUE;

    isTDFunction_ = isTDFunction;    
  };

  NABoolean isTDFunction() { return isTDFunction_; };
  void setIsTDFunction( NABoolean v ) { isTDFunction_ = v; }

  ItemExpr * transformTDFunction(BindWA * bindWA);
  NABoolean isEquivalentForBinding(const ItemExpr * other);

  virtual QR::ExprElement getQRExprElem() const 
  {
    return QR::QRFunctionWithParameters;
  }

private:
  // OLAP Info
  NABoolean isOLAP_;
  ItemExpr *olapPartitionBy_;
  ItemExpr *olapOrderBy_;
  NABoolean isTDFunction_;
} ;

//------------------------------------------------------------------------
// Running function class.
//
//------------------------------------------------------------------------
//
class ItmSeqRunningFunction : public ItmSequenceFunction
{
public:
  ItmSeqRunningFunction(OperatorTypeEnum itemType, ItemExpr *valPtr)
         : ItmSequenceFunction(itemType, valPtr)
         {  }

  // virtual destructor
  virtual ~ItmSeqRunningFunction();

  // methods for code generation
  virtual ItemExpr *preCodeGen(Generator*);
  virtual short codeGen(Generator*);

  // method to do precode generation
  // virtual ItemExpr * preCodeGen(Generator*);

  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
                                 CollHeap* outHeap = 0);

 void transformNode(NormWA & normWARef,
               ExprValueId & locationOfPointerToMe,
               ExprGroupId & introduceSemiJoinHere,
               const ValueIdSet & externalInputs);


  // a virtual function for type propagating the node
  virtual const NAType * synthesizeType();

 ItemExpr *transformRunningVariance();
 ItemExpr *transformRunningSDev();
 ItemExpr *transformRunningAvg();
 ItemExpr *transformRunningRank();

 virtual NABoolean hasEquivalentProperties(ItemExpr * other) { return TRUE;}
  
} ;
//------------------------------------------------------------------------
// Olap function class.
//
//------------------------------------------------------------------------
//
class ItmSeqOlapFunction : public ItmSequenceFunction
{
public:
  ItmSeqOlapFunction(OperatorTypeEnum itemType, ItemExpr *val1Ptr, ItemExpr *val2Ptr = NULL, ItemExpr *val3Ptr = NULL): 
        ItmSequenceFunction(itemType, val1Ptr, val2Ptr, val3Ptr),
        frameStart_(0),
        frameEnd_(0)
        {  }

  // virtual destructor
  virtual ~ItmSeqOlapFunction();

  // methods for code generation
  virtual ItemExpr *preCodeGen(Generator*);  //transfomr into running seq functions
  //virtual short codeGen(Generator*);

  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
                                 CollHeap* outHeap = 0);
  OperatorTypeEnum mapOperTypeToRunning() const;
  OperatorTypeEnum mapOperTypeToMoving() const;

  void transformNode(NormWA & normWARef,
               ExprValueId & locationOfPointerToMe,
               ExprGroupId & introduceSemiJoinHere,
               const ValueIdSet & externalInputs);

  ItemExpr *transformOlapVariance(CollHeap *heap);
  ItemExpr *transformOlapSDev(CollHeap *heap);
  ItemExpr *transformOlapAvg(CollHeap *heap);
  ItemExpr *transformOlapRank(CollHeap *heap);
  ItemExpr *transformOlapDRank(CollHeap *heap);
  virtual ItemExpr *transformOlapFunction(CollHeap *heap);

  virtual NABoolean hasEquivalentProperties(ItemExpr * other);

  // a virtual function for type propagating the node
  virtual const NAType * synthesizeType();


  Lng32 getframeStart()
  {
    return frameStart_;
  }

  Lng32 getframeEnd()
  {
    return frameEnd_;
  }

  void setframeStart(Lng32 v)
  {
    frameStart_=v;
  }

  void setframeEnd(Lng32 v)
  {
    frameEnd_=v;
  }

  void setOlapWindowFrame(Lng32 s, Lng32 e)
  {
    frameStart_ = s;
    frameEnd_ = e;
  }

  NABoolean isFrameStartUnboundedPreceding() const
  {
    return (frameStart_ == -INT_MAX);
  }

   NABoolean isFrameStartUnboundedFollowing() const
  {
    return (frameStart_ == INT_MAX);
  }
  NABoolean isFrameEndUnboundedPreceding() const
  {
    return (frameEnd_ == -INT_MAX);
  }

  NABoolean isFrameEndUnboundedFollowing() const
  {
    return (frameEnd_ == INT_MAX);
  }


  virtual  NABoolean isOlapFunction() const ;  // virtual method
  inline NABoolean
  canInverseOLAPOrder()
  {
    return !(frameStart_ == -INT_MAX &&
              frameEnd_ != INT_MAX &&
              (getOperatorType() == ITM_OLAP_MIN || 
               getOperatorType() == ITM_OLAP_MAX) ||
             getOperatorType() == ITM_OLAP_RANK ||
             getOperatorType() == ITM_OLAP_DRANK);

  }

  inline NABoolean
  mustInverseOLAPOrder()
  {
    return (frameStart_ != -INT_MAX &&
            frameEnd_ == INT_MAX &&
            (getOperatorType() == ITM_OLAP_MIN || getOperatorType() == ITM_OLAP_MAX));
  }

  NABoolean
  inverseOLAPOrder(CollHeap *heap);

private:
  //olap window frame -- start and end-- 
  // will add patition and order by here too later and remove them from ItemSequenceFunction
  //
  Lng32 frameStart_;
  Lng32 frameEnd_;
} ;

class ItmLeadOlapFunction: public ItmSeqOlapFunction 
{
public:
  ItmLeadOlapFunction(ItemExpr *valPtr, ItemExpr* offsetExpr = NULL, ItemExpr* defaultValue = NULL): 
        ItmSeqOlapFunction(ITM_OLAP_LEAD, valPtr, offsetExpr, defaultValue),
        offset_(-1)
        { }

  ItmLeadOlapFunction(ItemExpr *valPtr, Int32 offset): 
        ItmSeqOlapFunction(ITM_OLAP_LEAD, valPtr),
        offset_(offset)
        { }

  // virtual destructor
  virtual ~ItmLeadOlapFunction();

  // methods for code generation
  virtual ItemExpr *preCodeGen(Generator*);  //transfomr into running seq functions
  virtual short codeGen(Generator*);

  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
                                 CollHeap* outHeap = 0);

  virtual NABoolean hasEquivalentProperties(ItemExpr * other);

  // a virtual function for type propagating the node
  virtual const NAType * synthesizeType();

  virtual  NABoolean isOlapFunction() const { return TRUE; } ;  // virtual method

  Int32  getOffset() { return offset_; };
  void setOffset(Int32 x) { offset_ = x; };

  ItemExpr* transformOlapFunction(CollHeap *wHeap);

  void transformNode(NormWA & normWARef, 
                     ExprValueId & locationOfPointerToMe,
                     ExprGroupId & introduceSemiJoinHere, 
                     const ValueIdSet & externalInputs);

  // get a printable string that identifies the operator
  virtual const NAString getText() const
    { return "LEAD"; };

private:

   Int32 offset_;
} ;

// ------------------------------------------------------------------------
//
//  OFFSET sequence function.
//
//  OFFSET(x, y) returns SELECT list item x in row at offset (+ or -)
//  y in the sorted sequence.
//
//  Similar to the cursor FETCH RELATIVE operation, except returns
//  result in context of the current row.
// ------------------------------------------------------------------------
//
class ItmSeqOffset : public ItmSequenceFunction
{
public:
  ItmSeqOffset(ItemExpr *val1Ptr, ItemExpr *val2Ptr, ItemExpr *val3Ptr = NULL,
               NABoolean nullRowIsZero = FALSE, NABoolean leading = TRUE, Lng32 winSize = 0)
         : ItmSequenceFunction(ITM_OFFSET, val1Ptr, val2Ptr, val3Ptr),
           nullRowIsZero_(nullRowIsZero),
           offsetConstantValue_ (0),
           leading_(leading),
           winSize_(winSize)
  { allowsSQLnullArg() = FALSE; }

  ItmSeqOffset(ItemExpr *valPtr, 
               Int32 offsetConstantValue,
               NABoolean nullRowIsZero = FALSE,
               NABoolean leading = TRUE,
               Lng32 winSize = 0)
         : ItmSequenceFunction(ITM_OFFSET, valPtr),
           nullRowIsZero_(nullRowIsZero),
           offsetConstantValue_ (offsetConstantValue),
           leading_(leading),
           winSize_(winSize)
  { allowsSQLnullArg() = FALSE; }

  // virtual destructor
  virtual ~ItmSeqOffset();

  // methods to do code generation
  virtual ItemExpr *preCodeGen(Generator*);
  virtual short codeGen(Generator*);

  // a virtual function for type propagating the node
  virtual const NAType * synthesizeType();


  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
                                 CollHeap* outHeap = 0);

  void transformNode(NormWA & normWARef,
                    ExprValueId & locationOfPointerToMe,
                    ExprGroupId & introduceSemiJoinHere,
                    const ValueIdSet & externalInputs);

  // get the degree of this node. Although it is a binary op, this will return 1 if offset value was
  // set via constant below.

  virtual Int32 getArity() const;

  NABoolean nullRowIsZero() const {return nullRowIsZero_;}

  void setNullRowIsZero(NABoolean b) {nullRowIsZero_ = b;}

  //
  Int32 getOffsetConstantValue () const { return  offsetConstantValue_; }

  NABoolean isLeading() const {return leading_;}
  Lng32 winSize() const {return winSize_;}

  virtual NABoolean hasEquivalentProperties(ItemExpr * other);
  
private:
  NABoolean nullRowIsZero_;
  Int32 offsetConstantValue_;
  NABoolean leading_;
  Lng32 winSize_;

}; // class ItmSeqOffset

class ItmLagOlapFunction: public ItmSeqOlapFunction 
{
public:
  ItmLagOlapFunction(ItemExpr *seqColumn, ItemExpr *offsetExpr, ItemExpr* defaultValue = NULL)
         : ItmSeqOlapFunction(ITM_OLAP_LAG, seqColumn, offsetExpr, defaultValue)
         {}

  // virtual destructor
  virtual ~ItmLagOlapFunction(){}
  // methods to do code generation
  virtual ItemExpr *preCodeGen(Generator*);
  virtual short codeGen(Generator*);

  // a virtual function for type propagating the node
  virtual const NAType * synthesizeType();
  
  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL, CollHeap* outHeap = 0);
  
  void transformNode(NormWA & normWARef,
                ExprValueId & locationOfPointerToMe,
                ExprGroupId & introduceSemiJoinHere,
                const ValueIdSet & externalInputs);
	
  virtual  NABoolean isOlapFunction() const { return TRUE; }

  ItemExpr * transformOlapFunction(CollHeap *heap) { return this; }
  // get a printable string that identifies the operator
  virtual const NAString getText() const    { return "LAG"; };
};


// --------------------------------------------------------------------------
//
//  DIFF1 sequence function.
//
//  This function has both 1-parameter and two-parameter forms:
//  DIFF1(x) is equivalent to:  x-OFFSET(x, 1)
//  DIFF1(x, y) is equivalent to:  (x-OFFSET(x, 1)) / (y-OFFSET (y, 1)
//
// --------------------------------------------------------------------------
//
class ItmSeqDiff1 : public ItmSequenceFunction
{
public:
  ItmSeqDiff1(ItemExpr *valPtr1, ItemExpr *valPtr2 = NULL)
         : ItmSequenceFunction(ITM_DIFF1, valPtr1, valPtr2)
  { allowsSQLnullArg() = FALSE; }

  // virtual destructor
  virtual ~ItmSeqDiff1();

  // method to do code generation
  virtual short codeGen(Generator*);

  // a virtual function for type propagating the node
  virtual const NAType * synthesizeType();

  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
                                 CollHeap* outHeap = 0);

  ItemExpr *transformDiff1();

 void transformNode(NormWA & normWARef,
                    ExprValueId & locationOfPointerToMe,
                    ExprGroupId & introduceSemiJoinHere,
                    const ValueIdSet & externalInputs);


private:

}; // class ItmSeqDiff1

// --------------------------------------------------------------------------
//
//  DIFF2 sequence function.
//
//  This function has both 1-parameter and two-parameter forms:
//  Diff2(x) is equivalent to:  DIFF1(DIFF1(x))
//  Diff2(x, y) is equivalent to:  DIFF1(DIFF1(x))/ DIFF1(DIFF1(y))
// --------------------------------------------------------------------------
//
class ItmSeqDiff2 : public ItmSequenceFunction
{
public:
  ItmSeqDiff2(ItemExpr *valPtr1, ItemExpr *valPtr2 = NULL)
         : ItmSequenceFunction(ITM_DIFF2, valPtr1, valPtr2)
  { allowsSQLnullArg() = FALSE; }

  // virtual destructor
  virtual ~ItmSeqDiff2();

  // method to do code generation
  virtual short codeGen(Generator*);

  // a virtual function for type propagating the node
  virtual const NAType * synthesizeType();

  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
                                 CollHeap* outHeap = 0);

 ItemExpr *transformDiff2();

 void transformNode(NormWA & normWARef,
               ExprValueId & locationOfPointerToMe,
               ExprGroupId & introduceSemiJoinHere,
               const ValueIdSet & externalInputs);


private:

}; // class ItmSeqDiff2

// --------------------------------------------------------------------------
//
//  ROWS SINCE sequence function.
//
//  This function has two forms:
//  ROWS SINCE <condition>
//  ROWS SINCE <condition> INCLUSIVE
//
//  The <condition> is similar to CASE WHEN <condition>
// --------------------------------------------------------------------------
//
class ItmSeqRowsSince : public ItmSequenceFunction
{
public:
  ItmSeqRowsSince(ItemExpr *valPtr, ItemExpr *valPtr2 = NULL, NABoolean inclusionSpec = FALSE)
         : ItmSequenceFunction(ITM_ROWS_SINCE, valPtr, valPtr2),
         includeCurrentRow_ (inclusionSpec)
  { allowsSQLnullArg() = FALSE; }

  // virtual destructor
  virtual ~ItmSeqRowsSince();

  // methods for code generation
  virtual ItemExpr *preCodeGen(Generator*);
  virtual short codeGen(Generator*);

  // a virtual function for type propagating the node
  virtual const NAType * synthesizeType();

  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
                                 CollHeap* outHeap = 0);

  // get a printable string that identifies the operator
  virtual const NAString getText() const;

  virtual void transformNode(NormWA & normWARef,
                    ExprValueId & locationOfPointerToMe,
                    ExprGroupId & introduceSemiJoinHere,
                    const ValueIdSet & externalInputs);

  NABoolean includeCurrentRow() const { return includeCurrentRow_; }

private:

  NABoolean includeCurrentRow_;

}; // class ItmSeqRowsSince

//------------------------------------------------------------------------
// Moving function class.
//
//------------------------------------------------------------------------
//
class ItmSeqMovingFunction : public ItmSequenceFunction
{
public:
  ItmSeqMovingFunction (OperatorTypeEnum itemType,
                        ItemExpr *valPtr1, ItemExpr *valPtr2, ItemExpr *valPtr3 = NULL)
         : ItmSequenceFunction(itemType, valPtr1, valPtr2, valPtr3),
         skipMovingMinMaxTransformation_(FALSE)
  { allowsSQLnullArg() = FALSE; }

  // virtual destructor
  virtual ~ItmSeqMovingFunction();

  // method to do code generation
  virtual short codeGen(Generator*);

  // method to do precode generation
  virtual ItemExpr * preCodeGen(Generator*);

  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
                                 CollHeap* outHeap = 0);

 void transformNode(NormWA & normWARef,
               ExprValueId & locationOfPointerToMe,
               ExprGroupId & introduceSemiJoinHere,
               const ValueIdSet & externalInputs);


  // a virtual function for type propagating the node
  virtual const NAType * synthesizeType();
  virtual NABoolean hasEquivalentProperties(ItemExpr * other);

private:                               // the following are invoked only from within transformNode()

 ItemExpr *transformMovingVariance();
 ItemExpr *transformMovingSDev();
 ItemExpr *transformMovingAvg();
 ItemExpr *transformMovingSum();
 ItemExpr *transformMovingCount();
 ItemExpr *transformMovingMinMax();
 ItemExpr *transformMovingRank();

  // the following are used only in transformNode() for MovingMin/Max
  NABoolean skipMovingMinMaxTransformation_;
  NABoolean getSkipMovingMinMaxTransformation() { return skipMovingMinMaxTransformation_; }
  void setSkipMovingMinMaxTransformation() { skipMovingMinMaxTransformation_ = TRUE; }

} ;  // class ItmSeqMovingFunction

//------------------------------------------------------------------------
// Function class for sequence function THIS().
//
//------------------------------------------------------------------------
//
class ItmSeqThisFunction : public ItmSequenceFunction
{
public:
  ItmSeqThisFunction(ItemExpr *valPtr)
         : ItmSequenceFunction(ITM_THIS, valPtr)
         {  }
  // virtual destructor

  virtual ~ItmSeqThisFunction();

  // method to do code generation
  virtual short codeGen(Generator*);

  // method to do precode generation
  virtual ItemExpr * preCodeGen(Generator*);

  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
                                 CollHeap* outHeap = 0);

  // a virtual function for type propagating the node
  virtual const NAType * synthesizeType();
} ;     // class ItmSeqThisFunction

//------------------------------------------------------------------------
// Function class for ItmScalarMinMax.
//
// This node represends the traditional min/max functions of the form:
//
// SCALAR_MIN(A,B) : CASE WHEN (A < B) THEN A ELSE B
// SCALAR_MAX(A,B) : CASE WHEN (A > B) THEN A ELSE B
//------------------------------------------------------------------------
//
class ItmScalarMinMax : public BuiltinFunction
{
public:
  ItmScalarMinMax (OperatorTypeEnum opType, ItemExpr *val1Ptr, ItemExpr *val2Ptr)
    : BuiltinFunction(opType, CmpCommon::statementHeap(), 2, val1Ptr, val2Ptr)
    { allowsSQLnullArg() = FALSE; }

  // virtual destructor
  virtual ~ItmScalarMinMax();

  // a virtual function for type propagating the node
  virtual const NAType * synthesizeType();

  // A transformation method for protecting sequence functions from not
  // being evaluated due to short-circuit evaluation.
  //
  virtual void protectiveSequenceFunctionTransformation(Generator *generator);

  // method to do code generation
  virtual short codeGen(Generator*);

  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
                                 CollHeap* outHeap = 0);

}; // class ItmScalarMinMax

//------------------------------------------------------------------------
// Function class for sequence function NotTHIS().
// Merely a No-op wrapper used during tranformation
//  to indicate that no THIS function occurs
// below this point.
//------------------------------------------------------------------------
//
class ItmSeqNotTHISFunction : public ItmSequenceFunction
{
public:
  ItmSeqNotTHISFunction(ItemExpr *valPtr)
         : ItmSequenceFunction(ITM_NOT_THIS, valPtr)
         {  }
  // virtual destructor

  virtual ~ItmSeqNotTHISFunction();

  // a virtual function for type propagating the node
  virtual const NAType * synthesizeType();

  // method to do code generation
  virtual short codeGen(Generator*);

  // method to do precode generation
  virtual ItemExpr * preCodeGen(Generator*);

  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
                                 CollHeap* outHeap = 0);

} ;     // class ItmSeqNotTHISFunction

// lookup a column in a native hbase table that is being accessed in row format
class HbaseColumnLookup : public BuiltinFunction
{
public:
  HbaseColumnLookup(
       ItemExpr *child0,
       NAString &hbaseCol,
       const NAType * naType = NULL)
    : BuiltinFunction(ITM_HBASE_COLUMN_LOOKUP, 
		      CmpCommon::statementHeap(), 1, child0),
    hbaseCol_(hbaseCol),
    naType_(naType)
    {}

  virtual ~HbaseColumnLookup();

  virtual const NAType * synthesizeType();

  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
				 CollHeap* outHeap = 0);

  ItemExpr *bindNode(BindWA *bindWA);

  virtual short codeGen(Generator*);

  const NAType * naType() { return naType_; }
  NAString &hbaseCol() { return hbaseCol_; }

  // get a printable string that identifies the operator
  virtual const NAString getText() const
  {
    return "HBASE_COLUMN_LOOKUP";
  };

 private:
  NAString hbaseCol_;
  const NAType *naType_;
}; // class HbaseColumnLookup

// format hbase columns that are being accessed to be displayed
class HbaseColumnsDisplay : public BuiltinFunction
{
public:
  HbaseColumnsDisplay(
		      ItemExpr *child0,
		      ConstStringList * csl = NULL,
		      Lng32 displayWidth = 100000)
    : BuiltinFunction(ITM_HBASE_COLUMNS_DISPLAY, 
		      CmpCommon::statementHeap(), 1, child0),
    csl_(csl),
    displayWidth_(displayWidth)
    {}

  virtual ~HbaseColumnsDisplay();

  virtual const NAType * synthesizeType();

  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
				 CollHeap* outHeap = 0);

  ItemExpr *bindNode(BindWA *bindWA);

  virtual short codeGen(Generator*);

  // get a printable string that identifies the operator
  virtual const NAString getText() const
  {
    return "HBASE_COLUMNS_DISPLAY";
  };

  ConstStringList* &csl() { return csl_; }

 private:
 ConstStringList * csl_;

  Lng32 displayWidth_;
}; // class HbaseColumnsDisplay

// create a column to update/insert into an hbase native table
class HbaseColumnCreate : public BuiltinFunction
{
public:
  class HbaseColumnCreateOptions
  {
    friend class HbaseColumnCreate;
  public:
    enum ConvType
    {
      CAST_AS,
      TYPE_AS,
      NONE
    };
    
    HbaseColumnCreateOptions
      (ItemExpr * colName,
       ItemExpr * colVal,
       const NAType * naType,
       ConvType convType) 
      : colName_(colName),
      colVal_(colVal),
      naType_(naType),
      convType_(convType)
      {}

    const NAType * naType() { return naType_;}
    ConvType convType() { return convType_;}
    ItemExpr * colName() { return colName_; }
    ItemExpr * colVal() { return colVal_; }
    void setColName(ItemExpr * c) { colName_ = c; }
    void setColVal(ItemExpr * c) { colVal_ = c; }
    ItemExpr * colNameIE() { return colNameIE_; }
    void setColNameIE(ItemExpr * cn) { colNameIE_ = cn; }

  private:
    ItemExpr * colNameIE_;
    ItemExpr * colName_;
    ItemExpr * colVal_;
    const NAType * naType_;
    ConvType convType_;

  };

  HbaseColumnCreate(
		    NAList<HbaseColumnCreateOptions*> * hccol)		    
    : BuiltinFunction(ITM_HBASE_COLUMN_CREATE, 
		      CmpCommon::statementHeap(), 0, NULL),
    resultType_(NULL),
    hccol_(hccol),
    colNameMaxLen_(0),
    colValMaxLen_(0)
    {}

  virtual ~HbaseColumnCreate();

  virtual const NAType * synthesizeType();

  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
				 CollHeap* outHeap = 0);

  // a virtual function for performing name binding within the query tree
  virtual ItemExpr * bindNode(BindWA *bindWA);

  virtual short codeGen(Generator*);

  // get a printable string that identifies the operator
  virtual const NAString getText() const
  {
    return "HBASE_COLUMN_CREATE";
  };

  NABoolean createListSpecified() { return (hccol_ != NULL); };

 private:
  NAString hbaseCol_;
  const NAType *resultType_;

  short colNameMaxLen_;
  Int32 colValMaxLen_;

  NAList<HbaseColumnCreateOptions*> * hccol_;
}; // class HbaseColumnCreate

class HbaseTimestamp : public BuiltinFunction
{
public:
 HbaseTimestamp(ItemExpr * col)
   : BuiltinFunction(ITM_HBASE_TIMESTAMP,
                     CmpCommon::statementHeap(), 1, NULL),
    col_(col),
    tsVals_(NULL),
    colIndex_(-1)
    {}
  
  virtual ~HbaseTimestamp();
  
  virtual NABoolean isCovered
    (const ValueIdSet& newExternalInputs,
     const GroupAttributes& coveringGA,
     ValueIdSet& referencedInputs,
     ValueIdSet& coveredSubExpr,
     ValueIdSet& unCoveredExpr) const;

  virtual Int32 getArity() const { return (child(0) ? 1 : 0); }

  virtual NABoolean isCacheableExpr(CacheWA& cwa)
    { return TRUE; }

  // append an ascii-version of ItemExpr into cachewa.qryText_
  virtual void generateCacheKey(CacheWA& cwa) const;

  virtual const NAType * synthesizeType();
  
  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
				 CollHeap* outHeap = 0);

  ItemExpr *bindNode(BindWA *bindWA);

  virtual ItemExpr * preCodeGen(Generator * generator);

  virtual short codeGen(Generator*);

  // get a printable string that identifies the operator
  virtual const NAString getText() const
  {
    return "HBASE_TIMESTAMP";
  };
  
  void setColIndex(Lng32 idx) { colIndex_ = idx;}
  Lng32 getColIndex() { return colIndex_; }

  const ItemExpr * col() const { return col_; }
  const ItemExpr * tsVals() { return tsVals_; }
 private:
  ItemExpr * col_;
  ItemExpr * tsVals_;

  Lng32 colIndex_;

  NAString colName_;
}; // class HbaseTimestamp

class HbaseTimestampRef : public BuiltinFunction
{
public:
 HbaseTimestampRef(ItemExpr * col)
   : BuiltinFunction(ITM_HBASE_TIMESTAMP_REF,
                     CmpCommon::statementHeap()),
    col_(col)
    {}
  
  virtual ~HbaseTimestampRef();
  
  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
				 CollHeap* outHeap = 0);

  ItemExpr *bindNode(BindWA *bindWA);

  virtual short codeGen(Generator*);

  // get a printable string that identifies the operator
  virtual const NAString getText() const
  {
    return "HBASE_TIMESTAMP_REF";
  };
  
 private:
  ItemExpr * col_;
}; // class HbaseTimestampRef

class HbaseVersion : public BuiltinFunction
{
public:
 HbaseVersion(ItemExpr * col)
   : BuiltinFunction(ITM_HBASE_VERSION,
                     CmpCommon::statementHeap(), 1, NULL),
    col_(col),
    tsVals_(NULL),
    colIndex_(-1)
    {}
  
  virtual ~HbaseVersion();
  
  virtual NABoolean isCovered
    (const ValueIdSet& newExternalInputs,
     const GroupAttributes& coveringGA,
     ValueIdSet& referencedInputs,
     ValueIdSet& coveredSubExpr,
     ValueIdSet& unCoveredExpr) const;

  virtual Int32 getArity() const { return (child(0) ? 1 : 0); }

  virtual NABoolean isCacheableExpr(CacheWA& cwa)
    { return TRUE; }

  // append an ascii-version of ItemExpr into cachewa.qryText_
  virtual void generateCacheKey(CacheWA& cwa) const;

  virtual const NAType * synthesizeType();
  
  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
				 CollHeap* outHeap = 0);

  ItemExpr *bindNode(BindWA *bindWA);

  virtual ItemExpr * preCodeGen(Generator * generator);

  virtual short codeGen(Generator*);

  // get a printable string that identifies the operator
  virtual const NAString getText() const
  {
    return "HBASE_VERSION";
  };
  
  void setColIndex(Lng32 idx) { colIndex_ = idx;}
  Lng32 getColIndex() { return colIndex_; }

  const ItemExpr * col() const { return col_; }
  const ItemExpr * tsVals() { return tsVals_; }
 private:
  ItemExpr * col_;
  ItemExpr * tsVals_;

  Lng32 colIndex_;

  NAString colName_;
}; // class HbaseVersion

class HbaseVersionRef : public BuiltinFunction
{
public:
 HbaseVersionRef(ItemExpr * col)
   : BuiltinFunction(ITM_HBASE_VERSION_REF,
                     CmpCommon::statementHeap()),
    col_(col)
    {}
  
  virtual ~HbaseVersionRef();
  
  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
				 CollHeap* outHeap = 0);

  ItemExpr *bindNode(BindWA *bindWA);

  virtual short codeGen(Generator*);

  // get a printable string that identifies the operator
  virtual const NAString getText() const
  {
    return "HBASE_VERSION_REF";
  };
  
 private:
  ItemExpr * col_;
}; // class HbaseVersionRef

// generate a sequence number in a dml query.
class SequenceValue : public BuiltinFunction
{
public:
  SequenceValue(
		const CorrName &seqCorrName,
		NABoolean currVal = FALSE,
		NABoolean nextVal = TRUE)
    : BuiltinFunction(ITM_SEQUENCE_VALUE,
		      CmpCommon::statementHeap(), 0, NULL),
    seqCorrName_(seqCorrName),
    nextVal_(nextVal),
    currVal_(currVal),
    naTable_(NULL)
    {}

  virtual ~SequenceValue();

  virtual const NAType * synthesizeType();

  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
				 CollHeap* outHeap = 0);

  ItemExpr *bindNode(BindWA *bindWA);

  virtual short codeGen(Generator*);

  // get a printable string that identifies the operator
  virtual const NAString getText() const
  {
    return "SEQUENCE_VALUE";
  };

  CorrName &seqCorrName() { return seqCorrName_; }

  inline const NATable  *getNATable()           const { return naTable_; }
  void setNATable (NATable *naTable) {naTable_ = naTable;}

  virtual NABoolean isCacheableExpr(CacheWA& cwa)
    { return TRUE; }

  // append an ascii-version of ItemExpr into cachewa.qryText_
  virtual void generateCacheKey(CacheWA& cwa) const;

 private:
  CorrName seqCorrName_;
  NABoolean currVal_;
  NABoolean nextVal_;

  // natable for the sequence object
  const NATable *naTable_;

}; // class SequenceValue


// ROWNUM().
// Returns the current number of row being returned to application.
// Starts at 1 and increments after it is returned.
// Can only be used in the outermost select and in the outermost
// where predicate.
class RowNumFunc : public BuiltinFunction
{
public:
  RowNumFunc()
       : BuiltinFunction(ITM_ROWNUM, CmpCommon::statementHeap(),
                         0, NULL) {}

  // virtual destructor
  virtual ~RowNumFunc();

  virtual ItemExpr * bindNode(BindWA *bindWA);
  virtual const NAType * synthesizeType();

  virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
				 CollHeap* outHeap = 0);

  virtual NABoolean isCovered(const ValueIdSet& newExternalInputs,
			      const GroupAttributes& newRelExprAnchorGA,
	   	              ValueIdSet& referencedInputs,
			      ValueIdSet& coveredSubExpr,
			      ValueIdSet& unCoveredExpr) const;

  NABoolean canBeUsedInGBorOB(NABoolean setErr);

}; // class RowNumFunc

class SplitPart : public CacheableBuiltinFunction
{
public: 
  SplitPart(ItemExpr *val1Ptr, ItemExpr *val2Ptr, ItemExpr *val3Ptr)
    :CacheableBuiltinFunction(ITM_SPLIT_PART, 3, val1Ptr, val2Ptr, val3Ptr)
    {
      allowsSQLnullArg() = FALSE;
    } 

   virtual ~SplitPart();

   // a virtual function for type propagating the node
   virtual const NAType * synthesizeType();
   
   virtual ItemExpr * copyTopNode(ItemExpr *derivedNode = NULL,
                      CollHeap *outheap = 0);
   virtual ItemExpr * preCodeGen(Generator*);
}; //class SplitPart

#endif /* ITEMFUNC_H */
