/**********************************************************************
// @@@ 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 @@@
**********************************************************************/
 /* -*-C++-*-
******************************************************************************
*
* File:         ItemExpr.C
* Description:  Item expressions (both physical and logical operators)
* Created:      5/17/94
* Language:     C++
*
*
*
*
******************************************************************************
*/

#define  SQLPARSERGLOBALS_NADEFAULTS
#include "SqlParserGlobals.h"

#include "Platform.h"
#include "Sqlcomp.h"
#include "GroupAttr.h"
#include "AllItemExpr.h"
#include "PartFunc.h"
#include "wstr.h"
#include "NLSConversion.h"
#include "Cost.h"          /* for lookups in the defaults table */
#include "Stats.h"
#include "exp_function.h" // for calling ExHDPHash::hash(data, len)
#include "ItemFuncUDF.h"
#include "CmpStatement.h"
#include "exp_datetime.h"

#include "OptRange.h"

#   include <limits.h>

#include <string.h>			// memcmp


// A constant to be used for allocating a buffer for getText()
#define TEXT_DISPLAY_LENGTH 1001

static NABoolean isQuantifiedComp(const ItemExpr *ie);

#define _strcmpi strcasecmp


// Initialize static members.
//THREAD_P OperatorTypeEnum ItemExpr::origOpTypeBeingBound_ = NO_OPERATOR_TYPE;
//THREAD_P Int32 ItemExpr::origOpTypeCounter_ = 0;

void ItemExpr::cleanupPerStatement()
{ 
  if (CURRENTSTMT)
     CURRENTSTMT->setItemExprOrigOpTypeBeingBound(NO_OPERATOR_TYPE);
}

// -----------------------------------------------------------------------
// methods for class ExprValueId
// -----------------------------------------------------------------------


// Ane ExprValueId can hold either an ItemExpr * or a ValueId.
// If it holds ValueId then the ItemExpr * is NULL.

ExprValueId::ExprValueId()
{
  exprMode_ = STANDALONE;
  exprPtr_  = NULL;
  exprId_   = NULL_VALUE_ID;
}

ExprValueId::ExprValueId(const ExprValueId &other)
{
  exprMode_ = other.exprMode_;
  exprId_   = other.exprId_;
  exprPtr_  = other.exprPtr_;

  if (exprId_ != NULL_VALUE_ID)
    exprPtr_  = NULL;
}

ExprValueId::ExprValueId(ItemExpr * exprPtr)
{
  exprMode_ = STANDALONE;
  exprPtr_  = exprPtr;
  if (exprPtr_ != NULL)
    exprId_   = exprPtr->getValueId();
  else
    exprId_   = NULL_VALUE_ID;

  if (exprId_ != NULL_VALUE_ID)
    exprPtr_  = NULL;
}

ExprValueId::ExprValueId(const ValueId & exprId)
{
  exprMode_ = STANDALONE;
  exprPtr_  = NULL;
  exprId_   = exprId;
}

ExprValueId & ExprValueId::operator= (const ExprValueId & other)
{
  CMPASSERT(exprMode_ != MEMOIZED);
  exprMode_ = other.exprMode_;
  exprPtr_ = other.exprPtr_;
  exprId_ = other.exprId_;

  if (exprId_ != NULL_VALUE_ID)
    exprPtr_  = NULL;
  return *this;
}

ExprValueId & ExprValueId::operator= (ItemExpr * other)
{
  CMPASSERT(exprMode_ != MEMOIZED);
  exprPtr_ = other;
  // update the value id as well (may be set to a NULL value id, though)
  if (exprPtr_ != NULL)
    exprId_ = exprPtr_->getValueId();
  else
    exprId_ = NULL_VALUE_ID;

  if (exprId_ != NULL_VALUE_ID)
    exprPtr_  = NULL;
  return *this;
}

ExprValueId & ExprValueId::operator= (const ValueId & other)
{
  CMPASSERT(exprMode_ != MEMOIZED);
  exprId_ = other;
  exprPtr_ = NULL;
  return *this;
}

NABoolean ExprValueId::operator== (const ExprValueId &other) const
{
  return (getPtr() == other.getPtr());       // ptrs must match
}

NABoolean ExprValueId::operator== (const ItemExpr *other) const
{
  return getPtr() == other;
}
NABoolean ExprValueId::operator== (const ValueId &other) const
{
  return (getValueId() == other);
}

ValueId ExprValueId::getValueId() const
{
  // make sure we return the value id that belongs to exprPtr_
  // (we might have initialized it with an ItemExpr * and later
  // added the value id to the ItemExpr without updating this object)
  if (exprId_ == NULL_VALUE_ID AND exprPtr_ != NULL)
    return exprPtr_->getValueId();
  else
    return exprId_;
}
void ExprValueId::convertToMemoized()
{
  // set this mode to prevent updates to it: a MEMOIZED object cannot
  // be assigned a new value
  exprMode_ = MEMOIZED;
}

void ExprValueId::convertToStandalone()
{
  exprMode_ = STANDALONE;
}

ItemExpr * ExprValueId::getPtr() const
{
  ValueId temp = exprId_;		// NSK platform needs to save this...?
  exprPtr_->checkInvalidObject(this);
  if (temp == NULL_VALUE_ID)
  {
    if (exprPtr_ == NULL || exprPtr_->getValueId() == NULL_VALUE_ID)
      return exprPtr_;
    return exprPtr_->getValueId().getItemExpr();
  }
  return exprId_.getItemExpr();
}

// -----------------------------------------------------------------------
// common member functions
// -----------------------------------------------------------------------

THREAD_P ObjectCounter (*ItemExpr::counter_)(0);

ItemExpr::ItemExpr(OperatorTypeEnum otype,
		   ItemExpr *child0,
		   ItemExpr *child1)
  : ExprNode(otype),
//  origOpType_(origOpTypeBeingBound() != NO_OPERATOR_TYPE ?
//		origOpTypeBeingBound() : otype),
    currChildNo_(0),
    clause_(NULL),
    collateClause_(NULL),
    previousHostVar_(FALSE),
    resolveIncompleteType_(FALSE),
    preCodeGenNATypeChange_(FALSE),
    selectivityFactor_(-1),
    flags_(0)
{
  child(0) = child0;
  child(1) = child1;
  replacementExpr_ = this;
  (*counter_).incrementCounter();

  origOpType_ = otype;

  CmpStatement* currStmt = CmpCommon::statement();
  if ( currStmt ) {
    OperatorTypeEnum x = currStmt->getItemExprOrigOpTypeBeingBound();

    if (x != NO_OPERATOR_TYPE)
      origOpType_ = x;
  }
}

ItemExpr::ItemExpr(const ItemExpr& s)
  : ExprNode(s)
  , valId_(s.valId_)
  , currChildNo_(s.currChildNo_)
  , collateClause_(s.collateClause_)
  , replacementExpr_(s.replacementExpr_)
  , clause_(s.clause_)
  , origOpType_(s.origOpType_)
  , previousHostVar_(s.previousHostVar_)
  , resolveIncompleteType_(s.resolveIncompleteType_)
  , previousName_(s.previousName_)
  , preCodeGenNATypeChange_(s.preCodeGenNATypeChange_)
  , selectivityFactor_(s.selectivityFactor_)
  , flags_(s.flags_)
{
  inputs_[0] = s.inputs_[0];
  inputs_[1] = s.inputs_[1];
  inputs_[2] = s.inputs_[2];
}

ItemExpr::~ItemExpr()
{
  // recursively delete all the children
  for (Lng32 i = 0; i < MAX_ITM_ARITY; i++)
    delete inputs_[i].getPtr();
  (*counter_).decrementCounter();
}

void ItemExpr::transformToRelExpr(NormWA & normWARef,
                            ExprValueId & locationOfPointerToMe,
                            ExprGroupId & introduceSemiJoinHere,
                            const ValueIdSet & externalInputs)
{
      // Do nothing
   locationOfPointerToMe = this;

}

// operator[] is used to access the children of a tree
ExprValueId & ItemExpr::operator[] (Lng32 index)
{
  CMPASSERT(index >= 0 AND index < MAX_ITM_ARITY);
  return inputs_[index];
}

const ExprValueId & ItemExpr::operator[] (Lng32 index) const
{
  CMPASSERT(index >= 0 AND index < MAX_ITM_ARITY);
  return inputs_[index];
}

NABoolean ItemExpr::operator== (const ItemExpr& other) const	// virtual meth
{
  return (getValueId() == other.getValueId());
}
void ItemExpr::deleteInstance()
{
  Int32 nc = getArity();
  for (Lng32 i = 0; i < (Lng32)nc; i++)
    inputs_[i] = NULL;
  delete this;
} // ItemExpr::deleteInstance()


void ItemExpr::setChild(Lng32 index, ExprNode * newChild)
{
  if (newChild)
    {
      CMPASSERT(newChild->castToItemExpr());
      child(index) = newChild->castToItemExpr();
    }
  else
    child(index) = (ItemExpr *)NULL;
} // ItemExpr::setChild()

void ItemExpr::allocValueId()
{
  ValueDesc *vdesc = new (CmpCommon::statementHeap()) ValueDesc(this);
  setValueId(vdesc->getValueId());
} // ItemExpr::allocValueId()

// Check whether the given ValueId is referenced in this ItemExpr.
NABoolean ItemExpr::referencesTheGivenValue(const ValueId & vid,
                                    NABoolean doNotDigInsideVegRefs ,
                                    NABoolean doNotDigInsideInstNulls) const
{
  // In really peculiar cases, a VEGRef might contain another VEGRef within
  // its VEG which recursively self-references the VEGRef. In order to prevent
  // running into an infinite loop there, we remember those VEG we've already
  // already seen by setting a flag in those VEG. If we run into that again,
  // there is no need to check the members of the VEG into it anymore since
  // those have already been or will be checked.
  //
  NABoolean retVal = FALSE;

  if (getValueId() == vid)
    return TRUE;

  ValueId exprId;
  switch (getOperatorType())
  {
    case ITM_VEG_PREDICATE:
    {
      VEG *veg = ((VEGPredicate *)this)->getVEG();
      if (veg->getVEGReference()->getValueId() == vid)
        return TRUE;
      else
      {
        // Already seen. Return FALSE. In VEGRef_x(VEG{VEGRef_x(..),y,z}),
        // the call to the inner VEGRef_x returns FALSE. However, if the
        // vid is VEGRef_x itself, when the function is called on the outer
        // VEGRef_x, it has return TRUE already. The previous "if" clause
        // ensures that. If vid is one of the other values in the VEG such
        // as y or z, ValueIdSet::referencesTheGivenValue() is going to call
        // us again on other members of the VEG. We will return TRUE with
        // the matching member; and ValueIdSet::referencesTheGivenValue()
        // is also going to return TRUE when we return TRUE on any one of
        // the members of the VEG.
        //
        if (veg->seenBefore())
          return FALSE;
        else
        {
          // Mark this VEG as already seen before going over its members,
          // so that if one of its members is a VEGRef to this VEG, we
          // don't have to traverse the VEG anymore.
          //
          veg->markAsSeenBefore();
          retVal = veg->getAllValues().referencesTheGivenValue(vid,exprId);
          veg->markAsNotSeenBefore();
        }
      }
      break;
    }
    case ITM_VEG_REFERENCE:
    {
      if (doNotDigInsideVegRefs)
        return FALSE;

      VEG *veg = ((VEGReference *)this)->getVEG();

      // Already seen. Return FALSE. In VEGRef_x(VEG{VEGRef_x(..),y,z}),
      // the call to the inner VEGRef_x returns FALSE. However, if the
      // vid is VEGRef_x itself, when the function is called on the outer
      // VEGRef_x, it has return TRUE already. The previous "if" clause
      // ensures that. If vid is one of the other values in the VEG such
      // as y or z, ValueIdSet::referencesTheGivenValue() is going to call
      // us again on other members of the VEG. We will return TRUE with
      // the matching member; and ValueIdSet::referencesTheGivenValue()
      // is also going to return TRUE when we return TRUE on any one of
      // the members of the VEG.
      //
      if (veg->seenBefore())
      {
        return FALSE;
      }
      else
      {
        // Mark this VEG as already seen before going over its members,
        // so that if one of its members is a VEGRef to this VEG, we
        // don't have to traverse the VEG anymore.
        //
        veg->markAsSeenBefore();
        retVal = veg->getAllValues().referencesTheGivenValue(vid,exprId);
        veg->markAsNotSeenBefore();
      }
      break;
    }
    case ITM_INSTANTIATE_NULL:
    {
      ValueId  nvid = getValueId();
      const ItemExpr * nie = nvid.getItemExpr();
      InstantiateNull *inst = (InstantiateNull *)nie->castToItemExpr();

      if (doNotDigInsideInstNulls)
        return FALSE;
      else
      {
        // Need to dig underneath the instantiate null to check if
        // the value we are looking for is the immediate child of
        // the instantiate null or contained in a veg reference
        // that is the child of the instantiate null.
        const ValueId & childVid = this->child(0)->getValueId();
        const ItemExpr * childExpr = childVid.getItemExpr();
        retVal =  childExpr->referencesTheGivenValue(vid);
      }
      break;
    } // end case instantiate null
    case ITM_ROWSETARRAY_SCAN:
    {
      retVal = FALSE;
      break;
    }
    default:
    {
      Lng32 nc = getArity();
      for (Lng32 i = 0; i < nc; i++)
      {
        if (child(i).getPtr())
        {
          if (child(i)->referencesTheGivenValue(vid))
          {
            retVal = TRUE;
            break;
          }
        }
      } // endfor

      // if this is a subquery, check any outer references of the subquery as
      // well as the children.
      //
      if ((NOT retVal) AND isASubquery())
      {
        // check if the given value is referenced in the required inputs of
        // the subquery
        //
        const ValueIdSet inputs = ((Subquery *)this)->getSubquery()->
                                   getGroupAttr()->getCharacteristicInputs();

        // Must not call internal function here, since we are checking on a
        // different set (inputs), not a subexpr within this node.
        //
        retVal = inputs.referencesTheGivenValue(vid,exprId);
      }
      break;
    } // default
  } // switch

  return retVal;
}




// Check whether this ItemExpr references any one value
// belonging to the given ValueidSet
NABoolean ItemExpr::referencesOneValueFrom(const ValueIdSet &vs) const
{
  for (ValueId id = vs.init(); vs.next(id); vs.advance(id))
    {
	  //check if the item expr is a non-strict constant
	  //a strict constant is somethine like cos(1)
	  //where as cos(?p) can be considered a constant
	  //in the non-strict definition since it remains
	  //constant for a given execution of a query
      if (!id.getItemExpr()->doesExprEvaluateToConstant(FALSE) )
         if (referencesTheGivenValue(id))
	    return TRUE;
    }
  return FALSE;
} // ItemExpr::referencesOneValueFrom()

// Check whether the given ValueId is contained in a VEGRef
NABoolean ItemExpr::containsTheGivenValue(const ValueId & vid) const
{
  // In really peculiar cases, a VEGRef might contain another VEGRef within
  // its VEG which recursively self-references the VEGRef. In order to prevent
  // running into an infinite loop there, we remember those VEG we've already
  // already seen by setting a flag in those VEG. If we run into that again,
  // there is no need to check the members of the VEG into it anymore since
  // those have already been or will be checked.
  //
  NABoolean retVal = FALSE;

  if (getValueId() == vid)
    return TRUE;

  switch (getOperatorType())
  {
    case ITM_VEG_PREDICATE:
    {
      VEG *veg = ((VEGPredicate *)this)->getVEG();
      if (veg->getVEGReference()->getValueId() == vid)
        return TRUE;
      else
      {
        // Already seen. Return FALSE. In VEGRef_x(VEG{VEGRef_x(..),y,z}),
        // the call to the inner VEGRef_x returns FALSE. However, if the
        // vid is VEGRef_x itself, when the function is called on the outer
        // VEGRef_x, it has return TRUE already. The previous "if" clause
        // ensures that. If vid is one of the other values in the VEG such
        // as y or z, ValueIdSet::containsTheGivenValue() is going to call
        // us again on other members of the VEG. We will return TRUE with
        // the matching member; and ValueIdSet::containsTheGivenValue()
        // is also going to return TRUE when we return TRUE on any one of
        // the members of the VEG.
        //
        if (veg->seenBefore())
          return FALSE;
        else
        {
          // Mark this VEG as already seen before going over its members,
          // so that if one of its members is a VEGRef to this VEG, we
          // don't have to traverse the VEG anymore.
          //
          veg->markAsSeenBefore();
          retVal = veg->getAllValues().containsTheGivenValue(vid);
          veg->markAsNotSeenBefore();
        }
      }
      break;
    }
    case ITM_VEG_REFERENCE:
    {
      VEG *veg = ((VEGReference *)this)->getVEG();

      // Already seen. Return FALSE. In VEGRef_x(VEG{VEGRef_x(..),y,z}),
      // the call to the inner VEGRef_x returns FALSE. However, if the
      // vid is VEGRef_x itself, when the function is called on the outer
      // VEGRef_x, it has return TRUE already. The previous "if" clause
      // ensures that. If vid is one of the other values in the VEG such
      // as y or z, ValueIdSet::containsTheGivenValue() is going to call
      // us again on other members of the VEG. We will return TRUE with
      // the matching member; and ValueIdSet::containsTheGivenValue()
      // is also going to return TRUE when we return TRUE on any one of
      // the members of the VEG.
      //
      if (veg->seenBefore())
      {
        return FALSE;
      }
      else
      {
        // Mark this VEG as already seen before going over its members,
        // so that if one of its members is a VEGRef to this VEG, we
        // don't have to traverse the VEG anymore.
        //
        veg->markAsSeenBefore();
        retVal = veg->getAllValues().containsTheGivenValue(vid);
        veg->markAsNotSeenBefore();
      }
      break;
    }
    case ITM_INSTANTIATE_NULL:
    {
      ValueId  nvid = getValueId();
      const ItemExpr * nie = nvid.getItemExpr();
      InstantiateNull *inst = (InstantiateNull *)nie->castToItemExpr();
      // Special code to handle instantiate nulls for subqueries.
      // If the instantiate null was introduced for a subquery, then the
      // "NoCheckForLeftToInnerJoin" flag was set to TRUE. If set, this
      // flag indicates that we don't need to check to see if we need to
      // transform the left join to an inner join, and thus possibly
      // remove the instantiate null, because the instantiate_null isn't
      // for a left join. If the flag is FALSE, however, it means the
      // instantiate null is for left join. In this case, we don't need
      // to execute this special code, so just break out now.
      if (NOT inst->NoCheckforLeftToInnerJoin)
      {
        break;
      }
      else
      {
        // Need to dig underneath the instantiate null to check if
        // the value we are looking for is the immediate child of
        // the instantiate null or contained in a veg reference
        // that is the child of the instantiate null.
        const ValueId & childVid = this->child(0)->getValueId();
        const ItemExpr * childExpr = childVid.getItemExpr();
        return childExpr->containsTheGivenValue(vid);

      }
    } // end case instantiate null
    default:
    {
      break;
    }
  } // switch

  return retVal;

} // ItemExpr::containsTheGivenValue()


// return the folded expression (if can be done). Return NULL otherwise
ItemExpr* ItemExpr::constFold() 
{
   ItemExpr* expr = NULL;

   try  {
      expr = copyTree(STMTHEAP);
   }

   catch (...) {
      return NULL;
   }

   expr->synthTypeAndValueId(TRUE, TRUE);

   expr = expr->simplifyBeforeConstFolding();
   //expr = simplifyBeforeConstFolding();

   if ( expr == NULL )
     expr = this;

   ValueIdList dummy; ValueId dummyId;
   ItemExpr* outExpr = NULL;
   Int32 error = dummy.evaluateExpr(dummyId, expr->getValueId(), -1,
                                    FALSE, //don't simplify expr
                                    TRUE,  // eval all consts
                                    &outExpr);

   if ( error == TRUE && outExpr ) 
       return outExpr;
   else 
       return NULL; 
}

ItemExpr* ItemExpr::simplifyBeforeConstFolding()
{
  Lng32 nc = getArity();

  if ( nc == 0 ) {
    return getConstantInVEG();
  }

  for (Int32 i = 0; i < nc; i++)
   {

      ValueId id = child(i)->getValueId();

      ItemExpr* cExpr = id.getItemExpr()->simplifyBeforeConstFolding();

      if ( cExpr )
        setChild(i, cExpr);
   }

   return this;
}

ItemExpr* ItemExpr::getConstantInVEG()
{
  switch (getOperatorType())
  {
     case ITM_VEG_REFERENCE:
      {
          const VEG * exprVEG = ((VEGReference*)this)->getVEG();
          const ValueIdSet & VEGGroup = exprVEG->getAllValues();

          ItemExpr *c = NULL;
          Lng32 cnt = 0;

          for (ValueId id = VEGGroup.init(); VEGGroup.next(id); VEGGroup.advance(id))
            {
              const ItemExpr * expr = id.getItemExpr();
              if (expr->getOperatorType() == ITM_CONSTANT)
                {
                  c = (ConstValue*)(id.getItemExpr());
                  cnt ++;
                }

            }
            return (cnt == 1) ? c : NULL;
       }

       default:
        break;
   }

   return NULL;
}

ItemExpr * ItemExpr::createMirrorPred(ItemExpr *compColPtr, 
                                      ItemExpr * compColExprPtr, 
                                      const ValueIdSet &underlyingCols)
{
   CMPASSERT(compColPtr->getOperatorType() == ITM_BASECOLUMN);
   BaseColumn *bcol = static_cast<BaseColumn *>(compColPtr);
   // use the basecolumn Veg, using the basecolumn by itself can cause issues
   // during codegen downstream
   ValueId egVid = bcol->getTableDesc()->getColumnVEGList()[bcol->getColNumber()];
   ItemExpr *compColVEGRefPtr = egVid.getItemExpr();

   switch (getOperatorType())
     {
     case ITM_VEG_PREDICATE:
       {
          ValueId refColId ;
          // XXX this should be a for loop to collect the each sub
          // expression containing each referenced column, mirror those
          // sub expressions and then final assembly of the complete
          // complete expression. The colde below works for simple expressions
          // like A=2 and B=4 when the computed col expr is POWER(A+B,2)
          // because of the veges formed.
          underlyingCols.getFirst(refColId); 
          const VEG * predVEG = ((VEGPredicate *) this)->getVEG();
          const ValueIdSet & VEGGroup = predVEG->getAllValues();
          if (VEGGroup.containsTheGivenValue(refColId) &&
              underlyingCols.entries() == 1)
            {
              ItemExpr * keyColExpr = predVEG->getVEGReference();
              ItemExpr * keyColRef = refColId.getItemExpr();

              ValueIdMap compExprRewriteMap;
              ValueId newCompExpr;
              compExprRewriteMap.addMapEntry(keyColExpr->getValueId(), keyColRef->getValueId());
              newCompExpr = compColExprPtr->mapAndRewrite(compExprRewriteMap);

              // Now try to const folding the newCompExpr by evaluating 
              // the expression. If successful, we use the computed result 
              // instead of newCompExpr. The simplification is necessary for 
              // the scan optimizer to figure out the actual number of rows 
              // returned per probe. 

              ItemExpr* foldedExpr = newCompExpr.getItemExpr()->constFold();

              ItemExpr * compPred = new(CmpCommon::statementHeap())
                                      BiRelat(ITM_EQUAL,
                                              compColVEGRefPtr,
                                              (foldedExpr==NULL) ? newCompExpr.getItemExpr() : foldedExpr);
              compPred->synthTypeAndValueId(TRUE);

              return compPred;
            }
          
          return NULL; 
          break;
       }
     case ITM_EQUAL:
     case ITM_LESS:
     case ITM_LESS_EQ:
     case ITM_LESS_OR_LE:
     case ITM_GREATER:
     case ITM_GREATER_EQ:
     case ITM_GREATER_OR_GE:
       {
          ItemExpr *keyColRef;
          ItemExpr *keyColExpr;
          ValueId refColId;
          // XXX figure out what it means when we have more than one
          // say CC expr is POWER(T.A+T.B,2)
          // If the keyPred is: T.A =2 AND T.B=4
          // we need to make sure we substitue both T.A and T.B in the power
          // expression above. 
          // The current code does the correct thing for simple veg expressions
          // with multiple cols even though it 
          // only process the first of the underlying cols, due to the veges 
          // formed. Should be a for loop instead
          // Also, at the moment have restricted the key predicate candidates
          // to mirror only to be equipreds when we have multiple columns 
          // referenced in the computedColumn expression.
          underlyingCols.getFirst(refColId); 
          NABoolean keyColOnLeft = TRUE;
          if (child(0)->referencesTheGivenValue(refColId) &&
              underlyingCols.entries() == 1)
            {
              keyColRef = child(0);
              keyColExpr = child(1);
            }
          else if (child(1)->referencesTheGivenValue(refColId) &&
                   underlyingCols.entries() == 1)
            {
              keyColRef = child(1);
              keyColExpr = child(0);
              keyColOnLeft = FALSE;
            }
          else
            { // XXX print warning for now.
#ifdef DEBUG
              fprintf(stderr, "ItemExpr::createMirrorPred(): Didn't find any references to valueId: %d\n", tempV);
#endif
              return NULL; 
            }
          // now we want to replace the reference to the key column in the compExpr with the keyColExpr

          ValueIdMap compExprRewriteMap;
          ValueId newCompExpr;
          compExprRewriteMap.addMapEntry(keyColExpr->getValueId(), keyColRef->getValueId());
          newCompExpr = compColExprPtr->mapAndRewrite(compExprRewriteMap);


          ItemExpr* foldedExpr = newCompExpr.getItemExpr()->constFold();
          ItemExpr* mirroredExpr = 
               (foldedExpr==NULL) ? newCompExpr.getItemExpr() : foldedExpr;

          ItemExpr * compPred;
          if (keyColOnLeft == TRUE)
              compPred = new(CmpCommon::statementHeap())
                BiRelat(((BiRelat *) this)->getRelaxedComparisonOpType(),
                                   compColVEGRefPtr,
                                   mirroredExpr //newCompExpr.getItemExpr()
                        );
          else
              compPred = new(CmpCommon::statementHeap())
                           BiRelat(((BiRelat *) this)->getRelaxedComparisonOpType(),
                                   mirroredExpr, //newCompExpr.getItemExpr(),
                                   compColVEGRefPtr);
          compPred->synthTypeAndValueId(TRUE);
          return compPred;
          break;
       }
     default:
       return NULL;
     }
   return NULL;
}

//Does 'this' ItemExpr evaluate to a constant?
//e.g.
//Sin(Cos(1)+1) will return TRUE.
//Sin(?p) will return FALSE.
NABoolean ItemExpr::doesExprEvaluateToConstant(NABoolean strict,
                                               NABoolean considerVEG) const
{

  NABoolean result = TRUE;
  Lng32 nc = getArity();

  //check if I am a leaf node
  if(!nc){
	//I am a leaf node
	//therefore check if I can be considered
	//a constant
	switch(getOperatorType()){

		case ITM_CONSTANT:
		case ITM_DEFAULT_SPECIFICATION:
		case ITM_PI:
		  //I am a strict constant, so return TRUE
		  return TRUE;

		case ITM_HOSTVAR:
                 {
                     HostVar* hv = (HostVar*)this;
                     if ( hv->isSystemGeneratedOutputHV() )
                        return TRUE;
                 }

		case ITM_DYN_PARAM:
		case ITM_CACHE_PARAM:
		case ITM_CURRENT_USER:
		case ITM_SESSION_USER:
		case ITM_CURRENT_TIMESTAMP:
		case ITM_UNIX_TIMESTAMP:
		case ITM_GET_TRIGGERS_STATUS:
		case ITM_UNIQUE_EXECUTE_ID:
		case ITM_CURR_TRANSID:
		  if(strict)
			//I am a non-strict constant, so return FALSE
			return FALSE;
		  //non-strict definition of constant
		  //therefore return TRUE
		  return TRUE;
    case ITM_VEG_REFERENCE:
      if(considerVEG)
      {
        const VEG * refVEG = ((VEGReference *)this)->getVEG();
        ValueId literal = NULL_VALUE_ID;

        if (strict)
        {
          literal = refVEG->getAConstant();
        }
        else{
          literal = refVEG->getAConstantHostVarOrParameter();
        }

        if (literal == NULL_VALUE_ID)
          return FALSE;

        return TRUE;
      }
      return FALSE;
		default:
		  return FALSE;
    }
  }

  //I am not a leaf node

  //check if I the random method
  //I will return different values
  //for the same parameter, so
  //I will never return a constant
  //value
  if(getOperatorType() == ITM_RANDOMNUM)
    return FALSE;

  // An aggrgate, sequence function  and instantiateNull itemExprs require state information (i.e. other rows)
  // to determine their value. Therefore they cannot be a constant. Also a rowset array scan 
  // denotes an array of values and is therefore not a constant.
  if(isAnAggregate()|| isASequenceFunction () ||
      (getOperatorType() == ITM_INSTANTIATE_NULL) || 
      (getOperatorType() == ITM_ROWSETARRAY_SCAN) ) 
  {
    return FALSE;
  }

  //I am not constant if anyone of my children
  //is not constant
  //check if all my children can be considered constants
  for (Lng32 i = 0; i < nc; i++)
  {
    result = child(i)->doesExprEvaluateToConstant(strict,considerVEG);

    //check if this child is not a constant
    if(!result){
	  //this child is not a constant, so return FALSE
      return result;
    }

  }

  //none of my children is a non-constant, so return TRUE
  return result;

}//ItemExpr::doesExprEvaluateToConstant()

NABoolean ItemExpr::referencesAHostVar() const
{
  NABoolean result = FALSE;
  Lng32 nc = getArity();

  //check if I am a leaf node
  if(!nc)
  {
    //I am a leaf node
    //therefore check if I can be considered
    //a constant
    switch(getOperatorType())
    {
      case ITM_HOSTVAR:
      case ITM_DYN_PARAM:
      case ITM_CURRENT_USER:
      case ITM_SESSION_USER:
      case ITM_CURRENT_TIMESTAMP:
      case ITM_UNIX_TIMESTAMP:
      case ITM_GET_TRIGGERS_STATUS:
      case ITM_UNIQUE_EXECUTE_ID:
      case ITM_CURR_TRANSID:
	return TRUE;

      case ITM_VEG_PREDICATE:
      {
        VEG * predVEG = ((VEGPredicate *)this)->getVEG();
        // Now, get all members of the VEG group, only if this VEG has not
        // been seen before. This is to avoid infinite looping for cases
        // where a VEG references itself
        if (predVEG->seenBefore())
          return FALSE;

        // get all members of the VEG
        const ValueIdSet & VEGGroup = predVEG->getAllValues();
        for (ValueId id = VEGGroup.init(); VEGGroup.next(id); VEGGroup.advance(id))
        {
          predVEG->markAsSeenBefore();
          NABoolean isAHostVar = id.getItemExpr()->referencesAHostVar();
          predVEG->markAsNotSeenBefore();

          if (isAHostVar)
            return TRUE;
        }
        return FALSE;
      } // end Case ITM_VEG_PREDICATE
    } // end switch
  } // end nc == 0

  for (Lng32 i = 0; i < nc; i++)
  {
    if(this->child(i)->referencesAHostVar())
      return TRUE;
  }
  return FALSE;
}

// This method returns TRUE or FALSE depending whether the optimizer
// should use stats to compute selectivity or use default selectivity
// Return TRUE if the expression is a VEG reference, base column,
// index column, column with CAST / UPPER / LOWER / UCASE / 
// LCASE / UPSHIFT / TRIM / SUBSTR (sometimes)
//
// Note that in the case of functions such as CAST and UPPER,
// the stats returned are those of the argument. For a right TRIM
// where we are trimming blanks, this is correct but for the 
// others the resulting stats will be incorrect in some way.
// For example, UPPER maps characters to upper case, so the UECs
// of the result should often be lower than the original, and
// certain intervals (namely those encompassing values that begin
// with a lower case letter) should be empty. For another
// example, CAST often is a 1-to-1 transformation so the UECs
// are right, but the order might change (e.g. when casting 
// numerics to characters; 99 < 100, but '99' > '100'). Even
// so, the statistics of the argument are still a better reflection
// of the result of the function than the default distribution,
// particularly from the standpoint of skew. So, we use them.
NABoolean ItemExpr::useStatsForPred()
{
  OperatorTypeEnum myType = getOperatorType();

  if (myType == ITM_VEG_REFERENCE OR
	  myType == ITM_BASECOLUMN OR
	  myType == ITM_VEG_PREDICATE OR
	  myType == ITM_INDEXCOLUMN OR
	  myType == ITM_VALUEIDUNION OR
	  myType == ITM_CAST OR
	  myType == ITM_INSTANTIATE_NULL OR
	  myType == ITM_UNPACKCOL OR
	  myType == ITM_UPPER OR
	  myType == ITM_LOWER OR
	  myType == ITM_TRIM OR
	  myType == ITM_CONVERT)

	return TRUE;
  else if (myType == ITM_SUBSTR)
    {
      // if the substring is known to be a prefix of the string,
      // then use the stats
      ItemExpr * startPosition = child(1);
      if (startPosition->getOperatorType() == ITM_CONSTANT)
        {
          NABoolean negate = FALSE;
          ConstValue * c = startPosition->castToConstValue(negate);
          if (c->canGetExactNumericValue() &&
               (c->getExactNumericValue() == 1))
            return TRUE;
        }
      return FALSE;  
    }
  else
	return FALSE;
}

void ItemExpr::getLeafValueIds(ValueIdSet &lv) const
{
  Int32 nc = getArity();

  // if this is a leaf node, add its value id
  // UDFunction uses the getArity() function to return the number
  // of inputs. It is really a leaf value...
  if (nc == 0 || getOperatorType() == ITM_USER_DEF_FUNCTION)
    {
      lv += getValueId();
    }
  else
    {
      // else add the leaf value ids of all the children
      for (Lng32 i = 0; i < (Lng32)nc; i++)
	{
	  child(i)->getLeafValueIds(lv);
	}
    }
}

void ItemExpr::getLeafValueIds(ValueIdList &lv) const
{
  Int32 nc = getArity();

  // if this is a leaf node, add its value id
  // UDFunction uses the getArity() function to return the number
  // of inputs. It is really a leaf value...
  if (nc == 0 || getOperatorType() == ITM_USER_DEF_FUNCTION)
    {
      lv.insert(getValueId());
    }
  else
    {
      // else add the leaf value ids of all the children
      for (Lng32 i = 0; i < (Lng32)nc; i++)
	{
	  child(i)->getLeafValueIds(lv);
	}
    }
}

void ItemExpr::getLeafValueIdsForCaseExpr(ValueIdSet &lv) 
{
  Int32 nc = getArity();

  // if this is a leaf node, add its value id
  if (nc == 0)
    {
	  if (doesExprEvaluateToConstant(FALSE))
		  lv += getValueId();
	  else
	  {
        ValueIdSet baseColSet;
	    findAll(ITM_BASECOLUMN, baseColSet, TRUE, TRUE);
        lv.addSet(baseColSet);
	  }
    }
  else
    {
      // elseadd the leaf value ids of all the children
		if (getOperatorType() == ITM_IF_THEN_ELSE)
		{
		  // for if_then_else statement ignore the first parameter which is the condition
		  child(1)->getLeafValueIdsForCaseExpr(lv);

		  // else part of Case can be a NULL pointer if it is created by Generator
		  if (child(2))
			child(2)->getLeafValueIdsForCaseExpr(lv);
		}
		else // for Case get the child, which would be IF_THEN_ELSE
		{
		  if (getOperatorType() == ITM_CASE)
			child(0)->getLeafValueIdsForCaseExpr(lv);
		  else // for all other expressions, collect the base columns
		  {
			ValueIdSet baseColSet;
			findAll(ITM_BASECOLUMN, baseColSet, TRUE, TRUE);
			lv.addSet(baseColSet);
		  }
		}
	}
}

// get leaf expression if the cardinality for this expression can be
// estimated using histograms
ItemExpr * ItemExpr::getLeafValueIfUseStats(NABoolean digIntoInstantiateNull)
{
  ItemExpr * expr = this;

  if (useStatsForPred())
  {
    if (digIntoInstantiateNull == FALSE && expr->getOperatorType() == ITM_INSTANTIATE_NULL)
      return expr;

    if(expr->getArity() > 0)
    {
      if (expr->getOperatorType() != ITM_TRIM)
            expr = expr->child(0)->getLeafValueIfUseStats(digIntoInstantiateNull);
      else
            expr = expr->child(1)->getLeafValueIfUseStats(digIntoInstantiateNull);
    }
  }

  return expr;
}
ItemExpr * ItemExpr::castToItemExpr()
{
  return this;
} // ItemExpr::castToItemExpr()

const ItemExpr * ItemExpr::castToItemExpr() const
{
  return this;
} // ItemExpr::castToItemExpr()

ConstValue * ItemExpr::castToConstValue(NABoolean & negate_it)
{
  negate_it = FALSE;
  return NULL;
}

SimpleHashValue ItemExpr::hash()
{
  // this method is just defined to have a hash method in ExprNode
  // without referencing class HashValue (which is too complicated
  // for the common code directory)
  return treeHash().getValue();
}

HashValue ItemExpr::topHash()
{

  HashValue result = 0;

  // hash on item properties???

  return result;
}

// this method is not virtual, since combining the hash values of the
// top node and its inputs should be independent of the actual node
HashValue ItemExpr::treeHash()
{
  HashValue result = topHash();
  Int32 maxc = getArity();

  for (Lng32 i = 0; i < (Lng32)maxc; i++)
    {
      // call this method recursively for the inputs
      result ^= child(i)->treeHash();
    }

  return result;
}

NABoolean ItemExpr::duplicateMatch(const ItemExpr & other) const
{
  // duplicateMatch works a little different in ItemExpr objects than it
  // does in RelExpr. In classes derived from RelExpr we strictly require
  // the duplicateMatch() method to be defined correctly. In classes
  // derived from ItemExpr this has not been done. Therefore, the
  // default method returns FALSE to be conservative (except
  // when the two expressions are the same).
  // The generic processing of duplicateMatch() for every derived class
  // is done in a separate method, genericDuplicateMatch().
  return (this == &other);
}

NABoolean ItemExpr::genericDuplicateMatch(const ItemExpr & other) const
{
  DCMPASSERT(other.castToItemExpr());

  if ((getValueId() == other.getValueId()) &&
      (getValueId() != NULL_VALUE_ID))
    return TRUE;
  if (getOperatorType() != other.getOperatorType())
    return FALSE;
  Int32 arity = getArity();
  if (arity != other.getArity())
    return FALSE;

  for (Lng32 i=0; i < (Lng32) arity; i++)
    {
      if (NOT (child(i)->duplicateMatch(*(other.child(i).getPtr()))))
	return FALSE;
    }
  return TRUE;
}

ItemExpr * ItemExpr::copyTopNode(ItemExpr *derivedNode,
				 CollHeap* )
{
  ItemExpr *result = NULL;

  if (derivedNode == NULL)
    {
      ABORT("encountered an instantiation of an ItemExpr object");
    }
  else
    result = derivedNode;

  // copy this's (the source's) original setting to result (the target)
  result->origOpType_ = origOpType_;

  result->selectivityFactor_ = selectivityFactor_;

  #ifndef NDEBUG
    CMPASSERT(!collateClause());	// else, Binder fell down on the job
  #endif				// (wrong overload of synthType() used)

  // copy/synthesize other item properties???

  return result;
}

// this method is not virtual, since combining the copies of the
// top node and its inputs should be independent of the actual node
ItemExpr * ItemExpr::copyTree(CollHeap* outHeap)
{
  ItemExpr * result = copyTopNode(NULL, outHeap);
  Int32 arity = getArity();

  for (Int32 i = 0; i < arity; i++) {
    if (child(i)) {
      result->child(i) = child(i)->copyTree(outHeap);
    }
  }

  return result;
}

NABoolean ItemExpr::containsSubquery()     // virtual method
{
  Int32 arity = getArity();

  for (Int32 i = 0; i < arity; i++)
    if (child(i) && child(i)->containsSubquery())
      return TRUE;

  return FALSE;
}

ItemExpr *ItemExpr::containsUDF()     // virtual method
{
  Int32 arity = getArity();

  for (Int32 i = 0; i < arity; i++)
    if (child(i) && child(i)->containsUDF())
      return child(i)->containsUDF();

  return 0;
}
NABoolean ItemExpr::containsIsolatedUDFunction()    // virtual method
{
  Int32 arity = getArity();

  for (Int32 i = 0; i < arity; i++)
    if (child(i) && child(i)->containsIsolatedUDFunction())
      return TRUE;

  return FALSE;
}

NABoolean ItemExpr::containsValueIdProxySibling(const ValueIdSet &siblings)
    // virtual method
{
  Int32 arity = getArity();

  for (Int32 i = 0; i < arity; i++)
    if (child(i) && child(i)->containsValueIdProxySibling(siblings))
      return TRUE;

  return FALSE;
} 

NABoolean ItemExpr::isASubquery() const   { return FALSE; }  // virtual method

NABoolean ItemExpr::isAnAggregate() const { return FALSE; }  // virtual method

NABoolean ItemExpr::isAPredicate() const  { return FALSE; }  // virtual method

NABoolean ItemExpr::isASequenceFunction() const { return FALSE; }   // virtual method

NABoolean ItemExpr::isOlapFunction() const { return FALSE; }   // virtual method


NABoolean ItemExpr::isAUserSuppliedInput() const { return FALSE; }  // virtual

ItemExpr * ItemExpr::transformMultiValuePredicate(	     // virtual method
					NABoolean /*flattenSubqueries*/,
					ChildCondition /*tfmIf*/)
{ return NULL; }

NABoolean ItemExpr::containsAnAggregate() const
{
  for (Int32 i=0; i<getArity(); i++)
  {
    if (child(i)->containsAnAggregate())
      return TRUE;
  }
  return FALSE;
}

// ----------------------------------------------------------------------
// 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.
// ----------------------------------------------------------------------
void ItemExpr::getLeafValuesForCoverTest(ValueIdSet & leafValues, 
                                         const GroupAttributes& coveringGA,
                                         const ValueIdSet & newExternalInputs) const
{
  Lng32 nc = getArity();

  if ((nc == 0) 
    || coveringGA.isCharacteristicOutput(getValueId())
    || newExternalInputs.contains(getValueId()))
    {
      leafValues += getValueId();
    }
  else
    {
      for (Lng32 i = 0; i < nc; i++) {
	if (coveringGA.isCharacteristicOutput(child(i)->getValueId()) ||
	    newExternalInputs.contains(child(i)->getValueId()))
          leafValues += child(i)->getValueId();
        else
	  child(i)->getLeafValuesForCoverTest(leafValues, coveringGA, newExternalInputs);
      }
    }
} // ItemExpr::getLeafValuesForCoverTest()

// This is a recursive
// function that returns the leaf predicates of the tree
// whose root is the ItemExpr into the ValueIdSet&.
void ItemExpr::getLeafPredicates(ValueIdSet& leafPredicates)
{
  if (getOperatorType() != ITM_AND &&
      getOperatorType() != ITM_OR)
    leafPredicates.insert(getValueId());
  else {
    for (Lng32 i=0; i < (Lng32)getArity(); i++)
      child(i)->getLeafPredicates(leafPredicates);
  }
}// getLeafPredicates()

// -----------------------------------------------------------------------
// temp. method to collect basecolumns, used in FileScanRule
// -----------------------------------------------------------------------

template <class Result>
void ItemExpr::findAllT(OperatorTypeEnum wantedType,
		       Result& result,
		       NABoolean visitVEGMembers,
		       NABoolean visitIndexColDefs)
{
  OperatorTypeEnum myType = getOperatorType();

  if (myType == wantedType)
    result.addMember(this);

  // for VEGReferences and VEGPredicates (both having arity 0),
  // look at all the VEG members as well, if requested by the caller
  if (visitVEGMembers AND
      (myType == ITM_VEG_REFERENCE OR myType == ITM_VEG_PREDICATE))
    {
      VEG *veg;
      ValueId vegM;

      if (myType == ITM_VEG_REFERENCE)
	veg = ((VEGReference *) this)->getVEG();
      else
	veg = ((VEGPredicate *) this)->getVEG();

      if(! veg->seenBefore())
      {
	      veg->markAsSeenBefore();
	      for (ValueId x = veg->getAllValues().init();
			 veg->getAllValues().next(x);
			 veg->getAllValues().advance(x))

	      x.getItemExpr()->findAllT(wantedType,
			       result,
			       visitVEGMembers,
			       visitIndexColDefs);

	      veg->markAsNotSeenBefore();
      }
    }

  // for indexcolumns, look at the corresponding base column
  // or expression from the base table, if requested
  if (visitIndexColDefs AND myType == ITM_INDEXCOLUMN)
    {
      ((IndexColumn *) this)->getDefinition().getItemExpr()->
	findAllT(wantedType,
		result,
		visitVEGMembers,
		visitIndexColDefs);
    }

  // recurse
  Int32 nc = getArity();

  for (Lng32 i = 0; i < (Lng32)nc; i++)
    child(i)->findAllT(wantedType,
		      result,
		      visitVEGMembers,
		      visitIndexColDefs);

  if ( nc == 0 )
    switch ( myType )
      {
      case ITM_VALUEIDUNION:
	{
          // NB: ValueIdUnion objects can have more than 2 sources!
	  ValueIdUnion * tempUnion = (ValueIdUnion*) this;
          for (Lng32 i = 0; i < (Lng32)tempUnion->entries(); i++)
            {
              // guard against loops in the references
              // (can happen with common subexpressions, for example)
              if (!tempUnion->getSource(i).getItemExpr()->
                     referencesTheGivenValue(getValueId()))
                tempUnion->getSource(i).getItemExpr()->
                  findAllT(wantedType,
                           result,
                           visitVEGMembers,
                           visitIndexColDefs);
            }
	  break;
	}

      default:
	break;
      }

} // ItemExpr::findAllT, Template version

void ItemExpr::findAll(OperatorTypeEnum wantedType,
                       ValueIdSet & result,
                       NABoolean visitVEGMembers,
                       NABoolean visitIndexColDefs)
{
  findAllT(wantedType, result, visitVEGMembers, visitIndexColDefs);
}

void ItemExpr::findAll(OperatorTypeEnum wantedType,
		       ItemExprList& result,
		       NABoolean visitVEGMembers,
		       NABoolean visitIndexColDefs)
{
  // Collect all ItemExprs into a list.
  findAllT(wantedType, result, visitVEGMembers, visitIndexColDefs);
} // ItemExpr::findAll


Lng32 ItemExpr::getTreeSize(Lng32& maxDepth, NABoolean giveUpThreshold)
{
  Lng32 currentSize=1;
  Int32 nc = getArity();

  for (Lng32 i = 0; i < (Lng32)nc; i++)
  {
    Lng32 thisDepth = 0;
    currentSize += child(i)->getTreeSize(thisDepth, giveUpThreshold);

    if (giveUpThreshold > 0 && currentSize >= giveUpThreshold)
      break;

    if (thisDepth > maxDepth)
      maxDepth = thisDepth;
  }

  maxDepth++;
  return currentSize;
}

// Find all eqaulity columns in an item expression tree.
void ItemExpr::findEqualityCols(ValueIdSet& result)
{
  OperatorTypeEnum myType = getOperatorType();
  ValueId  myVid = getValueId();

  // If it is a base column or an index column, add to the list
  if (myType == ITM_BASECOLUMN || myType == ITM_INDEXCOLUMN)
    result += myVid;

  // If it belongs to VEG, add all the memebers of that VEG
  if (myType == ITM_VEG_REFERENCE || myType == ITM_VEG_PREDICATE)
  {
    VEG *veg;

    if (myType == ITM_VEG_REFERENCE)
      veg = ((VEGReference *) myVid.getItemExpr())->getVEG();
    else 
      // myType == ITM_VEG_PREDICATE
      veg = ((VEGPredicate *) myVid.getItemExpr())->getVEG();

    for (ValueId vid = veg->getAllValues().init();
         veg->getAllValues().next(vid);
         veg->getAllValues().advance(vid))
    {    
      result += vid; 
    }    
  }

  // recurse
  if (myType == ITM_EQUAL)
  {
    child(0)->findEqualityCols(result);
    child(1)->findEqualityCols(result);
  }
}

ItemExpr * ItemExpr::treeWalk(ItemTreeWalkFunc f,
                              CollHeap *outHeap,
                              enum ItemTreeWalkSeq sequence,
                              void *context)
{
  ItemExpr *transformedChildrenArr[4];
  ItemExpr **transformedChildren = transformedChildrenArr;
  Int32 arity = -1;
  NABoolean needToCopy = FALSE;
  ItemExpr *result = this;

  if (sequence == ITM_PREFIX_WALK)
    result = f(result, outHeap, context);

  arity = result->getArity();
  if (arity > 4)
    // allocated from stmt heap since it is used locally only
    // and is not deallocated below
    transformedChildren = new(CmpCommon::statementHeap()) ItemExpr *[getArity()];

  for (int i=0; i<arity; i++)
    {
      transformedChildren[i] =
        result->child(i)->treeWalk(f,
                                   outHeap,
                                   sequence,
                                   context);
      if (transformedChildren[i] != child(i))
        needToCopy = TRUE;
    }

  if (needToCopy)
    {
      // one of the children changed, since we can't
      // change an ItemExpr once we assigned a ValueId to
      // it, make a copy with new children
      result = result->copyTopNode(NULL, outHeap);
      for (int j=0; j<arity; j++)
        result->setChild(j, transformedChildren[j]);
    }

  if (sequence == ITM_POSTFIX_WALK)
    result = f(result, outHeap, context);
  
  return result;
}

ValueId ItemExpr::mapAndRewrite(ValueIdMap &map,
				NABoolean mapDownwards)
{
  ValueId result;

  // Look in the map for a match
  if (mapDownwards)
    map.mapValueIdDown(getValueId(),result);
  else
    map.mapValueIdUp(result,getValueId());

  // if this expression can be mapped directly, then return the
  // mapped value id
  if (result != getValueId())
    return result;

  return mapAndRewriteCommon(map, mapDownwards);
} // ItemExpr::mapAndRewrite

ValueId Aggregate::mapAndRewrite(ValueIdMap &map,
                                NABoolean mapDownwards)
{

  // Need to make sure we map and rewrite the distinctId as well.
  if (isDistinct())
    distinctId_ = distinctId_.getItemExpr()->mapAndRewrite(map, mapDownwards);

  return ItemExpr::mapAndRewrite(map, mapDownwards);
} // Aggregate::mapAndRewrite

ValueId ItemExpr::mapAndRewriteWithIndx(ValueIdMap &map,
					CollIndex ind)
{
  ValueId result;

  map.mapValueIdUpWithIndex(result,getValueId(), ind);

  // if this expression can be mapped directly, then return the
  // mapped value id
  if (result != getValueId())
    return result;

  return mapAndRewriteCommon(map, FALSE);
} // ItemExpr::mapAndRewriteWithIndex

// This method has the code that is common to
// mapAndRewrite() and mapAndRewriteWithIndex().
ValueId ItemExpr::mapAndRewriteCommon(ValueIdMap &map, NABoolean mapDownwards)
{
  ValueId result;

  ItemExpr *copyOfMe = NULL;
  Lng32 nc = getArity();

  // if the children of this expression changed after mapping, then
  // return the value id of a duplicate of myself with the new
  // children attached to it
  for (Lng32 i = 0; i < nc; i++)
    {
      ValueId c = child(i)->mapAndRewrite(map,mapDownwards);

      if (c != child(i)->getValueId())
	{
          // This child was mapped to a different value id
	  if (copyOfMe == NULL)
	    {
              // This was the first child to map to a different value
	      // make a copy of me and initialize its children with
	      // the same pointers that I have
	      copyOfMe = copyTopNode(NULL, CmpCommon::statementHeap());
              // copy the previous children into the new expression
	      for (Lng32 j = 0; j < nc; j++)
		copyOfMe->child(j) = child(j).getPtr();
	    }

	  copyOfMe->child(i) = c.getItemExpr();
	}
    }
  // If the expr had not child then copyOfMe is NULL

  if (copyOfMe)
    {
      // A new expression was created as the mapped value
      copyOfMe->synthTypeAndValueId();
      result = copyOfMe->getValueId();

      // Add to the map table the newly formed expression
      if (mapDownwards)
        map.addMapEntry(getValueId(),result);
      else
        map.addMapEntry(result,getValueId());
    }
  else
    // otherwise just return my value id
    result = getValueId();

  return result;
} // ItemExpr::mapAndRewriteCommon

ItemExpr * ItemExpr::foldConstants(ComDiagsArea *diagsArea,
				   NABoolean newTypeSynthesis)
{
  ItemExpr *result = this;
  Lng32 nc = getArity();

  // if the children of this expression changed after constant folding, then
  // return a duplicate of myself with the new children attached to it
  for (Lng32 i = 0; i < nc; i++)
    {
      ItemExpr *c = child(i)->foldConstants(diagsArea,newTypeSynthesis);

      if (c != child(i))
	{
          // This child was transformed into a different ItemExpr
	  if (result == this)
	    {
              // This was the first child to be transformed;
	      // make a copy of me and initialize its children with
	      // the same pointers that I have
	      result = copyTopNode(NULL, CmpCommon::statementHeap());
              // copy the previous children into the new expression
	      for (Lng32 j = 0; j < nc; j++)
		result->child(j) = child(j).getPtr();
	    }

	  result->child(i) = c;
	}
    }

  // make sure we return a tree with a correct type
  if (result != this)
    result->synthTypeAndValueId(newTypeSynthesis);

  return result;
}

ItemExpr * ItemExpr::applyInverseDistributivityLaw(
     OperatorTypeEnum backboneType,
     OperatorTypeEnum innerType)
{
  // operators other than OR will require some more code, see CMPASSERTs
  DCMPASSERT(backboneType == ITM_OR);

  // we must have a backbone of the backboneType for this to work
  if (getOperatorType() != backboneType)
    return this;

  // a default can switch this code off if required (should be needed
  // only if bugs are found in the code)
  if (CmpCommon::getDefault(FIND_COMMON_SUBEXPRS_IN_OR) != DF_ON)
    return this;

  ItemExpr *result = NULL;
  // NOTE: we'll use the words "disjuncts" and "conjuncts" that make
  // sense with the default operator types, but may not be a great choice
  // if the caller uses different types (sorry, but this might help
  // understand the code better)
  ValueIdSet disjuncts;
  ValueIdSet commonSubexprs;
  CollIndex numCommonSubexprs;
  ValueId c;

  // get a ValueIdSet with all the "disjuncts".
  convertToValueIdSet(disjuncts,NULL,backboneType,FALSE);

  // prime the common subexpressions with all of the conjuncts
  // of the first disjunct
  disjuncts.getFirst(c);
  c.getItemExpr()->convertToValueIdSet(commonSubexprs,NULL,innerType,FALSE);
  disjuncts.advance(c);

  // in a first loop, find the common subexpressions among all of the disjuncts
  for (/* c already initialized */; disjuncts.next(c); disjuncts.advance(c))
    {
      ValueIdSet conjuncts;

      c.getItemExpr()->convertToValueIdSet(conjuncts,NULL,innerType,FALSE);

      // find common subexpressions between the
      // previous and the current disjunct
      commonSubexprs.findCommonSubexpressions(conjuncts);

      // stop if we have no common subexpressions
      if (commonSubexprs.isEmpty())
	break;
    }

  numCommonSubexprs = commonSubexprs.entries();

  if (numCommonSubexprs > 0)
    {
      // Now that we know the real common subexpressions do the same loop
      // again, but this time modify the conjuncts by removing the
      // common parts from them, forming new conjuncts, and connecting
      // them to form a new backbone of disjuncts.

      for (ValueId c2 = disjuncts.init();
	   disjuncts.next(c2);
	   disjuncts.advance(c2))
	{
	  ValueIdSet conjuncts;

	  // one child of the backbone, eliminate common subexpressions
	  // from it
	  c2.getItemExpr()->convertToValueIdSet(conjuncts,
						NULL,
						innerType,
						FALSE);
	  commonSubexprs.findCommonSubexpressions(conjuncts, TRUE);

	  // make sure the common subexpressions haven't changed
	  CMPASSERT(numCommonSubexprs == commonSubexprs.entries());

	  // are there any non-common conjuncts left?
	  if (conjuncts.entries() == 0)
	    {
	      // No, one of the disjuncts consists of only the common
	      // subexpressions. This requires logic specific to the
	      // operator type. For example, (a=10 and b=11) or (a=10)
	      // is (a=10) and (b=11 or TRUE) which is (a=10).
	      CMPASSERT(backboneType == ITM_OR);
	      result = NULL;
	      // leave the inner loop with a NULL result, meaning
	      // that only the common subexpressions should survive
	      break;
	    }

	  // rebuild the ItemExpr tree for the conjuncts
	  ValueIdList conjunctList(conjuncts);
	  ItemExpr *newConjuncts = conjunctList.rebuildExprTree(innerType);

	  // rebuild the backbone
	  if (result == NULL)
	    result = newConjuncts;
	  else
	    result = connect2(backboneType,result,newConjuncts);
	}

      // create a tree with the common subexpressions
      ValueIdList commonSubexprsList(commonSubexprs);
      ItemExpr *commonSubexprsAsItem =
	commonSubexprsList.rebuildExprTree(innerType);

      // hook up common part and the non-common expressions (if any)
      if (result)
	result = connect2(innerType,commonSubexprsAsItem,result);
      else
	result = commonSubexprsAsItem;

      result->synthTypeAndValueId();
    }
  else
    {
      // sorry, no common subexpressions found, return original expression
      result = this;
    }

  return result;
}

// little helper for the above method
ItemExpr * ItemExpr::connect2(OperatorTypeEnum op,
			      ItemExpr *op1,
			      ItemExpr *op2)
{
  switch (op)
    {
    case ITM_AND:
    case ITM_OR:
      return new(CmpCommon::statementHeap()) BiLogic(op, op1, op2);
    default:
      CMPASSERT("Operator type not supported by connect2" == 0);
      return NULL;
    }
}

// -----------------------------------------------------------------------
// ItemExpr::synthTypeAndValueId()
// -----------------------------------------------------------------------

void ItemExpr::synthTypeAndValueId(NABoolean redriveTypeSynthesisFlag, NABoolean redriveChildTypeSynthesis)
{
  // If the redriveTypeSynthesisFlag is set, it synthesises iself.
  // If the redriveChildTypeSynthesis is set, it synthesizes the
  // types for the entire subtree, from the leaves upto this operator,
  // once again.

  if (nodeIsBound() AND NOT redriveTypeSynthesisFlag) return;

  Int32 nc = getArity();

  // do it recursively on the children
  for (Lng32 i = 0; i < (Lng32)nc; i++)
    {
      if (child(i))
	{
	  // If it is an Item Expressions
	  child(i)->synthTypeAndValueId(redriveChildTypeSynthesis, redriveChildTypeSynthesis);
	  // refer to the child by its valueid instead of its pointer
	  child(i) = child(i)->getValueId();
	}
      // else leave the RelExpr alone
    }

  // Now do the non-recursive part
  synthTypeAndValueId2( redriveTypeSynthesisFlag, redriveChildTypeSynthesis );
  
} // ItemExpr::synthTypeAndValueId()

//
// ItemExpr::synthTypeAndValueId2() - a helper routine for synthTypeAndValueId()
// NOTE: The code for this routine came from the previous version of
//       ItemExpr::synthTypeAndValueId().  It was pulled out as a separate
//       routine so that the C++ compiler would generate code for
//       ItemExpr::synthTypeAndValueId() that used significantly less stack space.
//
void ItemExpr::synthTypeAndValueId2(NABoolean redriveTypeSynthesisFlag, NABoolean redriveChildTypeSynthesis)
{
  Int32 nc = getArity();
  ValueDesc *vdesc;
  DomainDesc *ddesc;

  // make sure the expression has a value id
  if (valId_ == NULL_VALUE_ID)
    {
      vdesc = new (CmpCommon::statementHeap()) ValueDesc(this);
      // remember the value id and the type in the node
      setValueId(vdesc->getValueId());
    }
  else
    {
      vdesc = valId_.getValueDesc();
    }

  // if the type hasn't been set or if type synthesis is to be
  // redriven, set the type to the synthesized value
  ddesc = vdesc->getDomainDesc();

  if (ddesc == NULL OR (nc > 0 AND redriveTypeSynthesisFlag))
    {
      const NAType *t = synthesizeType();
      // changed from CMPASSERT to CMPABORT, because it could be null
      // for several reasons. In most cases it is because of User error
      // where, the diagnostics would be filled with the error number.
      // In such cases it is wrong to raise an unnecessary alarm. If the
      // diagnostics buffer is not filled, then raise an exception
      if (!t)
	CMPABORT;

      // Fix for "BR0094.txt", here and in Case::bindNode().
      // Special handling is required for CASE because its operand
      // is not one of its children (because the operand can be a subquery,
      // which the normalizer needs to move).  And when that operand IS a subq,
      // then the CASE can return NULL if the subq produces zero rows.
      if (getOperatorType() == ITM_CASE &&
          ((Case *)this)->caseOperandWasNullable())
	t = t->synthesizeNullableType(CmpCommon::statementHeap());

      if (ddesc == NULL)
	{
	  ddesc = new (CmpCommon::statementHeap())
	    DomainDesc(ActiveSchemaDB(), *t);
	  vdesc->setDomainDesc(ddesc);
	}
      else
	{
	  getValueId().changeType(t);
	}
    }

  // mark me as bound
  markAsBound();
} // ItemExpr::synthTypeAndValueId2()

// -----------------------------------------------------------------------
// ItemExpr::isCovered()
// -----------------------------------------------------------------------
NABoolean ItemExpr::isCovered
                      (const ValueIdSet& newExternalInputs,
		       const GroupAttributes& coveringGA,
		       ValueIdSet& referencedInputs,
		       ValueIdSet& coveredSubExpr,
		       ValueIdSet& unCoveredExpr) const
{

  NABoolean exprIsCovered;

  switch (getArity())
    {
    case 0:

      exprIsCovered = FALSE;
      break;

    default:
      {
        exprIsCovered = TRUE;
	NABoolean coverFlag;
	Lng32 index, nc = getArity();

	for (index = 0; index < nc; index++)
	  {
	    coverFlag = coveringGA.covers(child(index)->getValueId(),
					  newExternalInputs,
					  referencedInputs,
					  &coveredSubExpr,
					  &unCoveredExpr);
	    if (coverFlag)
	      coveredSubExpr += ((ItemExpr *)child(index))->getValueId();
	    exprIsCovered &= coverFlag;
	  } // for i'th child of expr

	break;

      } // default

    } // switch(getArity())

  return exprIsCovered;

} // ItemExpr::isCovered()

OrderComparison ItemExpr::sameOrder(ItemExpr *other,
				    NABoolean askOther)
{
  // first, check whether the item expressions are identical
  if (this == other)
    return SAME_ORDER;

  // second, try to simplify both item expressions
  OrderComparison order1;
  OrderComparison order2;
  OrderComparison result;
  Int32 inversions = 0;

  ItemExpr *simpThis = simplifyOrderExpr(&order1);
  ItemExpr *simpOther = other->simplifyOrderExpr(&order2);

  // check whether the expressions actually got simplified, return
  // DIFFERENT order if that was not the case
  if (this == simpThis AND other == simpOther)
    return DIFFERENT_ORDER;

  // Recursively call sameOrder with the simplified expressions
  // If it is a VEG reference, need to do a cast of "simpOther" to type
  // VEGReference so that the implementation of sameOrder that accepts
  // a VEGReference "other" parameter will be called.
  if (simpOther->getOperatorType() == ITM_VEG_REFERENCE)
    result = simpThis->sameOrder((VEGReference *)simpOther,askOther);
  else
    result = simpThis->sameOrder(simpOther,askOther);

  if (result != DIFFERENT_ORDER)
    {
      // if the order is not different, add up all the inversions
      // we encountered, either from simplifying expressions or
      // by comparing them
      if (order1 == INVERSE_ORDER)
	inversions++;
      if (order2 == INVERSE_ORDER)
	inversions++;
      if (result == INVERSE_ORDER)
	inversions++;

      // if we inverted an even number of times then the two expressions
      // have the same order
      if (inversions == 0 OR inversions == 2)
	result = SAME_ORDER;
      else
	result = INVERSE_ORDER;
    }

  return result;
}

OrderComparison ItemExpr::sameOrder(VEGReference *other,
				    NABoolean askOther)
{
  // First, check whether the "this" item expression is identical
  // to the "other" VegReference
  if (this == other)
    return SAME_ORDER;

  // Second, go through the "other" VegReference members one at a
  // time, and call sameOrder recursively to see if one of the member
  // ItemExpr's is identical to "this".
  const ValueIdSet &equivValues = other->getVEG()->getAllValues();
  OrderComparison result = DIFFERENT_ORDER;

  for (ValueId x = equivValues.init();
       equivValues.next(x) AND result == DIFFERENT_ORDER;
       equivValues.advance(x))
    {
      result = sameOrder(x.getItemExpr(),askOther);
    }

  return result;
}


ItemExpr * ItemExpr::simplifyOrderExpr(OrderComparison *newOrder)
{
  // The default implementation assumes that it is not possible
  // to simplify an expression.
  if (newOrder)
    *newOrder = SAME_ORDER;
  return this;
}

ItemExpr * ItemExpr::removeInverseOrder()
{
  // The default implementation just returns a pointer to itself,
  // since obviously there is no inverse order operator to remove.
  return this;
}

OperatorTypeEnum ItemExpr::getInverseOpType() const
{
  switch (getOperatorType())
    {
    case ITM_EQUAL:
      return ITM_NOT_EQUAL;
    case ITM_NOT_EQUAL:
      return ITM_EQUAL;
    case ITM_LESS:
      return ITM_GREATER;
    case ITM_LESS_EQ:
      return ITM_GREATER_EQ;
    case ITM_GREATER:
      return ITM_LESS;
    case ITM_GREATER_EQ:
      return ITM_LESS_EQ;
    case ITM_IS_TRUE:
      return ITM_IS_FALSE;
    case ITM_IS_FALSE:
      return ITM_IS_TRUE;
    case ITM_IS_NULL:
      return ITM_IS_NOT_NULL;
    case ITM_IS_NOT_NULL:
      return ITM_IS_NULL;
    case ITM_IS_UNKNOWN:
      return ITM_IS_NOT_UNKNOWN;
    case ITM_IS_NOT_UNKNOWN:
      return ITM_IS_UNKNOWN;

    case ITM_RETURN_FALSE:
      return ITM_RETURN_TRUE;
    case ITM_RETURN_TRUE:
      return ITM_RETURN_FALSE;

    default:
      return (getOperatorType());
    }
}

NABoolean ItemExpr::isAColumnReference( )
  { return FALSE; }

// return true iff maxSelectivity(this) == selectivity(this)
NABoolean ItemExpr::maxSelectivitySameAsSelectivity() const
{ 
  switch (getOperatorType())
    {
    case ITM_EQUAL:
    case ITM_LESS:
    case ITM_LESS_EQ:
    case ITM_GREATER:
    case ITM_GREATER_EQ:
      if (getArity() > 1)
        {
          // maxSelectivity(any op constant) == selectivity(any op constant) 
          // maxSelectivity(constant op any) == selectivity(constant op any) 
          // when op is oneof: =, <, <=, >, >=
          NABoolean negate;
          ItemExpr * rhs = child(1);
          ItemExpr * lhs = child(0);
          if (rhs->getOperatorType() == ITM_CACHE_PARAM) 
             rhs = ((ConstantParameter *)rhs)->getConstVal();
          else
            rhs = rhs->castToConstValue( negate );

          if (lhs->getOperatorType() == ITM_CACHE_PARAM) 
             lhs = ((ConstantParameter *)lhs)->getConstVal();
          else
            lhs = lhs->castToConstValue( negate );
          return ((lhs != NULL) || (rhs != NULL));
        }
      break;
      // maxSelectivity(any <> constant) is 1.0
    case ITM_IS_NULL:
    case ITM_IS_UNKNOWN:
    case ITM_IS_NOT_NULL:
    case ITM_IS_NOT_UNKNOWN:
      // maxSelectivity(any is null)     == selectivity(any is null)
      // maxSelectivity(any is not null) == selectivity(any is not null)
      return TRUE;
    default:
      return FALSE;
    }
  return FALSE; 
}
void ItemExpr::print(FILE * f,
		     const char * prefix,
		     const char * suffix) const
{
#ifndef NDEBUG
  ExprNode::print(f,prefix,suffix);

#ifndef NDEBUG
  fprintf(f,"%sItem Expression (Value Id %d): ",prefix, (CollIndex) valId_);

  if ( valId_ != NULL_VALUE_ID && &(valId_.getType()) != NULL )
    fprintf( f, "%s", valId_.getType().getTypeSQLname().data() );

  fprintf( f, "\n" );
#else
  fprintf(f,"%sItem Expression (Value Id %d):\n",prefix, (CollIndex) valId_);
#endif

  // print children
  Int32 nc = getArity();
  for (Lng32 i = 0; i < (Lng32)nc; i++)
    {
      fprintf(f,"%sExpression input %d:\n",prefix,i);
      if (child(i).getPtr())
	child(i)->print(f,CONCAT(prefix,"    "));
      else
	fprintf(f,"%snonexistent child\n",prefix);
    }
#endif
}

void ItemExpr::display()
{
  NAString result;
  unparse(result, PARSER_PHASE, USER_FORMAT_DELUXE);
  fprintf(stdout, "%s\n", result.data());
}


//
// computeKwdAndFlags() - a helper routine for ItemExpr::unparse()
//
// NOTE: The code in this routine came from the previous version of
//       ItemExpr::unparse().   It has been pulled out into
//       a separate routine so that the C++ compiler will produce
//       code that needs signficantly less stack space for the
//       recursive ItemExpr::unparse() routine.
//
void ItemExpr::computeKwdAndFlags( NAString &kwd,
		                   NABoolean &prefixFns,
		                   NABoolean &specialPrefixFns,
		                   PhaseEnum phase,
		                   UnparseFormatEnum form,
		                   TableDesc * tabId ) const
{
  OperatorTypeEnum operatorType = getOperatorType();

  if ( operatorType == ITM_BASECOLUMN)
  {
    if (form == QUERY_FORMAT)
    {
      if (CmpCommon::getDefault(MVQR_LOG_QUERY_DESCRIPTORS) != DF_DUMP_MV)
        kwd = ((BaseColumn *)this)->getTextForQuery();
      else
        kwd = getText();
    }
    else if ((form == COMPUTED_COLUMN_FORMAT) ||
	     (form == HIVE_MD_FORMAT))
      kwd = ToAnsiIdentifier(((BaseColumn *)this)->getColName());
    else
      kwd = getText();
  }
  else if ( operatorType == ITM_RENAME_COL)
  {
    if (form == HIVE_MD_FORMAT)
      kwd = ((RenameCol *)this)->getNewColRefName()->getColName();
    else
      kwd = getText();
  }
  else if (operatorType == ITM_NAMED_TYPE_TO_ITEM)
  {
    kwd = ToAnsiIdentifier(((NamedTypeToItem *)this)->getText());
  }
  else if (( operatorType == ITM_CACHE_PARAM) &&
           (form == QUERY_FORMAT) )
    ((ConstantParameter *)this)->getConstVal()->unparse(kwd, phase, QUERY_FORMAT, tabId);
  else
    kwd = getText();

  if (form == USER_FORMAT_DELUXE)
    // Do not upcase if string literal or delimited ident.
    if (!strchr(kwd, '\"') && !strchr(kwd, '\'')) //"
    {
      TrimNAStringSpace(kwd);
      kwd.toUpper();
    }

  switch (operatorType)
  {
    case ITM_BITAND:
    case ITM_CAST:
    case ITM_CHAR_LENGTH:
    case ITM_EXTRACT:
    case ITM_LEFT:
    case ITM_MOD:    
    case ITM_MOVING_SDEV:
    case ITM_MOVING_VARIANCE:
    case ITM_OFFSET:
    case ITM_POSITION:
    case ITM_POWER:
    case ITM_STDDEV:
    case ITM_SUBSTR:
    case ITM_VARIANCE:
      prefixFns = TRUE;
      break;

    case ITM_DATEDIFF_YEAR:
    case ITM_DATEDIFF_QUARTER:
    case ITM_DATEDIFF_MONTH:
    case ITM_DATEDIFF_WEEK:
    case ITM_YEARWEEK:
    case ITM_YEARWEEKD:
      specialPrefixFns = TRUE;
      break;

    case ITM_PLUS:
    case ITM_MINUS:
      if (((BiArith *) this)->isDateMathFunction() &&
          (form == QUERY_FORMAT ||
           form == COMPUTED_COLUMN_FORMAT))
        {
          // this is not a regular addition or subtractions, it's
          // a datetime function with special handling of the last
          // day of the month
          specialPrefixFns = TRUE;
        }
  }
}
//
// computeKwdAndPostfix() - a helper routine for ItemExpr::unparse()
//
// NOTE: Either computes or augments kwd, depending on the item expr involved.
//
// NOTE: The code in this routine came from the previous version of
//       ItemExpr::unparse().   It has been pulled out into
//       a separate routine so that the C++ compiler will produce
//       code that needs signficantly less stack space for the
//       recursive ItemExpr::unparse() routine.
//
void ItemExpr::computeKwdAndPostfix( NAString &kwd,
                                     NAString &postfix,
                                     UnparseFormatEnum form ) const
{
        // print function syntax of the form <kwd> <children> <postfix>
        //     <fname>(<prefix-args,> <children> <,postfix-args>)
        //     <--------kwd--------->            <----postfix--->

        // handle special prefix argument cases by adding to 'kwd' and 'postfix'

        OperatorTypeEnum operatorType = getOperatorType();
        switch (operatorType)
          {
          case ITM_CAST:
            {
              if (form == QUERY_FORMAT || form == COMPUTED_COLUMN_FORMAT)
                {
                  kwd += "(";
                  postfix = " AS ";

                  // Get the Data type after the Cast
                  const NAType *naType = ((Cast *) this)->getType();

                  // ignore NULLs description in getTypeSQLName, since it
                  // does not return valid SQL syntax
                  postfix += naType->getTypeSQLname(TRUE);
                  if (!naType->supportsSQLnull())
                    postfix += " NOT NULL";
                  postfix += ")";
                }
              else
                kwd += "(";
            }
            break;

          case ITM_EXTRACT:
          case ITM_EXTRACT_ODBC:
            switch(((Extract*) this)->getExtractField())
              {
              case REC_DATE_YEAR:
                kwd = "YEAR(";
                break;
              case REC_DATE_MONTH:
                kwd = "MONTH(";
                break;
              case REC_DATE_DAY:
                kwd = "DAY(";
                break;
              case REC_DATE_HOUR:
                kwd = "HOUR(";
                break;
              case REC_DATE_MINUTE:
                kwd = "MINUTE(";
                break;
              case REC_DATE_SECOND:
                kwd = "SECOND(";
                break;
              case REC_DATE_YEARQUARTER_EXTRACT:
                kwd = "DATE_PART('YEARQUARTER',";
                break;
              case REC_DATE_YEARMONTH_EXTRACT:
                kwd = "DATE_PART('YEARMONTH',";
                break;
              case REC_DATE_YEARQUARTER_D_EXTRACT:
                kwd = "DATE_PART('YEARQUARTERD',";
                break;
              case REC_DATE_YEARMONTH_D_EXTRACT:
                kwd = "DATE_PART('YEARMONTHD',";
                break;
                // YEARWEEK gets transformed into ITM_YEARWEEK, see below
              default:
                kwd += "(";
                break;
              }
            break;

          case ITM_DATE_TRUNC_YEAR:
            kwd = "DATE_TRUNC('YEAR',";
            break;
          case ITM_DATE_TRUNC_MONTH:
            kwd = "DATE_TRUNC('MONTH',";
            break;
          case ITM_DATE_TRUNC_DAY:
            kwd = "DATE_TRUNC('DAY',";
            break;
          case ITM_DATE_TRUNC_HOUR:
            kwd = "DATE_TRUNC('HOUR',";
            break;
          case ITM_DATE_TRUNC_MINUTE:
            kwd = "DATE_TRUNC('MINUTE',";
            break;
          case ITM_DATE_TRUNC_SECOND:
            kwd = "DATE_TRUNC('SECOND',";
            break;
          case ITM_DATE_TRUNC_CENTURY:
            kwd = "DATE_TRUNC('CENTURY',";
            break;
          case ITM_DATE_TRUNC_DECADE:
            kwd = "DATE_TRUNC('DECADE',";
            break;
          case ITM_DATEDIFF_YEAR:
            kwd = "DATEDIFF(YEAR,";
            break;
          case ITM_DATEDIFF_QUARTER:
            kwd = "DATEDIFF(QUARTER,";
            break;
          case ITM_DATEDIFF_MONTH:
            kwd = "DATEDIFF(MONTH,";
            break;
          case ITM_DATEDIFF_WEEK:
            kwd = "DATEDIFF(WEEK,";
            break;
          case ITM_YEARWEEK:
            kwd = "DATE_PART('YEARWEEK',";
            break;
          case ITM_YEARWEEKD:
            kwd = "DATE_PART('YEARWEEKD',";
            break;

          case ITM_PLUS:
          case ITM_MINUS:
            // we come here for special datetime functions that
            // get represented by a + or - operator with
            // isStandardNormalization() set
            if (((BiArith *) this)->isStandardNormalization())
              {
                // Here are the original expressions and their transformations,
                // (+) and (-) indicate the +/- operators with the standard
                // normalization flag set:
                //
                // ADD_MONTHS(<datetime_expr>, <num_expr> [, 0])  ==>
                //                <datetime_expr> (+) CAST(<num_expr> AS INTERVAL MONTHS)
                // DATE_ADD(<datetime_expr>, <interval_expr>)  ==>
                //                <datetime_expr> (+) <interval_expr>
                // DATE_SUB(<datetime_expr>, <interval_expr>)  ==>
                //                <datetime_expr> (-) <interval_expr>
                // DATEADD(<keyword>, <num_expr>, <datetime_expr>)  ==>
                //                <datetime_expr> (+) CAST(<num_expr> AS ...)
                // TIMESTAMPADD(<keyword>, <num_expr>, <datetime_expr>)  ==>
                //                <datetime_expr> (+) CAST(<num_expr> AS ...)
                //
                // We unparse all those as the equivalent DATE_ADD and DATE_SUB
                // functions:
                if (operatorType == ITM_PLUS)
                  kwd = "DATE_ADD(";
                else
                  kwd = "DATE_SUB(";
              }
            else if (((BiArith *) this)->isKeepLastDay() && operatorType == ITM_PLUS)
              {
                // Here are the original expressions and their transformations,
                // (+) and (-) indicate the +/- operators with the "keep last day"
                // normalization flag set:
                //
                // ADD_MONTHS(<datetime_expr>, <num_expr>, 1)  ==>
                //                <datetime_expr> (+) CAST(<num_expr> AS INTERVAL MONTHS)
                CMPASSERT(child(1)->getValueId().getType().getTypeQualifier() == NA_INTERVAL_TYPE &&
                          child(1)->getValueId().getType().getFSDatatype() == REC_INT_MONTH);
                kwd = "ADD_MONTHS(";
                postfix = ", 1" + postfix;
              }
            else
              DCMPASSERT(FALSE); // the above should have covered all datetime math expressions
            break;

          default:
            kwd += "(";
            break;
          }
}

void ItemExpr::unparse(NAString &result,
		       PhaseEnum phase,
		       UnparseFormatEnum form,
		       TableDesc * tabId) const
{
  // Avoid creating large strings which will only be truncated later
  // by EXPLAIN.
  if (form == EXPLAIN_FORMAT && (result.length() > 4096)) 
  {
    return;
  }

  // Allocate 3 procedure local variables and initialize them here.
  // They may get changed by the call to ItemExpr::computeKwdAndFlags() 
  // which follows, but we initialize them here so source analysis
  // tools won't complain about unitialized variables.
  //
  NAString  kwd(CmpCommon::statementHeap());
  NABoolean prefixFns = FALSE;          // prefix function, some with infix, arity 2
  NABoolean specialPrefixFns = FALSE;   // require special prefix argument, arity 1 or 2

  computeKwdAndFlags( kwd, prefixFns, specialPrefixFns, phase, form, tabId );

  OperatorTypeEnum operatorType = getOperatorType();

  Int32 arity = getArity();

  if (operatorType != origOpType() &&
      form == QUERY_FORMAT ||
      form == COMPUTED_COLUMN_FORMAT)
    {
      // handle some cases where the original function was rewritten
      // in the binder, using a ZZZBinderFunction
      switch (origOpType())
        {
        case ITM_DATE_TRUNC_MINUTE:
        case ITM_DATE_TRUNC_SECOND:
        case ITM_DATE_TRUNC_MONTH:
        case ITM_DATE_TRUNC_HOUR:
        case ITM_DATE_TRUNC_CENTURY:
        case ITM_DATE_TRUNC_DECADE:
        case ITM_DATE_TRUNC_YEAR:
        case ITM_DATE_TRUNC_DAY:
        case ITM_DATEDIFF_YEAR:
        case ITM_DATEDIFF_QUARTER:
        case ITM_DATEDIFF_MONTH:
        case ITM_DATEDIFF_WEEK:
        case ITM_YEARWEEK:
        case ITM_YEARWEEKD:
          {
            ItemExpr *unboundExpr =
              ZZZBinderFunction::tryToUndoBindTransformation((ItemExpr *) this);
            if (unboundExpr)
              {
                // we were able to undo this transformation, unparse
                // the ZZZBinderFunction instead
                unboundExpr->unparse(result,
                                     phase,
                                     form,
                                     tabId);
                return;
              }
          }
          break;
          
        default:
          break;
        }
    }

  switch (arity)
  {
    case 0:
      // simply print the text out for a leaf operator
      result += kwd;
      break;

    case 2:
      if (form != FILE_FORMAT && !specialPrefixFns)
      {
        if( ((form == MV_SHOWDDL_FORMAT) || 
             (form == QUERY_FORMAT) ||
             (form == COMPUTED_COLUMN_FORMAT)) && 
             prefixFns )
        {
          result += kwd;
          result += "(";

          if (child(0))
            child(0)->unparse(result, phase,form, tabId);
          else
            result += "NULL";

          if (operatorType == ITM_POSITION)
            result += " IN ";
          else
            result += ", ";

          if (child(1))
            child(1)->unparse(result, phase, form, tabId);
          else
            result += "NULL";
          result += ")";
          break;
        } // STDDEV, MOD, VARIANCE
        else  
          if ( (operatorType == ITM_TRIM)  && 
               ((form == QUERY_FORMAT) ||
                (form == COMPUTED_COLUMN_FORMAT)))
        {
          result += kwd;
          result += "(";
          child(1)->unparse(result,phase,form,tabId);
          result += ")";
        } 
        else 
          if((operatorType == ITM_ITEM_LIST ||
          operatorType == ITM_AND) &&
          (form != MV_SHOWDDL_FORMAT) &&
          (form != QUERY_FORMAT) )
          {
            if (child(0))
              child(0)->unparse(result,phase,form, tabId);
            else
              result += "NULL";

            if (operatorType != ITM_ITEM_LIST)
              result += " ";
            result += kwd;
            result += " ";

            if (child(1))
              child(1)->unparse(result,phase,form, tabId);
            else
              result += "NULL";
          }
          else
          {
            // assume this is an infix operator (<child0>) op (<child1>)

            result += "(";

            NABoolean list0 = FALSE, list1 = FALSE;
            if (operatorType != ITM_ITEM_LIST)
            {
              list0 = child(0)->getOperatorType() == ITM_ITEM_LIST;
              list1 = child(1)->getOperatorType() == ITM_ITEM_LIST;
            }

            if (list0) result += "(";
            child(0)->unparse(result,phase,form, tabId);
            if (list0) result += ")";

            result += " ";
            result += kwd;
            result += " ";

            if (list1) result += "(";
            child(1)->unparse(result,phase,form, tabId);
            if (list1) result += ")";

            result += ")";
          } // infix operator
          break; // for now, break here
        } 
    // otherwise fall through to next case

    default:
    {
      // usually, that's arity 1, but can be >1 as well
      if (form == USER_FORMAT_DELUXE && isQuantifiedComp(this))
      {
        child(0)->unparse(result,phase,form, tabId);
        result += " ";
        result += kwd;
        result += " (_subquery_)";
      } // QuantifiedComp
      else if (arity == 1 && isAPredicate() && operatorType != ITM_NOT)
      {
        child(0)->unparse(result,phase,form,tabId);
        result += " ";
        result += kwd;
      } // predicate and != ITM_NOT
      else if (form == MV_SHOWDDL_FORMAT && operatorType == ITM_RENAME_COL)
      {
        child(0)->unparse(result, phase, form, tabId);
      }
      else if (form == MV_SHOWDDL_FORMAT && operatorType == ITM_COUNT_NONULL)
      {
        result += "count(";
        child(0)->unparse(result, phase, form, tabId);
        result += ")";
      }
      else if (form == MV_SHOWDDL_FORMAT && operatorType == ITM_COUNT)
      {
        result += "count(*)";
      }
      else
      {
        NAString postfix = ")";

        computeKwdAndPostfix( kwd, postfix, form );

        // function name, open parenthesis, initial arguments
        result += kwd;

        // unparse all the children as arguments
        for (Lng32 i = 0; i < (Lng32)arity; i++)
          {
            if (i > 0) result += ", ";
            child(i)->unparse(result,phase,form,tabId);
          }

        // add any postfix and closing parenthesis
        result += postfix;
      } // else (print function syntax)
    } // default of switch(arity)
  } // end switch (arity)
} // ItemExpr::unparse

// MDAMR
DisjunctArray * ItemExpr::mdamTreeWalk()
{

  DisjunctArray * rc = new STMTHEAP DisjunctArray(new STMTHEAP ValueIdSet(getValueId()));
  return rc;
}
//MDAMR

NABoolean ItemExpr::equatesToAConstant() const
{
  if (getOperatorType() != ITM_EQUAL)
    return FALSE;

  ItemExpr *lhs = child(0);
  lhs = lhs->getLeafValueIfUseStats();

  if(lhs->getOperatorType() != ITM_VEG_REFERENCE)
    return FALSE;

  ItemExpr *rhs = child(1);
  rhs = rhs->getLeafValueIfUseStats();

  if (rhs->getOperatorType() == ITM_CACHE_PARAM)
    return TRUE;

  if(!rhs->doesExprEvaluateToConstant(TRUE, TRUE))
     return FALSE;

  return TRUE;
}

// The check performed to determine if a column 
// exists works only till binder phase. For use 
// in post-Binder phase, the logic in the method 
// will have to be changed.
NABoolean ItemExpr::containsColumn()
{
  OperatorTypeEnum op = getOperatorType();

  // This is a base column.
  if (op == ITM_BASECOLUMN)
    return TRUE;

  // This is a leaf item other than a base column.
  if (op >= ITM_CONSTANT && op <= ITM_VEG_REFERENCE)
    return FALSE;

  // Iterate through this item's inputs looking for a base column.
  for (Int32 i = 0; i < getArity(); i++) {
    ItemExpr *expr = child(i);

    if (!expr)
      return FALSE;

    if (expr->containsColumn())
      return TRUE;
  }

  return FALSE;
}

//++MV
// -----------------------------------------------------------------------
// Return the default selectivity for this predicate
// -----------------------------------------------------------------------
double ItemExpr::defaultSel()
{
  if (selectivityFactor_ < 0)
    return getOperatorType() == ITM_RETURN_FALSE ? 0.0 : 1.0;
  else
    return selectivityFactor_;
}
//--MV

ItemExpr * ItemExpr::containsRightmost(const ItemExpr *ie)
{
  if (this == ie) return this;
  if (!this || !ie) return NULL;
  for (Int32 arity = getArity(); arity-- > 0; )
    if (child(arity))
      return (child(arity) == ie) ? this : child(arity)->containsRightmost(ie);
  return NULL;
}

NABoolean ItemExpr::hasEquivalentProperties(ItemExpr * other)
{
  if (other == NULL )
    return FALSE;

  CMPASSERT(other->getValueId() != NULL_VALUE_ID && getValueId() != NULL_VALUE_ID);
  //defaults behavior is return false
  return FALSE;
}

NABoolean ItemExpr::hasBaseEquivalence(ItemExpr * other)
{
  if (other == NULL)
    return FALSE;

  CMPASSERT(other->getValueId() != NULL_VALUE_ID && this->getValueId()!= NULL_VALUE_ID);
  
  if (getOperatorType() != other->getOperatorType() || 
        getArity() != other->getArity())
    return FALSE;

  if (getValueId()== other->getValueId() ||
      (getOperatorType() == ITM_CONSTANT && ((ConstValue*)this)->isNull() && ((ConstValue*)other)->isNull()))
    return TRUE;
  else
    if (getArity()==0)
      return FALSE;

  for (Int32 i= 0 ; i < getArity(); i++)
  {
    ItemExpr * chld= child(i);
    if (!chld->hasBaseEquivalence(other->child(i)) || !chld->hasEquivalentProperties(other->child(i)) )
      return FALSE;
  }
  return TRUE;
}//ItemExpr::hasBaseEquivalence(ValueId otherId)


ItemExpr * ItemExpr::changeDefaultOrderToDesc()
{
  if (getOperatorType() == ITM_ITEM_LIST )
  {
    for(Int32 i=0; i<getArity(); i++)
    {
      child(i) = child(i)->changeDefaultOrderToDesc();
    }
    return this;
  }
  else
    if (getOperatorType()== ITM_INVERSE)
    {
      if (child(0)->getOperatorType() == ITM_INVERSE)
        return child(0)->child(0);
      else
        return this;
    }
    else
      return new (CmpCommon::statementHeap()) InverseOrder(this);
  }//ItemExpr::changeDefaultOrderToDesc()

ValueId ItemExpr::removeInverseFromExprTree( NABoolean & invExists)
{
  if (getOperatorType() == ITM_ITEM_LIST )
  {
    for(Int32 i=0; i<getArity(); i++)
      child(i) = child(i)->removeInverseFromExprTree(invExists);
    return getValueId();
  }
  else
      if (getOperatorType() == ITM_INVERSE)
        invExists = TRUE;
      return removeInverseOrder()->removeInverseOrder()->getValueId(); 

 }//ItemExpr::removeInverseFromExprTree()

///


void ItemExpr::transformOlapFunctions(CollHeap *wHeap)
{

  for (Int32 i= 0 ; i < getArity(); i++)
  {
    ItemExpr * mychild= child(i);
    if (mychild->isOlapFunction())
    {
      ItmSeqOlapFunction * olap = (ItmSeqOlapFunction*) mychild;
      ItemExpr * itmExpr = olap->transformOlapFunction(wHeap);
      itmExpr->synthTypeAndValueId(TRUE);
      child(i) = itmExpr;
    }
    //else  //olap function can t have another olap as descendant ????
   // {
    //  child(i)->transformOlapFunctions(wHeap);
    //}
    child(i)->transformOlapFunctions(wHeap);
  }

}//void ItemExpr::transformOlapFunctions(CollHeap *wHeap)


// -----------------------------------------------------------------------
// removeInverseFromExprTree
//
// overloading above method for special purpose use
// onlyDouble parameter is used when the Inverse should not be removed 
// unless two Inverse exprs are found in a row
// -----------------------------------------------------------------------
ItemExpr* 
ItemExpr::removeInverseFromExprTree( NABoolean & invExists,
                                     const NABoolean onlyDouble )
{
  if (getOperatorType() == ITM_ITEM_LIST )
  {
    for(Int32 i=0; i<getArity(); i++)
      child(i) = child(i)->removeInverseFromExprTree(invExists,
                                                     onlyDouble);
    return this;
  }
  else
  {
    if (getOperatorType() == ITM_INVERSE)
      invExists = TRUE;

    // if the onlyDouble flag is set to TRUE, then we
    // must find two Inverse exprs in a row to remove
    if( (!onlyDouble) ||
        getOperator().match(ITM_INVERSE) &&
        child(0)->getOperator().match(ITM_INVERSE) )
    {
      return removeInverseOrder()->removeInverseOrder();
    }
    else
    {
      return this;
    }
  }
 }//ItemExpr::removeInverseFromExprTree()

//


 void ItemExpr::removeNotCoveredFromExprTree(ItemExpr * &ie ,
                                             const ValueIdSet &seqColumns,
                                             NABoolean rootNode)
{
  if (rootNode)
  { 
    while (ie->getOperatorType() == ITM_NOTCOVERED && 
           seqColumns.contains(ie->getValueId()))
    {
      ie= ie->child(0);
    }
  }
 
  for(Int32 i=0; i<ie->getArity(); i++)
  {
    while (ie->child(i)->getOperatorType() == ITM_NOTCOVERED && 
      seqColumns.contains(ie->child(i)->getValueId()))
    {
      ie->child(i) = ie->child(i)->child(0);
    }
    ItemExpr * tmp = ie->child(i);
    removeNotCoveredFromExprTree(tmp,seqColumns, FALSE);
  }

}//ItemExpr::removeNotCoveredFromExprTree()

// -----------------------------------------------------------------------
// member functions for class ZZZBinderFunction
// -----------------------------------------------------------------------
ItemExpr *ZZZBinderFunction::copyTopNode(ItemExpr *derivedNode,
                                         CollHeap *outHeap)
{
  ItemExpr *result=0;

  if (derivedNode == NULL)
   {
    switch (getArity())
     {
       case 1:
               result = new (outHeap) ZZZBinderFunction(getOperatorType(),
                            child(0));
         break;
       case 2:
               result = new (outHeap) ZZZBinderFunction(getOperatorType(),
                            child(0), child(1));
         break;
       case 3:
               result = new (outHeap) ZZZBinderFunction(getOperatorType(),
                            child(0), child(1), child(2));
         break;
       case 4:
               result = new (outHeap) ZZZBinderFunction(getOperatorType(),
                            child(0), child(1), child(2), child(3));
         break;
       case 5:
               result = new (outHeap) ZZZBinderFunction(getOperatorType(),
                             child(0), child(1), child(2), child(3), child(4));
         break;
     } // switch
   }
  else
   {
    result = derivedNode;
   }

  return BuiltinFunction::copyTopNode(result, outHeap);
}

// -----------------------------------------------------------------------
// member functions for class BiArith
// -----------------------------------------------------------------------
Int32 BiArith::getArity() const { return 2;}

const NAString BiArith::getText() const
{
  switch (getOperatorType())
    {
    case ITM_PLUS:
      return "+";
    case ITM_MINUS:
      return "-";
    case ITM_TIMES:
      return "*";
    case ITM_DIVIDE:
      return "/";
    case ITM_EXPONENT:
      return "**";
    default:
      return "unknown BiArith";
    } // switch
} // BiArith::getText()

NABoolean BiArith::duplicateMatch(const ItemExpr& other) const
{
  if (NOT genericDuplicateMatch(other))
    return FALSE;

  const BiArith &o = (BiArith &) other;
  if (unaryNegate_ != o.unaryNegate_)
    return FALSE;

  if (normalizeFlags_ != o.normalizeFlags_ )
    return FALSE;

  if (intervalQualifier_ OR o.intervalQualifier_)
    {
      if (intervalQualifier_ == NULL OR
	  o.intervalQualifier_ == NULL OR
	  NOT (*intervalQualifier_ == *(o.intervalQualifier_)))
	return FALSE;
    }
  return TRUE;
}

ItemExpr * BiArith::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  BiArith *result;
  BiArith  *result2;

  if (derivedNode == NULL)
    result = new (outHeap) BiArith(getOperatorType());
  else
    result = (BiArith*)derivedNode;

  result->setRoundingMode(getRoundingMode());
  if ( ignoreSpecialRounding() ) result->setIgnoreSpecialRounding();
  result->setDivToDownscale(getDivToDownscale());

  result2 = (BiArith *)ItemExpr::copyTopNode(result, outHeap);
  result2->normalizeFlags_ = normalizeFlags_ ;
  return result2;
}

ItemExpr * BiArithSum::copyTopNode(ItemExpr *derivedNode, CollHeap *outHeap)
{
  ItemExpr *result;
  if (derivedNode == NULL)
    result = new (outHeap) BiArithSum(getOperatorType());
  else
    result = derivedNode;

  return ItemExpr::copyTopNode(result, outHeap);
}

ConstValue * BiArith::castToConstValue (NABoolean & negate_it)
{
  OperatorTypeEnum op = getOperatorType();

  if ((op == ITM_MINUS) || (op == ITM_PLUS))
  {
    NABoolean neg0 = FALSE;
    NABoolean neg1 = FALSE;
    ConstValue * lhs = child(0)->castToConstValue(neg0);
    ConstValue * rhs = child(1)->castToConstValue(neg1);

    if (lhs && rhs)
    {
      Lng32 scale0 = 0;
      if (lhs->canGetExactNumericValue() &&
          lhs->getExactNumericValue(scale0) == 0)
        {
          if (op == ITM_MINUS)
            negate_it = (!neg1);
          else
            negate_it = neg1;
          return (rhs);
        }
      else
      {
        Lng32 scale1 = 0;
        if (rhs->canGetExactNumericValue() &&
            rhs->getExactNumericValue(scale1) == 0)
          {
            negate_it = neg0;
            return (lhs);
          }
      }
    }
  }
  return NULL;
}

/*--------------------------------------------------------------
* this routine is mainly called by complifyAndRemoveUncoveredSuffix(),
* sameOrder() and shortCutGroupBy::topMatch() to find out if a
* simplified expression still has the same order or if it has inverse
* order. Based on this we decide to do a inverse scan or a forward
* scan to satisfy order by or min/max aggregate.
*-----------------------------------------------------------------*/
ItemExpr * BiArith::simplifyOrderExpr(OrderComparison *newOrder)
{
  ItemExpr *result = this;
  OrderComparison myOrder = SAME_ORDER;
  OrderComparison childOrder = SAME_ORDER;


  // - the following expressions are simplified and
  //   has the same order as "a"
  //     a + const
  //     const + a
  //     a - const
  //     a * positive const
  //     positive const * a
  //     a / positive const
  // - the following expressions have the inverse order of "a"
  // and are siplified
  //     const - a
  //     a * negative const
  //     negative const * a
  //     a / negative const
  // - the following expressions are not simplified because
  //  the order is not consistent
  // positive const / a
  // negative const / a
  //
  // example:
  //
  //   values for a : -2 , -1, 1, 2, 3
  //
  //  if we say that 1/a is inverse order of a
  // then a order by of 1/a results in
  //
  //    (ordering of a    1/a          but the correct order
  //     if we simplify)                would be
  //	3	             .33             -1     -1
  //    2                .5				-.5    -2
  //	1                 1             .33    3
  //	-1                -1            .5     2
  //    -2                -.5            1     1
  //
  //Note: as long as 'a' is an unsigned integer we can simplify but
  //      it is to rare an occasion that a user does 1/a or -1/a so
  //      it is not supported.


  if (child(0)->getOperatorType() == ITM_CONSTANT)
    {
      switch (getOperatorType())
	{
	case ITM_PLUS:
	  result = child(1)->simplifyOrderExpr(&childOrder);
	  myOrder = SAME_ORDER;
	  break;

	case ITM_MINUS:
	  result = child(1)->simplifyOrderExpr(&childOrder);
	  myOrder = INVERSE_ORDER;
	  break;

	case ITM_TIMES:
	  result = child(1)->simplifyOrderExpr(&childOrder);
	  break;

	case ITM_DIVIDE:
      break;

	default:
	  break;
	}
    }
  else if (child(1)->getOperatorType() == ITM_CONSTANT)
    {
      switch (getOperatorType())
	{
	case ITM_PLUS:
	case ITM_MINUS:
	  result = child(0)->simplifyOrderExpr(&childOrder);
	  myOrder = SAME_ORDER;
	  break;

	case ITM_TIMES:
	  result = child(0)->simplifyOrderExpr(&childOrder);
	  break;

	case ITM_DIVIDE:
      // part of fix to genesis case 10-070416-0218, soln 10-070416-4141
      // mxcmp must consider ORDER BY "v/const" incompatible with GROUP BY "v"
      // when "v/const" can lose precision relative to "v"
      if (getRoundingMode() != 0 &&
          CmpCommon::getDefault(COMP_BOOL_176) == DF_OFF)
        {
          // do NOT simplify. leave expr as is.
          break;
        }
      else
        {
          result = child(0)->simplifyOrderExpr(&childOrder);
        }
	  break;

	default:
	  break;
	}
    }
  else if (child(0)->getOperatorType() == ITM_MINUS AND
	  child(0)->child(0)->getOperatorType() == ITM_CONSTANT
	  AND child(0)->child(1)->getOperatorType() == ITM_CONSTANT
	  AND *(short *)((ConstValue *)((ItemExpr*)(child(0)->child(0))))->getConstValue()==0
	  )

  {
	  ItemExpr * constExpr = child(0)->child(1);
	  switch(getOperatorType())
	  {
	  case ITM_TIMES:
		  result = child(1)->simplifyOrderExpr(&childOrder);
		  myOrder = INVERSE_ORDER;
		  break;
	  case ITM_DIVIDE:
		  break;
	  }
  }
  else if (child(1)->getOperatorType() == ITM_MINUS AND
	  child(1)->child(0)->getOperatorType() == ITM_CONSTANT
	  AND child(1)->child(1)->getOperatorType() == ITM_CONSTANT
	  AND *(short *)((ConstValue *)((ItemExpr*)(child(1)->child(0))))->getConstValue()==0
	  )

  {
	  switch(getOperatorType())
	  {
	  case ITM_TIMES:
		  result = child(0)->simplifyOrderExpr(&childOrder);
		  myOrder = INVERSE_ORDER;
		  break;
	  case ITM_DIVIDE:
        // part of fix to genesis case 10-070416-0218, soln 10-070416-4141
        // mxcmp must consider ORDER BY "v/-const" incompatible 
        // with GROUP BY "v"
        // when "v/-const" can lose precision relative to "v"
        if (getRoundingMode() != 0 &&
            CmpCommon::getDefault(COMP_BOOL_176) == DF_OFF)
          {
            // do NOT simplify. leave expr as is.
            break;
          }
        else
          {
            result = child(0)->simplifyOrderExpr(&childOrder);
            myOrder = INVERSE_ORDER;
          }
		  break;
	  }

  }

  // return results
  if (newOrder)
    {
      // if both this and the child inverse or leave the order the
      // net result is the same order, otherwise we inverse the order once
      if (myOrder == childOrder)
	*newOrder = SAME_ORDER;
      else
	*newOrder = INVERSE_ORDER;
    }
  return result;
}

ItemExpr * BiArith::foldConstants(ComDiagsArea *diagsArea,
				  NABoolean newTypeSynthesis)
{
  ItemExpr *result = this;

  // attempt to do constant arithmetic if both operands are constants
  // and if we are allowed to pick the result type
  if (child(0)->getOperatorType() == ITM_CONSTANT AND
      child(1)->getOperatorType() == ITM_CONSTANT AND
      newTypeSynthesis)
    {
      // get the two operands into two Int64 variables if possible
      Int64 ops[2] = {0,0};
      Lng32 scales[2] = {0,0};
      Int64 numResult = 0;
      NABoolean canDoIt = TRUE; // give up once it becomes too difficult
      scales[0] = 0;  scales[1] = 0;
      ops[0] = 0;  ops[1] = 0;

      for (Int32 i = 0; i < 2 AND canDoIt; i++)
	{
	  NABoolean negate;
	  ConstValue *cv = child(i)->castToConstValue(negate);
	  if (cv AND cv->canGetExactNumericValue())
	    {
	      CMPASSERT(NOT negate);
	      ops[i] = cv->getExactNumericValue(scales[i]);
	    }
	  else
	    {
	      // can't do it yet if this isn't represented as a signed
	      // or unsigned binary number without any additional fluff
	      canDoIt = FALSE;
	    }
	}

      // -----------------------------------------------------------------
      // At this point, ops contains two 64 bit numbers that represent the
      // exact numeric operands. scales contains the scales of the operands.
      // Now do the arithmetic, but try not to cause overflow traps.
      // -----------------------------------------------------------------

      // for now, give up on any values with a scale != 0
      if (scales[0] != 0 OR scales[1] != 0)
	canDoIt = FALSE;

      if (canDoIt)
	{
	  // adjust scales, if necessary
	  switch (getOperatorType())
	    {
	    case ITM_PLUS:
	    case ITM_MINUS:
	      if (scales[0] != scales[1])
		// sorry, keep it simple for now
		canDoIt = FALSE;
	      break;

	    default:
	      break;
	    }
	}

      NABoolean overflow = FALSE;
      NABoolean zeroDivide = FALSE;

      // check for overflow
      // for now, just do it for reasonably small constants
      if (ops[0] < -10000000 OR ops[0] > 10000000 OR
	  ops[1] < -10000000 OR ops[1] > 10000000)
	canDoIt = FALSE;

      // -----------------------------------------------------------------
      // ok, now it's time to do the real thing
      // -----------------------------------------------------------------

      if (canDoIt AND NOT overflow)
	{
	  switch (getOperatorType())
	    {
	    case ITM_PLUS:
	      numResult = ops[0] + ops[1];
	      break;

	    case ITM_MINUS:
	      numResult = ops[0] - ops[1];
	      break;

	    case ITM_TIMES:
	      numResult = ops[0] * ops[1];
	      break;

	    case ITM_DIVIDE:
	      if (ops[1] == 0)
		zeroDivide = TRUE;
	      else
		numResult = ops[0] / ops[1];
	      break;
	    }
	}

      // error handling
      if (canDoIt AND (overflow OR zeroDivide))
	{
          NAString up(CmpCommon::statementHeap());
	  unparse(up);
	  *diagsArea << DgSqlCode(zeroDivide ? -4075 : -4076) << DgString0(up);
	  canDoIt = FALSE;
	}

      if (canDoIt)
	{
	  // now we're ready to do the switch

          if (numResult >= INT_MIN AND numResult <= INT_MAX)
	    {
	      // result can fit into a long, use the ConstValue(long)
	      // constructor
	      Lng32 num;

	      num = (Lng32) numResult;
	      result = new(CmpCommon::statementHeap()) SystemLiteral(num);
	    }
	  else
	    {
	      // the result becomes an 8 byte integer, use the ConstValue
	      // constructor with a type, the binary image, and a text string

	      char numstr[TEXT_DISPLAY_LENGTH];
	      convertInt64ToAscii(numResult,numstr);
              NAString runningOutOfNames(numstr, CmpCommon::statementHeap());

	      result = new(CmpCommon::statementHeap()) SystemLiteral(
		   new(CmpCommon::statementHeap()) SQLLargeInt(CmpCommon::statementHeap(), TRUE,FALSE),
		   (void *) &numResult,
		   sizeof(numResult),
		   &runningOutOfNames);
	    }
	}
    }

  // perform the generic tasks (recursion, type synthesis) on the
  // result, regardless of whether we transformed it or not
  return result->ItemExpr::foldConstants(diagsArea,newTypeSynthesis);
}


NABoolean BiArith::isEquivalentForCodeGeneration(const ItemExpr * other)
  {
  NABoolean rc = FALSE;        // assume failure

  if (hasBaseEquivalenceForCodeGeneration(other))
    {
    // we know that other is a BiArith, its operator type is the same,
    // and that the children are equivalent
    BiArith * otherBiArith = (BiArith *)other;

    if ( (unaryNegate_ == otherBiArith->unaryNegate_) &&
         (normalizeFlags_ == otherBiArith->normalizeFlags_ ) )
      {
      // make sure both have the same interval qualifier (if any)
      NABoolean sameIntervalQualifier = FALSE;  // assume failure
      if (intervalQualifier_)
        {
        if (otherBiArith->intervalQualifier_)
          {
          const NAType & otherIntervalQualifier = *(otherBiArith->intervalQualifier_);
          if (intervalQualifier_->operator==(otherIntervalQualifier))
            sameIntervalQualifier = TRUE;
          }
        }
      else if (otherBiArith->intervalQualifier_ == 0)
        sameIntervalQualifier = TRUE;

      if (sameIntervalQualifier)
        {
        // the next test distinguishes between BiArith and its special-case
        // inheriting classes, BiArithSum and BiArithCount
	if (getText() == otherBiArith->getText())  // same class?
          rc = TRUE;  // the two values can be produced by the same generated expr
        }
      }
    }

  return rc;
  }

QR::ExprElement BiArith::getQRExprElem() const
{
  return QR::QRBinaryOperElem;
}

NABoolean BiArith::hasEquivalentProperties(ItemExpr * other)
{  
  if (other == NULL)    
    return FALSE;  
  if (getOperatorType() != other->getOperatorType() ||     
    getArity() != other->getArity())    
    return FALSE;    
  
  BiArith * otherBiArith = (BiArith *) other;    
  
  return     
    (this->unaryNegate_ == otherBiArith->unaryNegate_) &&     
    (this->normalizeFlags_ == otherBiArith->normalizeFlags_) &&    
    (this->intervalQualifier_ == otherBiArith->intervalQualifier_) &&    
    (this->divToDownscale_ == otherBiArith->divToDownscale_);
}

ItemExpr * UnArith::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  UnArith *result;

  if (derivedNode == NULL)
    result = new (outHeap) UnArith();
  else
    result = (UnArith*)derivedNode;

  return result;
}

// -----------------------------------------------------------------------
// member functions for class ColReference
// -----------------------------------------------------------------------
Int32 ColReference::getArity() const { return 0; }

const NAString ColReference::getText() const
{
  NAColumn *nacol = getValueId() != NULL_VALUE_ID ?
    getValueId().getNAColumn() :
    NULL;
  return nacol ?
    nacol->getFullColRefNameAsAnsiString() :
    colRefName_->getColRefAsAnsiString();
}

HashValue ColReference::topHash()
{
  HashValue result = ItemExpr::topHash();

  // hash any local data members of the derived class
  result ^= colRefName_->getColRefAsString();

  return result;
}

NABoolean ColReference::duplicateMatch(const ItemExpr & other) const
{
  if (NOT genericDuplicateMatch(other))
    return FALSE;

  ColReference &o = (ColReference &) other;

  // compare any local data members of the derived class
  // and return FALSE if they don't match
  if (NOT (*colRefName_ == *(o.colRefName_)))
    return FALSE;

  return TRUE;
}

ItemExpr * ColReference::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL)
  {
    ColRefName *colName;
    if (colRefName_->isStar())
    {
      colName = new (outHeap) ColRefName(1);
    }
    else
    {
      colName = new (outHeap)
	ColRefName(colRefName_->getColName(),
		   colRefName_->getCorrNameObj(),
		   outHeap);
    }
    ColReference *newColRef = new (outHeap) ColReference(colName);
    newColRef->setTargetColumnClass(getTargetColumnClass());
    result = newColRef;
  }
  else
    result = derivedNode;

  return ItemExpr::copyTopNode(result, outHeap);
}

// -----------------------------------------------------------------------
// member functions for class HostVar
// -----------------------------------------------------------------------

HostVar::HostVar(const HostVar &hv)
       : ItemExpr(hv.getOperatorType()),
	 varName_(hv.varName_, CmpCommon::statementHeap()),
	 indicatorName_(hv.indicatorName_, CmpCommon::statementHeap()),
	 prototypeValue_(hv.prototypeValue_, CmpCommon::statementHeap()),
	 prototypeType_(hv.prototypeType_),
	 isEnvVar_(hv.isEnvVar_), isDefine_(hv.isDefine_),
	 isSystemGenerated_(hv.isSystemGenerated_),
	 paramMode_ (hv.paramMode_),
	 ordinalPosition_ (hv.ordinalPosition_),
	 hvIndex_ (hv.hvIndex_),
	 rowsetInfo_(hv.rowsetInfo_),
	 heading_(hv.heading_, CmpCommon::statementHeap()),
	 tablename_(hv.tablename_,CmpCommon::statementHeap())
{
  if (hv.varType_ == NULL)
     varType_ = NULL;
  else
     varType_ = hv.varType_->newCopy(CmpCommon::statementHeap());
}

Int32 HostVar::getArity() const { return 0; }

NABoolean HostVar::isAUserSuppliedInput() const             { return TRUE; }

const NAString HostVar::getText() const
{
  NAString punc(CmpCommon::statementHeap());
  if (isSystemGenerated_) punc = "\\:";			// backslash, colon
  if (!indicatorName_.isNull())
    return punc + varName_ + " " + punc + indicatorName_;
  else
    return punc + varName_;
}

HashValue HostVar::topHash()
{
  HashValue result = ItemExpr::topHash();

  // hash any local data members of the derived class
  result ^= (CollIndex) getValueId();

  return result;
}

NABoolean HostVar::duplicateMatch(const ItemExpr & other) const
{
  // rely on value id comparison since the binder should not
  // assign different value ids for the same hostvar
  return genericDuplicateMatch(other);
}

ItemExpr * HostVar::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL)
    result = new (outHeap) HostVar(*this);
  else
    result = derivedNode;

  return ItemExpr::copyTopNode(result, outHeap);
}

NABoolean HostVar::isCharTypeMatchRulesRelaxable()
{
  if ( getType()->getTypeQualifier() == NA_CHARACTER_TYPE &&
       ((CharType*)getType())->getCharSet() == CharInfo::UNICODE
     )
    return TRUE;
  else
    return FALSE;
}

ItemExpr * DefaultSpecification::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL)
    result = new (outHeap) DefaultSpecification();
  else
    result = derivedNode;

  return ItemExpr::copyTopNode(result, outHeap);
}



NABoolean RowsetArrayScan::isCharTypeMatchRulesRelaxable()
{
  if ( getOperatorType() == ITM_ROWSETARRAY_SCAN &&
       getType()->getTypeQualifier() == NA_CHARACTER_TYPE &&
       ((CharType*)getType())->getCharSet() == CharInfo::UNICODE
     )
    return TRUE;
  else
    return FALSE;
}

// -----------------------------------------------------------------------
// member functions for class ConstantParameter
// -----------------------------------------------------------------------
ConstantParameter::ConstantParameter(const ConstValue& v, NAMemory *h,
                                     NABoolean quantizeLen, UInt32 p)
  : val_((ConstValue*)&v), type_(CONST_CAST(NAType*, v.getType()))
  , Parameter(ITM_CACHE_PARAM)
{
  if (type_->getTypeQualifier() != NA_CHARACTER_TYPE) {
    type_ = type_->newCopy(h);
  }
  else {
    // convert char type to equivalent varchar type
    type_ = ((CharType*)type_)->equivalentVarCharType(h, quantizeLen);
  }
  posns_ = new(STMTHEAP) ClusteredBitmap(STMTHEAP);
  *posns_ += p;
}

ConstantParameter::ConstantParameter(ConstValue* v, NAMemory *h,
                                     const NAType* typ, UInt32 p)
  : val_(v), type_(typ->newCopy(h)), Parameter(ITM_CACHE_PARAM)
{
  // non-null ConstantParameters are non-nullable
  type_->setNullable(v->isNull());

  if (v->getType()->getTypeQualifier() == NA_CHARACTER_TYPE &&
      type_->getTypeQualifier() == NA_CHARACTER_TYPE) {
    // this is part of a fix to genesis case: 10-010618-3484.
    // ConstantParameter's type must take v's (not typ's) upshift.
    CharType *vt = (CharType*)v->getType();
    CharType *t = (CharType*)type_;
    t->setUpshifted(vt->isUpshifted());
  }
  posns_ = new(STMTHEAP) ClusteredBitmap(STMTHEAP);
  *posns_ += p;
}

ConstantParameter::ConstantParameter(const ConstantParameter& cp, NAHeap *h)
  : val_(new(h) ConstValue(*cp.val_,h)), type_(cp.type_->newCopy(h))
  , posns_(new(h) ClusteredBitmap(*cp.posns_,h))
  , Parameter(cp)
{
}

ConstantParameter::~ConstantParameter()
{
  // we don't own type_; the statementHeap does.
  // so, we leave it up to statementHeap to free it.
}

ItemExpr *ConstantParameter::copyTopNode
(ItemExpr *derivedNode, CollHeap* outHeap)
{
  CMPASSERT(derivedNode == NULL);
  ItemExpr *result = new (outHeap) ConstantParameter(*this, (NAHeap*)outHeap);
  return result;
}

NABoolean ConstantParameter::duplicateMatch(const ItemExpr& other) const
{
  if (NOT genericDuplicateMatch(other))
    return FALSE;

  CMPASSERT(val_ != NULL);
  const ConstantParameter &o = (ConstantParameter &) other;
  return val_->duplicateMatch(*(o.val_));
  // no comparison of type_ since it should be the same if the values are
}

const NAString ConstantParameter::getText() const
{
  if (val_)
    return NAString("%(", CmpCommon::statementHeap()) + val_->getText() + ")";
  else
    return NAString("%", CmpCommon::statementHeap());
}

const NAType* ConstantParameter::synthesizeType()
{
  return getType();
}

HashValue ConstantParameter::topHash()
{
  return val_ ? val_->topHash() : ItemExpr::topHash();
}

// return true if val matches this ConstantParameter
NABoolean ConstantParameter::matches(ConstValue *val) const
{
  if (!val_ || !val) 
    return FALSE;
  else
    return *val_ == *val;
}

// -----------------------------------------------------------------------
// member functions for class DynamicParam
// -----------------------------------------------------------------------
const NAString DynamicParam::getText() const
{
  if (!indicatorName_.isNull())
    return NAString("?") + paramName_ +
           NAString(" ?") + indicatorName_ ;
  else
    return NAString("?") + paramName_  ;
}

HashValue DynamicParam::topHash()
{
  HashValue result = ItemExpr::topHash();

  // hash any local data members of the derived class
  result ^= (CollIndex) getValueId();

  return result;
}

NABoolean DynamicParam::duplicateMatch(const ItemExpr & other) const
{
  // rely on value id comparison since the binder should not
  // assign different value ids for the same parameter
  return genericDuplicateMatch(other);
}

ItemExpr * Parameter::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  ItemExpr *result = NULL;
  if (derivedNode == NULL)
    ABORT("copyTopNode() can only be called for a derived class of Parameter");
  else
    result = derivedNode;
  return ItemExpr::copyTopNode(result, outHeap);
}

ItemExpr * DynamicParam::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL) {
    result = new (outHeap) DynamicParam(paramName_, indicatorName_, outHeap);
    ((DynamicParam *) result)->setRowsetSize(rowsetSize_);
    ((DynamicParam *) result)->setRowsetInfo(rowsetInfo_);
    ((DynamicParam *) result)->setParamHeading(heading_);
    ((DynamicParam *) result)->setParamTablename(tablename_);
    // we remember our original dynamic parameter because we
    // must use their valueid at dynamicparam::codegen time
    ((DynamicParam *) result)->setOriginal(this);
  }

  else
    result = derivedNode;

  return Parameter::copyTopNode(result, outHeap);
}

const NAType * DynamicParam::pushDownType(NAType& desiredType,
				  enum NABuiltInTypeEnum defaultQualifier)
{
   const NAType * currentType = &getValueId().getType();
   if ( desiredType.getTypeQualifier() == NA_CHARACTER_TYPE &&
        currentType-> getTypeQualifier() == NA_CHARACTER_TYPE
      )
   {
     CharType &desiredCT = (CharType&)desiredType;
     enum CharInfo::CharSet desiredCS = desiredCT.getCharSet();
     CharType* ct = (CharType*)currentType;

     if ( ct ->getCharSet() != desiredCS ) 
     {
       ct->setCharSet(desiredCS);
       ct->setCollation(desiredCT.getCollation());
       ct->setCoercibility(desiredCT.getCoercibility());
       ct->setCaseinsensitive(desiredCT.isCaseinsensitive());
     }
     return currentType;
   }
   return &desiredType;   
}


// -----------------------------------------------------------------------
// member functions for class RoutineParam
// -----------------------------------------------------------------------
const NAString RoutineParam::getText() const
{
    return NAString("?") + paramName_  ;
}

HashValue RoutineParam::topHash()
{
  HashValue result = ItemExpr::topHash();

  // hash any local data members of the derived class
  result ^= paramName_;
  result ^= optionalParam_;
  result ^= paramMode_;
  result ^= ordinalPosition_;
  result ^= rdesc_;
  result ^= (CollIndex) getValueId();

  return result;
}

NABoolean RoutineParam::duplicateMatch(const ItemExpr & other) const
{
  // rely on value id comparison since the binder should not
  // assign different value ids for the same parameter
  return genericDuplicateMatch(other);
}


ItemExpr * RoutineParam::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  RoutineParam *result;

  if (derivedNode == NULL) {
      // Does not copy the rdesc_ 
    result = new (outHeap) RoutineParam(paramName_, paramType_, 
                              ordinalPosition_,paramMode_, NULL, outHeap);
  }

  else
    result = (RoutineParam *) derivedNode;

  if (derivedNode != NULL)
  {
    result->paramName_       = paramName_;
    if (paramType_ != NULL)
      result->paramType_     = paramType_->newCopy (outHeap);
    result->paramMode_       = paramMode_;
    result->ordinalPosition_ = ordinalPosition_;
    result->rdesc_           = NULL; // Do not want to copy the RoutineDesc
                                     // nor does it make any sense to just
                                     // point to the one from the clone since
                                     // multiple routineParams typically will
                                     // point to the same routineDesc. If we
                                     // just make a deep copy here we will end
                                     // up with N new copies of the same info..
                                     // 
  }
  result->optionalParam_   = optionalParam_;
  result->isCacheable_     = isCacheable_;
  memcpy(result->argumentType_, argumentType_, sizeof(argumentType_));

  return Parameter::copyTopNode((ItemExpr *)result, outHeap);
}
// -----------------------------------------------------------------------
// member functions for class BaseColumn
// -----------------------------------------------------------------------

BaseColumn::~BaseColumn()
{}

// copy constructor
BaseColumn::BaseColumn(const BaseColumn &column) :
  ItemExpr(column),
  tableDesc_(column.tableDesc_),
  colNumber_(column.colNumber_),
  equivalentIndexCols_(column.equivalentIndexCols_),
  computedColumnExpr_(column.computedColumnExpr_)
{}


NAColumn *BaseColumn::getNAColumn() const
{
  return getTableDesc()->getNATable()->getNAColumnArray()[colNumber_];
}

const NAString& BaseColumn::getColName() const
{
  return getNAColumn()->getColName();
}

const NAType& BaseColumn::getType() const
{
  return *getNAColumn()->getType();
}

Int32 BaseColumn::getArity() const { return 0; }

const NAString BaseColumn::getText() const
{
  // getenv() calls are costly. avoid especially in release code.
#ifndef NDEBUG
  if (getenv("SIMPLE_BASECOL_DISPLAY") || getenv("SIMPLE_DISPLAY"))
  {
    return
      NAString(getTableDesc()->getNATable()->getTableName().getObjectName()) +
      NAString(".") +
      NAString(getTableDesc()->getNATable()->getNAColumnArray()[colNumber_]->
               getColName());
  }
#endif

  if (CmpCommon::getDefault(MVQR_LOG_QUERY_DESCRIPTORS) == DF_DUMP_MV)
  {
    // If a correlation name exists, use it.
    // Otherwise, just use the base column name.
    const CorrName& corr = getTableDesc()->getCorrNameObj();
    NAString result;
    if (corr.getCorrNameAsString() != "")
    {
      result += corr.getCorrNameAsString();
      result += ".";
    }
    result += getTableDesc()->getNATable()->getNAColumnArray()[colNumber_]->getColName();
    return result;
  }

  // return the table in the format "table.col"
  ColRefName name(
    getTableDesc()->getNATable()->getNAColumnArray()[colNumber_]->getColName(),
    getTableDesc()->getCorrNameObj(), CmpCommon::statementHeap());
  return name.getColRefAsAnsiString(FALSE, TRUE);
}

const NAString BaseColumn::getTextForQuery() const {
  // return the table in the format "table.col" where
  // table is the physical table name and not the corr
  // table name as in getText() version

  return
    NAString(getTableDesc()->getNATable()->getTableName().getCatalogName()) +
    NAString(".") +
    NAString(getTableDesc()->getNATable()->getTableName().getSchemaName()) +
    NAString(".") +
    NAString(getTableDesc()->getNATable()->getTableName().getObjectName()) +
    NAString(".") +
    NAString(getTableDesc()->getNATable()->getNAColumnArray()[colNumber_]->
      getColName());
}

// return the set of KeyColumns referenced in the Computed Column Expression

void BaseColumn::getUnderlyingColumnsForCC(ValueIdSet &underlyingCols)
{
  if (getNAColumn()->isComputedColumn()) 
    {
      ValueIdSet keyCols = getTableDesc()->getClusteringIndex()->getIndexKey();
      keyCols = keyCols.convertToBaseIds();

      ValueIdSet compExprSet =  getComputedColumnExpr();
      underlyingCols.accumulateReferencedValues(keyCols, compExprSet);
    }
}

HashValue BaseColumn::topHash()
{
  HashValue result = ItemExpr::topHash();

  // hash any local data members of the derived class
  result ^= (void *) getTableDesc();
  result ^= colNumber_;

  return result;
}

NABoolean BaseColumn::duplicateMatch(const ItemExpr & other) const
{
  if (NOT genericDuplicateMatch(other))
    return FALSE;

  BaseColumn &o = (BaseColumn &) other;

  // compare any local data members of the derived class
  // and return FALSE if they don't match
  if (getTableDesc() != o.getTableDesc() OR
      colNumber_ != o.colNumber_)
    return FALSE;

  return TRUE;
}

ItemExpr * BaseColumn::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  ItemExpr *result;
  ItemExpr *oldBC;

  if (derivedNode == NULL)
    oldBC = new (outHeap) BaseColumn(*this);
  else
    oldBC = derivedNode;

  result = ItemExpr::copyTopNode(oldBC, outHeap);
  if (derivedNode != NULL)
     ((BaseColumn *)result)->computedColumnExpr_ = 
                               ((BaseColumn *)derivedNode)->computedColumnExpr_;
  return result;
}

NABoolean BaseColumn::isCovered(const ValueIdSet& newExternalInputs,
				const GroupAttributes& newRelExprAnchorGA,
				ValueIdSet& referencedInputs,
				ValueIdSet& /*coveredSubExpr*/,
				ValueIdSet& /*unCoveredExpr*/) const
{
  // ---------------------------------------------------------------------
  // A base column is also covered if any equivalent index column is
  // available in the group attributes or in the new inputs. Note that
  // the inverse of this is not true: the ValueId of an IndexColumn item
  // expression is NOT covered by group attributes that contain the value
  // id of the corresponding BaseColumn.
  // ---------------------------------------------------------------------
  ValueId x = equivalentIndexCols_.init();
  for (;
       equivalentIndexCols_.next(x);
       equivalentIndexCols_.advance(x))
    {
      if (newRelExprAnchorGA.isCharacteristicOutput(x) OR
	  newRelExprAnchorGA.isCharacteristicInput(x))
	return TRUE;

      if (newExternalInputs.contains(x))
	{
	  referencedInputs += x;
	  return TRUE;
	}
    }

  return FALSE;
}

OrderComparison BaseColumn::sameOrder(ItemExpr *other,
				      NABoolean askOther)
{
  OrderComparison result =
    ItemExpr::sameOrder(other,askOther);

  if (result != DIFFERENT_ORDER)
    return result;

  // try all equivalent index columns, but don't call sameOrder recursively
  // for them, rather do a simple look-up
  // 10-031114-1317: replaced a for loop that traverses the ValueIdSet
  // with the contains method that is more efficient

  if (equivalentIndexCols_.contains(other->getValueId()))
  {
    result = SAME_ORDER;
  }

  return result;
}

ValueIdList *BaseColumn::getClusteringKeyCols() const
{
  return (ValueIdList*)
    &(tableDesc_->getClusteringIndex()->getClusteringKeyCols());
}

QR::ExprElement BaseColumn::getQRExprElem() const
{
  return QR::QRColumnElem;
}

// -----------------------------------------------------------------------
// member functions for class IndexColumn
// -----------------------------------------------------------------------
IndexColumn::IndexColumn(const NAFileSet *indexPtr,
			 Lng32 indexColumnNumber,
			 const ValueId &colDefinition)
  : ItemExpr(ITM_INDEXCOLUMN),index_(indexPtr),
    indexColNumber_(indexColumnNumber),indexColDefinition_(colDefinition)
{}

IndexColumn::~IndexColumn()
{}

NAColumn * IndexColumn::getNAColumn() const
{
  return index_->getAllColumns()[indexColNumber_];
}

const NAType& IndexColumn::getType() const
{
  return *getNAColumn()->getType();
}

Int32 IndexColumn::getArity() const { return 0; }

const NAString IndexColumn::getText() const
{
  // As an indexcol is not an Ansi construct, we need not make an effort to
  // unparse it following Ansi rules; this quick-and-dirty method is fine
  // (should only be seen in gui-display tool):

  return ColRefName::getColRefAsString(
			 getNAColumn()->getColName(),
			 index_->getFileSetName().getQualifiedNameAsString());
}

void IndexColumn::unparse(NAString &result,
			  PhaseEnum /*phase*/,
			  UnparseFormatEnum form,
			  TableDesc * tabId) const
{
  // don't print the NSK name in Explain
  if (form == EXPLAIN_FORMAT)
    {
      // result += "indexcol(";
      /*      if (index_->isVolatile())
	      {
	      // only output the object part of the external name
	      // and exclude cat/sch names as these are internal IDs.
	      ComObjectName con(index_->getExtFileSetName());
	      result += ColRefName::getColRefAsString(
	      getNAColumn()->getColName(),
	      con.getObjectNamePartAsAnsiString());
	      }
	      else
	      {
      */
      result += ColRefName::getColRefAsString(
	   getNAColumn()->getColName(),
	   index_->getExtFileSetName());
     // result += ")";
    }
  else
    {
      // in all other cases do print the NSK name?
      result += getText();
    }
}

HashValue IndexColumn::topHash()
{
  HashValue result = ItemExpr::topHash();

  // hash any data members of the derived class
  // (the definition is functionally dependent on the index and
  // column number, so don't hash it)
  result ^= (void *) index_;
  result ^= indexColNumber_;

  return result;
}

NABoolean IndexColumn::duplicateMatch(const ItemExpr & other) const
{
  if (NOT genericDuplicateMatch(other))
    return FALSE;

  IndexColumn &o = (IndexColumn &) other;

  // compare any local data members of the derived class
  // and return FALSE if they don't match
  if (index_ != o.index_ OR
      indexColNumber_ != o.indexColNumber_ OR
      NOT (indexColDefinition_ == o.indexColDefinition_))
    return FALSE;

  return TRUE;
}

ItemExpr * IndexColumn::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL)
    result = new (outHeap)
      IndexColumn(index_,indexColNumber_,indexColDefinition_);
  else
    result = derivedNode;

  return ItemExpr::copyTopNode(result, outHeap);
}

OrderComparison IndexColumn::sameOrder(ItemExpr *other,
				       NABoolean askOther)
{
  OrderComparison result =
    ItemExpr::sameOrder(other,askOther);

  if (result != DIFFERENT_ORDER)
    return result;

  // try it with the definition of the index column
  return indexColDefinition_.getItemExpr()->sameOrder(other,TRUE);
}

ValueId IndexColumn::mapAndRewrite(ValueIdMap &map,
				   NABoolean mapDownwards)
{
  // try the standard method first
  ValueId result = ItemExpr::mapAndRewrite(map,mapDownwards);

  // we're done if the map contained a mapping for this column
  if (result != getValueId())
    return result;

  // try to replace the index column with its base column and then map
  result = indexColDefinition_.getItemExpr()->mapAndRewrite(map,mapDownwards);

  // return the result if it could be mapped
  // (no need to cache the index col. mapping since no new expr is created)
  if (result != indexColDefinition_)
    return result;

  // if all failed, just return the value id unchanged
  return getValueId();
}

Lng32 IndexColumn::getOffset() const
{
  return index_->getIndexKeyColumns().getOffset((short) indexColNumber_);
}

// -----------------------------------------------------------------------
// member functions for class SelIndex
// -----------------------------------------------------------------------
ItemExpr * SelIndex::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  CMPASSERT(derivedNode == NULL);

  ItemExpr *result = new (outHeap)
    SelIndex(getSelIndex(), getExprInGrbyClause());
  ((SelIndex *)result)->setRenamedColNameInGrbyClause
    (renamedColNameInGrbyClause());

  return ItemExpr::copyTopNode(result, outHeap);
}

Int32 SelIndex::getArity() const { return 0; }

const NAString SelIndex::getText() const
{
  char cp[TEXT_DISPLAY_LENGTH];
  sprintf(cp, "%d", getSelIndex());
  return cp;
}

// -----------------------------------------------------------------------
// member functions for class ValueIdRef
// -----------------------------------------------------------------------
Int32 ValueIdRef::getArity() const { return 0; }

NABoolean ValueIdRef::isCovered(const ValueIdSet& newExternalInputs,
				const GroupAttributes& coveringGA,
				ValueIdSet& referencedInputs,
				ValueIdSet& coveredSubExpr,
				ValueIdSet& /*unCoveredExpr*/) const
{
  // ---------------------------------------------------------------------
  // The ValueIdRef isCovered if the expression that it derives from
  // is covered.
  // ---------------------------------------------------------------------
  return coveringGA.covers(isDerivedFrom(), newExternalInputs,
			   referencedInputs, &coveredSubExpr);
} // ValueIdRef::isCovered()

const NAString ValueIdRef::getText() const
{
  char cp[TEXT_DISPLAY_LENGTH];
  sprintf(cp,"ValueId (%d)",CollIndex(isDerivedFrom()));
  return cp;
} // ValueIdRef::getText()


HashValue ValueIdRef::topHash()
{
  HashValue result = ItemExpr::topHash();

  // hash any local data members of the derived class
  result ^= derivedFrom_;

  return result;
}

NABoolean ValueIdRef::duplicateMatch(const ItemExpr & other) const
{
  if (NOT genericDuplicateMatch(other))
    return FALSE;

  ValueIdRef &o = (ValueIdRef &) other;

  // compare any local data members of the derived class
  // and return FALSE if they don't match
  if (NOT (derivedFrom_ == o.derivedFrom_))
    return FALSE;

  return TRUE;
}

ItemExpr * ValueIdRef::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL)
    result = new (outHeap) ValueIdRef(derivedFrom_);
  else
    result = derivedNode;

  return ItemExpr::copyTopNode(result, outHeap);
}

OrderComparison ValueIdRef::sameOrder(ItemExpr *other,
				      NABoolean askOther)
{
  OrderComparison result =
    ItemExpr::sameOrder(other,askOther);

  if (result != DIFFERENT_ORDER)
    return result;

  // check with the original expression
  return isDerivedFrom().getItemExpr()->sameOrder(other,TRUE);
}

// -----------------------------------------------------------------------
// member functions for class ValueIdProxy
// -----------------------------------------------------------------------

NABoolean ValueIdProxy::isCovered(const ValueIdSet& newExternalInputs,
                                  const GroupAttributes& coveringGA,
                                  ValueIdSet& referencedInputs,
                                  ValueIdSet& coveredSubExpr,
                                  ValueIdSet& unCoveredExpr) const
{
  // ---------------------------------------------------------------------
  // The ValueIdProxy isCovered if the expression that it derives from
  // is covered.
  // ---------------------------------------------------------------------
  return coveringGA.covers(isDerivedFrom(), newExternalInputs,
                           referencedInputs, &coveredSubExpr, &unCoveredExpr);
} // ValueIdProxy::isCovered()

const NAString ValueIdProxy::getText() const
{
  char cp[TEXT_DISPLAY_LENGTH];
  sprintf(cp,"ValueIdProxy (%d:%d->%d)",CollIndex(isDerivedFrom()),
                                        CollIndex(getOutputNum()),
                                        CollIndex(getOutputId()));
  return cp;
} // ValueIdProxy::getText()


HashValue ValueIdProxy::topHash()
{
  HashValue result = ItemExpr::topHash();

  // hash any local data members of the derived class
  result ^= derivedFrom_;
  result ^= outputOrdinalNumber_;
  result ^= outputValueId_;

  return result;
}

NABoolean ValueIdProxy::duplicateMatch(const ItemExpr & other) const
{
  if (NOT genericDuplicateMatch(other))
    return FALSE;

  ValueIdProxy &o = (ValueIdProxy &) other;

  // compare any local data members of the derived class
  // and return FALSE if they don't match
  if ((NOT (derivedFrom_ == o.derivedFrom_)) AND 
      (NOT (outputValueId_ == o.outputValueId_)) AND
      (NOT (outputOrdinalNumber_ == o.outputOrdinalNumber_)))
    return FALSE;

  return TRUE;
}


ItemExpr * ValueIdProxy::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL)
    result = new (outHeap) ValueIdProxy(derivedFrom_, 
                                        outputValueId_, 
                                        outputOrdinalNumber_);
  else
  {
    result = derivedNode;
  }

  ValueIdProxy * tmpNode = (ValueIdProxy *) result;
 
  tmpNode->derivedFrom_ = derivedFrom_;
  tmpNode->outputValueId_ = outputValueId_;
  tmpNode->outputOrdinalNumber_ = outputOrdinalNumber_;
  tmpNode->transformDerivedFromValueId_ = transformDerivedFromValueId_;

  return ItemExpr::copyTopNode(result, outHeap);
}

ItemExpr *ValueIdProxy::containsUDF()
{
    // The transfromChild_ means that this ValueIdProxy represents the
    // the subquery or UDF, thus return true..
  if ((transformDerivedFromValueId_ == TRUE) && 
      derivedFrom_.getItemExpr()->containsUDF())
    return this;
  else
    return 0;

} // ValueIdProxy::containsUDF

NABoolean ValueIdProxy::containsIsolatedUDFunction()
{
    // The transfromChild_ means that this ValueIdProxy represents the
    // the subquery or UDF, thus return true..
  if ((transformDerivedFromValueId_ == TRUE) && 
      derivedFrom_.getItemExpr()->containsUDF())
  {
     UDFunction *udf = (UDFunction *) derivedFrom_.getItemExpr()->containsUDF();

     const RoutineDesc *rdesc = udf->getRoutineDesc();
     if (rdesc == NULL || rdesc->getEffectiveNARoutine() == NULL ) return FALSE;  
     return ( rdesc->getEffectiveNARoutine()->isIsolate() ? TRUE : FALSE ) ;
  }
  else
    return FALSE;

} // ValueIdProxy::containsIsolatedUDFunction

NABoolean ValueIdProxy::containsSubquery()     // virtual method
{

    // The transfromChild_ means that this ValueIdProxy represents the
    // the subquery or UDF, thus return true..
  if ((transformDerivedFromValueId_ == TRUE) && 
      derivedFrom_.getItemExpr()->containsSubquery())
    return TRUE;
  else
    return FALSE;

} // ValueIdProxy::containsSubquery

NABoolean ValueIdProxy::containsValueIdProxySibling(const ValueIdSet &siblings)
    // virtual method
{
  // This method is used to make sure we extract all valueIds associated with
  // a subquery or UDF from a predicate or list.

  for (ValueId s = siblings.init(); siblings.next(s); siblings.advance(s))
  {
    if (s.getItemExpr()->getOperatorType() == ITM_VALUEID_PROXY)
    {
       ValueIdProxy *proxy = (ValueIdProxy *) (s.getItemExpr());
       if ( derivedFrom_ == proxy->isDerivedFrom() ) return TRUE;
    }
  }
  return FALSE;

} // ValueIdProxy::containsValueIdProxySibling

// -----------------------------------------------------------------------
// member functions for class ValueIdUnion
// -----------------------------------------------------------------------
void ValueIdUnion::setSource(Lng32 index, ValueId v)
{
  if((Lng32)sources_.entries() <= index) {
    sources_.insertAt(index, v);
  } else {
    sources_[index] = v;
  }
}

Int32 ValueIdUnion::getArity() const { return 0; }

NABoolean ValueIdUnion::isCovered(const ValueIdSet& newExternalInputs,
				  const GroupAttributes& coveringGA,
				  ValueIdSet& referencedInputs,
				  ValueIdSet& coveredSubExpr,
				  ValueIdSet& /*unCoveredExpr*/ ) const
{
  // ---------------------------------------------------------------------
  // Check which of all the operands of the ValueIdUnion isCovered().
  // Return its ValueId in coveredSubExpr.
  // ---------------------------------------------------------------------

  // $$$ Question: why not return all of the operands of the ValueIdUnion which
  // $$$ are covered -- why do we break after we find the first, in the loop below?

  ValueIdSet localSubExpr;

  for(CollIndex i = 0; i < entries(); i++)
  {
    localSubExpr.clear();
    if (coveringGA.covers(getSource(i), newExternalInputs,
			  referencedInputs, &localSubExpr) )
      {
	coveredSubExpr += getSource(i);
        break;
      }
  }

  // ---------------------------------------------------------------------
  // An aggregate function is coerced to fail the coverage test even when
  // its operand isCovered(). This is because the computation of the
  // aggregate function requires "raw" values produced by its operand to
  // be grouped. The aggregated values cannot be treated in the same
  // manner as the constitutent raw values.
  // ---------------------------------------------------------------------
  // Is something similar to the above, copied from
  // Aggregate::isCovered(), also true for ValueIdUnion?  If this is so
  // (which sort of makes sense to me), then that explains why this
  // function is hardcoded to always return FALSE.
  // ---------------------------------------------------------------------

  return FALSE; // the ValueIdUnion is not covered by its child's coveringGA

} // ValueIdUnion::isCovered()

void ValueIdUnion::getLeafValuesForCoverTest(ValueIdSet & leafValues, 
                                             const GroupAttributes& coveringGA,
                                             const ValueIdSet & newExternalInputs) const
{
  // for now, not sure if this method is really necessary -- default to
  // the base class method:

  ItemExpr::getLeafValuesForCoverTest (leafValues, coveringGA, newExternalInputs) ;

  //  leafValues += getValueId();  // this MIGHT be the right definition of this
  //                               // class -- hard to say at this point ...
} // ValueIdUnion::getLeafValuesForCoverTest()

const NAString ValueIdUnion::getText(UnparseFormatEnum form) const
{
  NAString result(CmpCommon::statementHeap());
  const char *delim;

  if (form == USER_FORMAT_DELUXE)
    delim = " UNION ";				// keyword format
  else
  {
    delim = ", ";				// standard list format
    result = "ValueIdUnion(";
  }

  for (CollIndex i = 0; i < entries(); i++)
  {
    if (i > 0)
      result += delim;

    // guard against loops in the references
    // (can happen with common subexpressions, for example)
    if (!getSource(i).getItemExpr()->referencesTheGivenValue(getValueId()))
      getSource(i).getItemExpr()->unparse(result);
    else
      result += "...";
  }

  if (form == USER_FORMAT_DELUXE)
    result.toUpper();
  else
    result += ")";

  return result;

} // ValueIdUnion::getText(), the NON-virtual method

const NAString ValueIdUnion::getText() const
{
  return getText(USER_FORMAT/*standard list format*/);

} // ValueIdUnion::getText(), the virtual method

HashValue ValueIdUnion::topHash()
{
  HashValue result = ItemExpr::topHash();

  // hash any local data members of the derived class
  for(CollIndex i = 0; i < entries(); i++)
  {
    result ^= getSource(i);
  }

  result ^= result_;

  result ^= flags_;

  return result;
}

NABoolean ValueIdUnion::duplicateMatch(const ItemExpr & other) const
{
  if (NOT genericDuplicateMatch(other))
    return FALSE;

  ValueIdUnion &o = (ValueIdUnion &) other;

  // compare any local data members of the derived class
  // and return FALSE if they don't match
  for(CollIndex i = 0; i < entries(); i++)
  {
    if (getSource(i) != o.getSource(i))
      return FALSE;
  }

  if (result_ != o.result_ || flags_ != o.flags_)
    return FALSE;

  return TRUE;
}

ItemExpr * ValueIdUnion::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  ValueIdUnion *result;

  if (derivedNode == NULL)
    result = new (outHeap) ValueIdUnion(sources_, result_, flags_);
  else
    result = (ValueIdUnion*)derivedNode;

  result->otherFlags_ = otherFlags_;

  return ItemExpr::copyTopNode(result, outHeap);
}

// -----------------------------------------------------------------------
// member functions for class VEG
// -----------------------------------------------------------------------
VEG::VEG()
  : ItemExpr(ITM_VEG), done_(FALSE), userInputs_(0), seenBefore_(FALSE),
   specialNulls_(FALSE)
{
  allocValueId();
  // Allocate a VegReference for representing any member of the VEG.
  vegRef_  = new (CmpCommon::statementHeap()) VEGReference(getValueId());
  // Allocate a VegPredicate for replacing the = predicate
  vegPred_ = new (CmpCommon::statementHeap()) VEGPredicate(getValueId());
} // VEG::VEG()

VEG::VEG(const ValueIdSet & vegSet)
 : ItemExpr(ITM_VEG), eqGroup_(vegSet), done_(FALSE), userInputs_(0),
   seenBefore_(FALSE), specialNulls_(FALSE)
{
  allocValueId();
  // Allocate a VegReference for representing any member of the VEG.
  vegRef_  = new (CmpCommon::statementHeap()) VEGReference(getValueId());
  // Allocate a VegPredicate for replacing the = predicate
  vegPred_ = new (CmpCommon::statementHeap()) VEGPredicate(getValueId());
} // VEG::VEG()

VEG::~VEG()
{
  delete vegRef_;
  delete vegPred_;
} // VEG::~VEG()

void VEG::insert(const ValueId & newValue)
{
  if (NOT eqGroup_.contains(newValue))
  {
    eqGroup_ += newValue;
    if (newValue.getItemExpr()->isAUserSuppliedInput())
      userInputs_++;
  }
} // VEG::insert()

void VEG::insert(const ValueIdSet & newValues)
{
  for (ValueId exprId = newValues.init();
       newValues.next(exprId);
       newValues.advance(exprId))
  {
    if (NOT eqGroup_.contains(exprId))
    {
      eqGroup_ += exprId;
      if (exprId.getItemExpr()->isAUserSuppliedInput())
        userInputs_++;
    }
  }
} // VEG::insert()

void VEG::merge(const VEG& other)
{
  // Add all members of the other VEG to my own
  eqGroup_ += other.eqGroup_;
  // Fixup the VEGReference and VEGPredicate of the
  // other VEG to reference me instead.
  other.getVEGReference()->replaceVEG(getValueId());
  other.getVEGPredicate()->replaceVEG(getValueId());
  userInputs_ += other.userInputs_;

  if (specialNulls_ && !other.getSpecialNulls())
    specialNulls_ = FALSE;
} // VEG::merge()

Int32 VEG::getArity() const { return 0; }

const NAString VEG::getText() const
{
  if (seenBefore())
  {
    // getenv() calls are costly. avoid especially in release code.
#ifndef NDEBUG
    if (getenv("SIMPLE_VEG_DISPLAY") || getenv("SIMPLE_DISPLAY"))
      return NAString("[...]");
#endif
    return NAString("...");
  }

  markAsSeenBefore();

  NAString result("(",CmpCommon::statementHeap());

  // getenv() calls are costly. avoid especially in release code.
#ifndef NDEBUG
  if (getenv("SIMPLE_VEG_DISPLAY") || getenv("SIMPLE_DISPLAY")) result = "[";
#endif
  NABoolean first = TRUE;

  //char cstrId[TEXT_DISPLAY_LENGTH];

  const ValueIdSet & eqGroup_ = getAllValues();

  for (ValueId x = eqGroup_.init(); eqGroup_.next(x); eqGroup_.advance(x))
  {
    // getenv() calls are costly. avoid especially in release code.
#ifndef NDEBUG
    if (getenv("NO_INDEXCOL_DISPLAY") || getenv("SIMPLE_DISPLAY"))
      if (x.getItemExpr()->getOperatorType() == ITM_INDEXCOLUMN) continue;
#endif

      if (x.getItemExpr()->getOperatorType() == ITM_INDEXCOLUMN) continue;
    if (NOT first)
    {
      result += " = ";
    }
    first = FALSE;
    x.getItemExpr()->unparse(result);
    // add valueId's after pred. name

    // getenv() calls are costly. avoid especially in release code.
#ifndef NDEBUG
    if ( (getenv("SIMPLE_VEG_DISPLAY") || getenv("SIMPLE_DISPLAY")) &&
          x.getItemExpr()->getOperatorType() == ITM_VEG_REFERENCE ) continue;
#endif



  }

  // getenv() calls are costly. avoid especially in release code.
#ifndef NDEBUG
  if (getenv("SIMPLE_VEG_DISPLAY") || getenv("SIMPLE_DISPLAY"))
    result += "]";
#endif
  result += ")";
  markAsNotSeenBefore();
  return result;
}

HashValue VEG::topHash()
{
  HashValue result = ItemExpr::topHash();

  // hash any local data members of the derived class
  result ^= (ValueIdSet &) *this;

  return result;
}

NABoolean VEG::duplicateMatch(const ItemExpr & other) const
{
  if (NOT genericDuplicateMatch(other))
    return FALSE;

  if (getVEGReference()->getVEG() !=
      ((VEG &)other).getVEGReference()->getVEG())
    return FALSE;

  return TRUE;

}

ItemExpr * VEG::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  ItemExpr *result;

  ABORT("No methods for copying this object yet");

  if (derivedNode == NULL)
    result = new (outHeap) VEG();
  else
    result = derivedNode;

  return ItemExpr::copyTopNode(result, outHeap);
}


void
VEG::getAndExpandAllValues(ValueIdSet& expandedValues) const
{
  // Get all members of VEGRef:
  const ValueIdSet& vegGroup = getAllValues();
  for (ValueId vid = vegGroup.init();
       vegGroup.next(vid);
       vegGroup.advance(vid))
    {
      if (vid.getItemExpr()->getOperatorType() != ITM_VEG_REFERENCE)
         {
          expandedValues.insert(vid);
          continue;
         }

      if ( (vid.getItemExpr()->getOperatorType() == ITM_VEG_REFERENCE) &&
           (! expandedValues.contains(vid))
         )
        {

        // In some cases, a VEGRef might contain another VEGRef within
        // its VEG which recursively self-references the VEGRef.
        // In order to prevent running into an infinite loop there, we
        // insert the vid into the set and remove it after returning
        // from recursive call. (case 10-001201-9972)

          expandedValues.insert(vid);
         ((VEGReference *) (vid.getItemExpr())) -> getVEG() ->
           getAndExpandAllValues(expandedValues);
          expandedValues -=vid;
        }
    }
} // VEG::getAndExpandAllValues(ValueIdSet& expandedValues) const


// return a Constant, hostvar or parameter from this VEG
ValueId VEG::getAConstantHostVarOrParameter() const
{
  for (ValueId id = eqGroup_.init(); eqGroup_.next(id); eqGroup_.advance(id))
  {
    ItemExpr *ie = id.getItemExpr();

    OperatorTypeEnum oper = ie->getOperatorType();

    if ((oper == ITM_CONSTANT)  ||
        (oper == ITM_HOSTVAR)   ||
        (oper == ITM_DYN_PARAM) ||
        (oper == ITM_CACHE_PARAM))
      return id;
  }

  return NULL_VALUE_ID;
}

// return a Constant from this VEG. If includeCacheParam is TRUE, also accept
// the value of a constant parameter.
ValueId VEG::getAConstant(NABoolean includeCacheParam) const
{
  for (ValueId id = eqGroup_.init(); eqGroup_.next(id); eqGroup_.advance(id))
  {
    ItemExpr *ie = id.getItemExpr();

    OperatorTypeEnum oper = ie->getOperatorType();

    if (oper == ITM_CONSTANT)
      return id;
    else if (includeCacheParam && oper == ITM_CACHE_PARAM)
      return (static_cast<ConstantParameter*>(ie))->getConstVal()->getValueId();
  }

  return NULL_VALUE_ID;
}

// -----------------------------------------------------------------------
// member functions for class VEGPredicate
// -----------------------------------------------------------------------

// default selectivity for VEGPredicates (same as equality preds)
double VEGPredicate::defaultSel()
{
  return (1.0/(CURRSTMT_OPTDEFAULTS->defNoStatsUec()) );
}

VEGPredicate::VEGPredicate(const ValueId & ofVEG)
            : ItemExpr(ITM_VEG_PREDICATE)
	    , veg_(ofVEG)
	    , specialNulls_(FALSE) // ++MV - Irena
{
  CMPASSERT (ofVEG.getItemExpr()->getOperatorType() == ITM_VEG);
  synthTypeAndValueId();
}

VEGPredicate::VEGPredicate(const VEGPredicate& vp)
            : ItemExpr(ITM_VEG_PREDICATE)
	    , veg_(vp.veg_)
	    , specialNulls_(vp.specialNulls_)
	    , predsWithSelectivities_(vp.predsWithSelectivities_)
{
  synthTypeAndValueId();
}

VEGPredicate::~VEGPredicate() {}

void VEGPredicate::replaceVEG(const ValueId& vegId)
{
  CMPASSERT(vegId.getItemExpr()->getOperatorType() == ITM_VEG);
  veg_ = vegId;
} // VEGPredicate::replaceVEG()

Int32 VEGPredicate::getArity() const { return 0; }

NABoolean VEGPredicate::isAPredicate() const { return TRUE; }

// ----------------------------------------------------------------------
// 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.
// ----------------------------------------------------------------------
void VEGPredicate::getLeafValuesForCoverTest(ValueIdSet & leafValues, 
                                             const GroupAttributes& coveringGA,
                                             const ValueIdSet & newExternalInputs) const
{
  leafValues += ((VEGPredicate *)this)->getVEG()->getVEGReference()->getValueId();
} // VEGPredicate::getLeafValuesForCoverTest()

NABoolean VEGPredicate::isCovered(const ValueIdSet& newExternalInputs,
				  const GroupAttributes& coveringGA,
				  ValueIdSet& referencedInputs,
				  ValueIdSet& /* coveredSubExpr*/,
				  ValueIdSet& /* unCoveredExpr*/ ) const
{
  ValueId VEGRefId = getVEG()->getVEGReference()->getValueId();
  ValueIdSet vegMembers = getVEG()->getAllValues();
  NABoolean covered = FALSE;

  // A VEGPredicate is covered if the child can supply the VEGRefId.
  // If the VEGRefId is only supplied by the inputs we want to return false.

  // The VEGRefId will be part of the child's required outputs since
  // the parent needed that to evaluate the VEGPredicate.
  // So simply check if the VEGRefId is part of the required outputs.
  // However, when FileScanRule::nextSubstitute is trying to determine
  // if a index is useful, the required output simply contains the
  // list of indexcol valueId's, and has not been remapped to the
  // VEGRefId's that correspond in that region. So check to see if
  // the indexcol intersects with the VEG members.

  // We cannot call coveringGA.covers() in this case because it will be fooled
  // by the presences of one of the members of the VEG in the required
  // inputs or newExternalInputs.

  if (coveringGA.isCharacteristicOutput(VEGRefId))
    {
      covered = TRUE;
    }
  else
    {
      // Check if a member of the VEG is in the characteristic outputs
      ValueIdSet outputs = coveringGA.getCharacteristicOutputs();
      outputs.intersectSet(vegMembers);
      if (NOT outputs.isEmpty())
        covered = TRUE;
    }

  // If the VEGPredicate is covered we want to include in the
  // characteristic inputs the VEGRefId for the VEG if
  // available
  if (covered)
    {
      // If the VEGPredicate is covered without supplying any
      // new external inputs, indicate which of the given
      // external inputs can help for evaluating this
      // VEGPredicate here.
      if (newExternalInputs.contains(VEGRefId))
        referencedInputs += VEGRefId;
      else
        {
          const NABoolean doNotLookInsideVegReferences = FALSE ;
          const NABoolean doNotLookInsideInstantiateNulls = FALSE ;
          //
          // It is likely that some member of the VEG appears in
          // the external inputs. For example, consider
          //       t1 left join t2 on t1.x = t2.y
          // The VEG will contain (t2.y, ixcol t2.y, VEGRef(t1.x ..))
          //
          // The nested loop join transformation will supply
          // VEGRef(t1.x ..), which belongs to an outer scope, as an
          // external input. Clearly, the latter new external input does
          // not contain the VEGReference for the former VEG. In fact,
          // the reverse situation is true. The case that is sketched
          // in these comments is detected by the code that appears below:
          referencedInputs.accumulateReferencedValues
            (newExternalInputs,
             vegMembers,
             doNotLookInsideVegReferences,
             doNotLookInsideInstantiateNulls);
        }
    } // if (covered)

  // The idea is to push the predicate down only when the tree can
  // produce a member of the VEG. However, we are having too many
  // problems with the above policy. We did not want to push a
  // VEGPredicate down the tree only because the VEG references a
  // constant that is needed in the tree. However, predicates of the
  // form :hv = 10 and other predicates that only reference correlated
  // values need to be pushed to some scan.

  // $$$$ Comments (Dec. 19, 1996)
  // Check whether the predicate should be pushed down by looking at
  // the number of user supplied inputs that are members of the
  // VEG. If the VEGPredicate is not covered because the tree cannot
  // produce a member of the VEG, push it down iff there are at least
  // two user supplied inputs that are members of the VEG. Indeed,
  // this is a kludge that is meant to permit the optimization
  // i.e., evaluating predicates such as :hv =
  // 10 on some scan. However, it has the advantage of eliminating the
  // really dumb behaviour of pushing a predicate down on the strength
  // of supplying a single constant value as an input.

  // The kludge added does not work. Predicates of the form
  // :hv = 10 are not stored in a VEGPred unless there also is a
  // predicate of the form col = :hv. So, all that needs to be handled
  // here are VEGPreds that reference correlated column values but
  // do not reference values supplied by the child's char outputs.
  // For example, 31 = T0.i1, and T0 is not a child.
  else
  {
     // Check if all value ids in the vegMembers set are either
     // user supplied inputs or correlated references (an embedded
     // vegRef must be a correlated reference or it's in an left join
     // ON clause).  If it's in an left join ON clause, this is ok,
     // it just means we may push down the pred to the right child
     // of the left join if the join is a TSJ and the pred only
     // refers to the left child and user inputs. For example,
     // select t0.a from t0 left join t1 on t0.a = 10. The pred
     // t0.a = 10 will get pushed to the right child (t1) if the
     // join is a TSJ. This would not happen without this fix but
     // this should not be a problem as it is legal to push an
     // ON clause pred to the right child of a left join.
     NABoolean allVEGMembersAreInputs = TRUE;
     NABoolean outerReferencesSeen = FALSE;
     NABoolean userSuppliedInputsSeen = FALSE;
     ValueIdSet outerReferences;
     ValueIdSet userSuppliedInputs;
     for (ValueId vid = vegMembers.init();
                        vegMembers.next(vid);
                        vegMembers.advance(vid))
     {
       // Check if the veg member is not a user supplied input or
       // a correlated reference. It is a correlated reference if it
       // is an embedded vegRef or if it is an instantiate null whose
       // child is an embedded vegRef. A instantiate null with an
       // embedded vegRef child represents a correlated reference to
       // the right child output of a left join. 
       
       if (NOT (vid.getItemExpr()->isAUserSuppliedInput() OR
                (vid.getItemExpr()->getOperatorType() == ITM_VEG_REFERENCE) OR
                ((vid.getItemExpr()->getOperatorType() ==
                    ITM_INSTANTIATE_NULL) AND
                 (vid.getItemExpr()->child(0)->getOperatorType() ==
                    ITM_VEG_REFERENCE))
               )
          )
       {
	 // If this column was a host var before binding, we consider it as such
         if (vid.getItemExpr()->previousHostVar())
         {
           allVEGMembersAreInputs = TRUE;
           break;
         }
         allVEGMembersAreInputs = FALSE;
       }

       // check for outer-references in form of embedded veg-references
       if (vid.getItemExpr()->getOperatorType() == ITM_VEG_REFERENCE)
       {
         outerReferencesSeen = TRUE;
         outerReferences +=vid;
       }
       else if (vid.getItemExpr()->isAUserSuppliedInput())
       {
         userSuppliedInputs +=vid;
         userSuppliedInputsSeen = TRUE;
       }
     } // for

     if (outerReferencesSeen &&
         NOT allVEGMembersAreInputs)
     {
       // This VEGPredicate has an outer reference in the VEG Members set.
       // In addition the set also has a NON-UserSuppliedInput such
       // as a base column or an index column (extra columns);
       // We already know that these extra columns are not part of the output
       // (A check is made at the beginning of this routine)
       //  Check if these are part of input and set covered to TRUE only when
       // they are NOT part of characteristic input set
       // CR 10-010314-1732

       if ( newExternalInputs.contains(VEGRefId) &&
            userSuppliedInputsSeen
          )
       {
         // VegMembers contain an user Supplied input and an outer Reference
         ValueIdSet inputset = vegMembers;
         inputset -= outerReferences;
         inputset -= userSuppliedInputs;
         inputset.intersectSet(newExternalInputs);

         if (inputset.isEmpty())
         {
           covered = TRUE;
           referencedInputs += VEGRefId;
         }
       }
     }

     // Allow the predicate to be pushed down if all vegMembers are
     // user supplied inputs or correlated references, and the VEGRef
     // or at least one of it's constiuent parts are covered by the
     // char. inputs.
     if (allVEGMembersAreInputs)
     {
       if (coveringGA.isCharacteristicInput(VEGRefId))
       {
         covered = TRUE;
       }
       if (newExternalInputs.contains(VEGRefId))
       {
         covered = TRUE;
         referencedInputs += VEGRefId;
       }
       if (NOT covered)
       {
         vegMembers.intersectSet(newExternalInputs);
         if (NOT vegMembers.isEmpty())
         {
           covered = TRUE;
           referencedInputs += vegMembers;
         }
       }
     } // end if all veg members are inputs
  } // end if not covered by outputs

  return covered;

} // VEGPredicate::isCovered()

const NAString VEGPredicate::getText() const
{
  char cp[TEXT_DISPLAY_LENGTH];

  // getenv() calls are costly. avoid especially in release code.
#ifndef NDEBUG
  if (getenv("SIMPLE_VEG_DISPLAY") || getenv("SIMPLE_DISPLAY"))
  {
    sprintf(cp,"VP%d",CollIndex(getValueId()));
    return NAString(cp) + veg_.getItemExpr()->getText();
  }
#endif

  //sprintf(cp,"VEGPred_%d(",CollIndex(getValueId()));
  cp[0] = 0;
  return NAString(cp) + veg_.getItemExpr()->getText(); // + ")";
} // VEGPredicate::getText()

// MVs -- 
void VEGPredicate::unparse(NAString &result,
			   PhaseEnum phase,
			   UnparseFormatEnum form,
			   TableDesc * tabId) const
{
  if ((form != MVINFO_FORMAT) &&
      (form != QUERY_FORMAT))
  {
    ItemExpr::unparse(result, phase, form, tabId);
    return;
  }

  const ValueIdList vegMembers(getVEG()->getAllValues());

  CMPASSERT(vegMembers.entries() >=2);
  ValueIdList copyList;  

  CollIndex startIndex;
  if (form == QUERY_FORMAT || form == MVINFO_FORMAT)
    startIndex = 0;
  else 
    startIndex = 1;

  ValueId  nextMemberId;
  for (CollIndex i=startIndex; i<vegMembers.entries(); i++)
  {
    nextMemberId = vegMembers[i];
    ItemExpr *nextExpr = nextMemberId.getItemExpr();
    if (nextExpr->getOperatorType() == ITM_INDEXCOLUMN)
      continue;
    if ((form == QUERY_FORMAT) &&
        (nextExpr->getOperatorType() == ITM_BASECOLUMN))
    {
      BaseColumn * bs = (BaseColumn *)nextExpr;
      if (bs->getTableDesc() != tabId && form != MVINFO_FORMAT)
        continue;
    }  
    copyList.insert(vegMembers[i]);
  }  

  if (copyList.entries() < 2) 
    return;

  ValueId  firstMemberId = copyList[0];
  NAString firstMemberText;
  firstMemberId.getItemExpr()->unparse(firstMemberText, phase, form, tabId);

  NAString nextMemberText("empty");
  for (CollIndex i=1; i<copyList.entries(); i++)
  {
    nextMemberId = copyList[i];

    // If this is not the first predicate, "AND" between predicates.
    if (nextMemberText != "empty")
      result += " AND ";

    nextMemberText = "";
    nextMemberId.getItemExpr()->unparse(nextMemberText, phase, form, tabId);

    result += firstMemberText;
    result += " = ";
    result += nextMemberText;
  }
}

HashValue VEGPredicate::topHash()
{
  HashValue result = ItemExpr::topHash();

  // hash any local data members of the derived class
  result ^= getVEG()->topHash();

  return result;
} // VEGPredicate::topHash()

NABoolean VEGPredicate::duplicateMatch(const ItemExpr & other) const
{
  if (NOT genericDuplicateMatch(other))
    return FALSE;

  // compare any local data members of the derived class
  // and return FALSE if they don't match
  if (veg_ != ((VEGPredicate &)other).veg_)
    return FALSE;

  return TRUE;
} // VEGPredicate::duplicateMatch()

ItemExpr * VEGPredicate::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  ItemExpr *result = NULL;

  if (derivedNode == NULL)
    //ABORT("No methods for copying this object yet");
    result = new VEGPredicate(*this);
  else
    result = derivedNode;

  return ItemExpr::copyTopNode(result, outHeap);
} // VEGPredicate::copyTopNode()

// -----------------------------------------------------------------------
// member functions for class VEGReference
// -----------------------------------------------------------------------
VEGReference::VEGReference(const ValueId & ofVEG)
            : ItemExpr(ITM_VEG_REFERENCE), veg_(ofVEG)
{
  CMPASSERT (ofVEG.getItemExpr()->getOperatorType() == ITM_VEG);
  allocValueId();
}

VEGReference::~VEGReference() {}

Int32 VEGReference::getArity() const { return 0; }

void VEGReference::replaceVEG(const ValueId& vegId)
{
  CMPASSERT(vegId.getItemExpr()->getOperatorType() == ITM_VEG);
  veg_ = vegId;
} // VEGReference::replaceVEG()

NABoolean VEGReference::isCovered(const ValueIdSet& newExternalInputs,
				  const GroupAttributes& coveringGA,
				  ValueIdSet& referencedInputs,
				  ValueIdSet& coveredSubExpr,
				  ValueIdSet& unCoveredExpr ) const
{
  // If we arrive here to check whether a VEGReference isCovered(),
  // it means that this VEGReference does not belong to the
  // Characteristic Inputs and Outputs. (Otherwise, the test in
  // covers() would have detected its presence.)
  // Walk through all the members of the set in order to return an
  // indication of which values are referenced inputs, which values
  // are covered sub expressions and which of them are uncovered expr.

  NABoolean retVal = FALSE;

  VEG *veg = getVEG();

  if (veg->seenBefore())
    return FALSE;

  // Remember valueId of the VEGReference that we've already seen.
  veg->markAsSeenBefore();

  for (ValueId x = veg->getAllValues().init();
                   veg->getAllValues().next(x);
                   veg->getAllValues().advance(x))
  {
    // I am covered if ANY ONE of my candidate values is covered
    if (coveringGA.covers(x, newExternalInputs, referencedInputs,
                          &coveredSubExpr, &unCoveredExpr))
    {
      retVal = TRUE;
      break;
    }
  }

  veg->markAsNotSeenBefore();
  return retVal;

} // VEGReference::isCovered()

OrderComparison VEGReference::sameOrder(ItemExpr * other,
					NABoolean /*askOther*/)
{
  // first, check whether the item expressions are identical
  if (this == other)
    return SAME_ORDER;

  // We can have circular VegRefs like :
  // VEGRef_285(TAB4.SSTUTKYOKI = VEGRef_310(TAB9.TKYOKI = VEGRef_285(..)))
  // In this case, sameOrder()will go into infinite loop (soln 10-110911-7326).
  // Not sure why we ended up constructing circular VegRefs in the first place,
  // but ItemExpr::referencesTheGivenValue() code indicates it's possible
  // and handles by marking Vegrefs as seen before and back out if VegRef is
  // being seen second time. Same logic is also used here as explained below:
  // 1. if VegRef has not seen before, mark it as seen before, also remember it.
  // 2. for every veg member who is of type vegreference and seen before,
  //    do not call sameOrder() again.
  // 3. if this method has called markAsSeenBefore(), then call
  //    markAsNotSeenBefore()
  NABoolean callNotSeen = FALSE;
  VEG *veg = getVEG();
  // step 1
  if (!veg->seenBefore())
  {
    veg->markAsSeenBefore();
    callNotSeen = TRUE;
  }

  // VEGReferences can be used for ordering comparison under the
  // assumption that all comparison predicates that can be applied
  // actually have been applied. For example, if we want "order by t1.x"
  // and t1.x is in a VEG with t2.y, then we can use an existing
  // order t2.y if we can assume that t1.x has already been compared
  // with t2.y. Note that we want order t1.x we should have t1.x
  // available at that time.
  const ValueIdSet &equivValues = getVEG()->getAllValues();
  OrderComparison result = DIFFERENT_ORDER;

  for (ValueId x = equivValues.init();
       equivValues.next(x) AND result == DIFFERENT_ORDER;
       equivValues.advance(x))
    {
      if((x.getItemExpr()->getOperatorType()) == ITM_VEG_REFERENCE)
      {
        // step 2
        VEG *innerVeg = ((VEGReference *)x.getItemExpr())->getVEG();
        if (!innerVeg->seenBefore())
          result = x.getItemExpr()->sameOrder(other,TRUE);
      }
      else
        result = x.getItemExpr()->sameOrder(other,TRUE);
    }

  // step 3
  if (callNotSeen)
    veg->markAsNotSeenBefore();

  return result;
}

// ----------------------------------------------------------------------
// Walk through members of VegReference and verify if any member of this
// VegReference, which is of TYPE ITM_VEG_REFERENCE contains passed
// argument. Also dig deep inside all ITM_VEG_REFERENCE objects to avoid
// circular vegRefences like :
// VEGRef_285((T4.SSTUTKYOKI = VEGRef_310((T9.TKYOKI = VEGRef_285(...))))
// This method gets called from VEGRegion::replaceVEGMember() and fixes
// bug QC_1348
// ----------------------------------------------------------------------
NABoolean VEGReference::referencesVegRefValue(ValueId& ofVegRef)
{
  // Get all members of VEGRef:
  const ValueIdSet &vegGroup = getVEG()->getAllValues();
  VEG *oldVEGPtr = ((VEGReference *)ofVegRef.getItemExpr())->getVEG();
  for (ValueId vid = vegGroup.init(); vegGroup.next(vid); vegGroup.advance(vid))
  {
    if (vid.getItemExpr()->getOperatorType() == ITM_VEG_REFERENCE)
    {
      VEG *newVEGPtr = ((VEGReference *) (vid.getItemExpr()))->getVEG();
      if (newVEGPtr == oldVEGPtr)
        return TRUE;
      else
        return ((VEGReference *) (vid.getItemExpr()))->referencesVegRefValue(ofVegRef);
    }
  }
  return FALSE;

}


const NAString VEGReference::getText() const
{
  char cp[TEXT_DISPLAY_LENGTH];
  sprintf(cp,"VEGRef_%d(",CollIndex(getValueId()));

  // getenv() calls are costly. avoid especially in release code.
#ifndef NDEBUG
  NABoolean simpleDisplay = FALSE;
  simpleDisplay = getenv("SIMPLE_VEG_DISPLAY") || getenv("SIMPLE_DISPLAY");
  if (simpleDisplay)
    sprintf(cp,"VR%d",CollIndex(getValueId()));
#endif
  NAString x(NAString(cp, CmpCommon::statementHeap())+
              veg_.getItemExpr()->getText(),
            CmpCommon::statementHeap());
  x += ")";
#ifndef NDEBUG
  if (simpleDisplay)
    x.remove(x.length()-1);
#endif
  return x;
} // VEGReference::getText()

void VEGReference::unparse(NAString &result,
			   PhaseEnum phase,
			   UnparseFormatEnum form,
			   TableDesc * tabId) const
{
  if ((form == EXPLAIN_FORMAT) || (form == MVINFO_FORMAT) ||
       (form == QUERY_FORMAT))
    {
      // End users won't know what a VegReference is, and
      // most items in EXPLAIN are already rewritten w/o VEGies.
      // Generate equiv(col) where col is the unparsed text
      // of some VEG member.

      /*if (form == EXPLAIN_FORMAT)
	result += "equiv(";
      */
      const ValueIdSet &vegMembers =
	((VEG *) veg_.getItemExpr())->getAllValues();

      for (ValueId someMemberId = vegMembers.init();
	   vegMembers.next(someMemberId);
	   vegMembers.advance(someMemberId))
        {
	  ItemExpr * someMemberExpr = someMemberId.getItemExpr();
	  if (form == QUERY_FORMAT)
	  {
	    // for QUERY_FORMAT, unparse the VEG member that belongs to the
	    // given tableDesc
	    if ((someMemberExpr->getOperatorType() == ITM_BASECOLUMN) &&
	        (((BaseColumn *)someMemberExpr)->getTableDesc() == tabId) ||
                 (CmpCommon::getDefault(MVQR_LOG_QUERY_DESCRIPTORS) == DF_DUMP_MV))
	    {
		someMemberExpr->unparse(result, phase, form, tabId);
		break;
	    }
	    else
	      continue;
	  }
	  else
	  {
	    // if not QUERY_FORMAT, unparse the first veg member
            someMemberExpr->unparse(result,phase,form);
	    break;
	  }
        }
      /*
      if (form == EXPLAIN_FORMAT)
        result += ") ";
	*/
    }
  else
    {
      result += getText();
    }
}

HashValue VEGReference::topHash()
{
  HashValue result = ItemExpr::topHash();

  // hash any local data members of the derived class
  result ^= getVEG()->topHash();

  return result;
} // VEGReference::topHash()

NABoolean VEGReference::duplicateMatch(const ItemExpr & other) const
{
  if (NOT genericDuplicateMatch(other))
    return FALSE;

  // compare any local data members of the derived class
  // and return FALSE if they don't match
  if (veg_ != ((VEGReference &)other).veg_)
    return FALSE;

  return TRUE;
} // VEGReference::duplicateMatch()

ItemExpr * VEGReference::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  ItemExpr *result = NULL;

  if (derivedNode == NULL)
    //ABORT("No methods for copying this object yet");
    result = new (outHeap) VEGReference(getVEG()->getValueId());
  else
    result = derivedNode;

  return ItemExpr::copyTopNode(result, outHeap);
} // VEGReference::copyTopNode()

QR::ExprElement VEGReference::getQRExprElem() const
{
  return QR::QRColumnElem;
}

// -----------------------------------------------------------------------
// member functions for class CheckConstraint
// -----------------------------------------------------------------------
Int32 CheckConstraint::getArity() const { return 0;}

ItemExpr * CheckConstraint::copyTopNode(ItemExpr *derivedNode,
					CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL)
    result = new (outHeap) CheckConstraint(*this, outHeap);
  else
    result = derivedNode;

  return ItemExpr::copyTopNode(result, outHeap);
}

const NAString CheckConstraint::getText() const
{
  return "CheckConstraint";
}

void CheckConstraint::unparse(NAString &result,
			     PhaseEnum /* phase */,
			     UnparseFormatEnum /* form */,
			     TableDesc * tabId) const
{
  result += getText();
  result += "(";
  result += getConstraintName().getQualifiedNameAsAnsiString();
  result += ")";
}

// -----------------------------------------------------------------------
// member functions for class OptConstraint
// -----------------------------------------------------------------------
ItemExpr * OptConstraint::copyTopNode(ItemExpr *derivedNode,
				      CollHeap* outHeap)
{
  return ItemExpr::copyTopNode(derivedNode, outHeap);
}

// -----------------------------------------------------------------------
// member functions for class CardConstraint
// -----------------------------------------------------------------------
Int32 CardConstraint::getArity() const { return 0;}

ItemExpr * CardConstraint::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL)
    result = new (outHeap) CardConstraint(lowerBound_,upperBound_);
  else
    result = derivedNode;

  return OptConstraint::copyTopNode(result, outHeap);
}

const NAString CardConstraint::getText() const
{
  return "CardConstraint";
}

void CardConstraint::unparse(NAString &result,
			     PhaseEnum /* phase */,
			     UnparseFormatEnum /* form */,
			     TableDesc * tabId) const
{
  char ascii[TEXT_DISPLAY_LENGTH];

  sprintf(ascii,"CardConstraint(%g,%g)",lowerBound_,upperBound_);
  result += ascii;
}

// -----------------------------------------------------------------------
// member functions for class UniqueOptConstraint
// -----------------------------------------------------------------------
Int32 UniqueOptConstraint::getArity() const { return 0;}

ItemExpr * UniqueOptConstraint::copyTopNode(ItemExpr *derivedNode,
					    CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL)
    result = new (outHeap) UniqueOptConstraint(uniqueCols_);
  else
    result = derivedNode;

  return OptConstraint::copyTopNode(result, outHeap);
}

const NAString UniqueOptConstraint::getText() const
{
  return "UniqueOptConstraint";
}

void UniqueOptConstraint::unparse(NAString &result,
				  PhaseEnum phase,
				  UnparseFormatEnum form,
				  TableDesc * tabId) const
{
  result += "UniqueOptConstraint";
  uniqueCols_.unparse(result,phase,form);
}

// -----------------------------------------------------------------------
// member functions for class FuncDependencyConstraint
// -----------------------------------------------------------------------
Int32 FuncDependencyConstraint::getArity() const
{
  return 0;
}

ItemExpr * FuncDependencyConstraint::copyTopNode(ItemExpr *derivedNode,
						 CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL)
    result = new (outHeap) FuncDependencyConstraint(determiningCols_,
						    dependentCols_);
  else
    result = derivedNode;

  return OptConstraint::copyTopNode(result, outHeap);
}

void FuncDependencyConstraint::synthFunctionalDependenciesFromChild(
     GroupAttributes &ga,
     const RelExpr *child,
     NABoolean createNewDependencies)
{
  const ValueIdSet & childConstraints =
    child->getGroupAttr()->getConstraints();
  ValueIdSet vegColsFromChild(child->getGroupAttr()->
			      getCharacteristicOutputs());

  // For now we want to maintain only VEGReferences as the dependent
  // columns. This is mainly done to avoid unusual situations
  // (monkeys at the keyboard) that might lead to errors. Restricting
  // functional dependencies to VEGRefs should still cover the majority
  // of all interesting situations.
  if (createNewDependencies)
    {
      for (ValueId co = vegColsFromChild.init();
	   vegColsFromChild.next(co);
	   vegColsFromChild.advance(co))
	{
	  if (co.getItemExpr()->getOperatorType() != ITM_VEG_REFERENCE)
	    vegColsFromChild -= co;
	}
    }

  // walk through the child constraints
  for (ValueId cx = childConstraints.init();
       childConstraints.next(cx);
       childConstraints.advance(cx))
    {
      ItemExpr *c = cx.getItemExpr();
      OperatorTypeEnum optype = c->getOperatorType();

      if (optype == ITM_UNIQUE_OPT_CONSTRAINT AND
	  createNewDependencies AND
	  NOT vegColsFromChild.isEmpty())
	{
	  UniqueOptConstraint *uc = ((UniqueOptConstraint *)c);

	  // Try to find unique columns in the child that are no longer
	  // unique in the parent. For each such uniqueness constraint,
	  // add a functional dependency constraint if the unique columns
	  // are visible to the parent.

	  // NOTE: At some later point we should consider taking out
	  // the check on the characteristic outputs, since it may
	  // suppress some interesting constraints (we don't check
	  // uniqueness constraints for being covered by char. outputs either)
	  // Example: select a from t1 join t2 may get
	  // different uniqueness constraints (and cardinality estimates)
	  // than select * from t1 join t2.

	  if (NOT ga.isUnique(uc->uniqueCols()) &&
	      child->getGroupAttr()->getCharacteristicOutputs().contains(
		   uc->uniqueCols()))
	    {
	      // yes, found unique columns that are visible to the parent,
	      // now check whether all unique columns are VEGRefs
	      // (sorry, we only consider those for now)
	      NABoolean NonVEGFound = FALSE;

	      for (ValueId ux=uc->uniqueCols().init();
		   uc->uniqueCols().next(ux);
		   uc->uniqueCols().advance(ux))
		if (ux.getItemExpr()->getOperatorType() != ITM_VEG_REFERENCE)
		  NonVEGFound = TRUE;

	      if (NOT NonVEGFound)
		{
		  ValueIdSet myDependentCols(vegColsFromChild);

		  // remove the unique columns from the dependent columns
		  // (don't want functional dependencies like A --> A)
		  myDependentCols -= uc->uniqueCols();

		  if (NOT myDependentCols.isEmpty())
		    {
		      FuncDependencyConstraint *nc =
			new(CmpCommon::statementHeap())
			FuncDependencyConstraint(uc->uniqueCols(),
						 myDependentCols);
		      ga.addConstraint(nc);
		    }
		}
	    }
	}
      else if (optype == ITM_FUNC_DEPEND_CONSTRAINT)
	{
	  // Found a functional dependency in the child constraints.
	  // Copy it if the determining columns are visible in the
	  // parent node.
	  FuncDependencyConstraint *fd = (FuncDependencyConstraint *) c;

	  // NOTE: At some later point we should consider taking out
	  // the check on the characteristic outputs (same as above).

	  if (child->getGroupAttr()->getCharacteristicOutputs().contains(
		   fd->getDeterminingCols()))
	    {
	      ga.addConstraint(c);
	    }
	}
    }
}

void FuncDependencyConstraint::minimizeUniqueCols(ValueIdSet &uniqueCols)
{
  if (uniqueCols.contains(determiningCols_))
    {
      // We know now that the uniqueCols determine our "dependentCols_".

      // As an example, let's assume that uniqueCols is (a,b,c,d),
      // determiningCols_ is (a,b), and dependentCols_ is (c).

      // If columns (a,b) determine (c), then it is true that if
      // (a,b,c) is unique then (a,b) is unique as well. This is
      // because the definition of functional dependency says that
      // there will never be two rows with the same (a,b) values that
      // have different (c) values.

      // The extra column (d) in the example does not invalidate this
      // argument.

      // at this point we only use simple ValueId operations, no
      // cover test methods for checks like "does (a,b) determine (a+c+2)?"

      // Could assert here that the intersection of determiningCols_ and
      // dependentCols_ is empty (more precisely: that the dependent columns
      // don't cover any of the unique columns, but we don't have the
      // necessary information to check this here). See method
      // FuncDependencyConstraint::createFunctionalDependenciesFromChild()
      // above for where this constraint is enforced.

      uniqueCols.subtractSet(dependentCols_);
    }
}

const NAString FuncDependencyConstraint::getText() const
{
  return "FuncDependencyConstraint";
}

void FuncDependencyConstraint::unparse(NAString &result,
				       PhaseEnum phase,
				       UnparseFormatEnum form,
				       TableDesc * tabId) const
{
  // use EXPLAIN format since we only talk about VEGRefs and
  // one member should be sufficient to represent the VEG
  result += "FuncDependencyConstraint(";
  determiningCols_.unparse(result,phase,EXPLAIN_FORMAT);
  result += " ---> ";
  dependentCols_.unparse(result,phase,EXPLAIN_FORMAT);
  result += ")";
}


// -----------------------------------------------------------------------
// member functions for class CheckOptConstraint
// -----------------------------------------------------------------------
CheckOptConstraint::~CheckOptConstraint() {}

Int32 CheckOptConstraint::getArity() const { return 0; }

ItemExpr * CheckOptConstraint::copyTopNode(ItemExpr *derivedNode,
                                           CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL)
    result = new (outHeap) CheckOptConstraint(checkPreds_);
  else
    result = derivedNode;

  return OptConstraint::copyTopNode(result, outHeap);
}

const NAString CheckOptConstraint::getText() const
{
  return "CheckOptConstraint";
}

void CheckOptConstraint::unparse(NAString &result,
                                 PhaseEnum phase,
                                 UnparseFormatEnum form,
                                 TableDesc * tabId) const
{
  result += "CheckOptConstraint";
  checkPreds_.unparse(result,phase,form);
}

// -----------------------------------------------------------------------
// member functions for class RefOptConstraint
// -----------------------------------------------------------------------
Int32 RefOptConstraint::getArity() const { return 0;}

ItemExpr * RefOptConstraint::copyTopNode(ItemExpr *derivedNode,
					    CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL) 
  {
    result = new (outHeap) RefOptConstraint(fkCols_, uniqueConstraintName_);
    ((RefOptConstraint*)result)->isMatched_ = isMatched_ ;
  }
  else
    result = derivedNode;

  return OptConstraint::copyTopNode(result, outHeap);
}

const NAString RefOptConstraint::getText() const
{
  return "RefOptConstraint";
}

void RefOptConstraint::unparse(NAString &result,
				  PhaseEnum phase,
				  UnparseFormatEnum form,
				  TableDesc * tabId) const
{
  result += "RefOptConstraint";
  fkCols_.unparse(result,phase,form);
  result += "(";
  result += uniqueConstraintName().getQualifiedNameAsAnsiString();
  result += ")";
}

// -----------------------------------------------------------------------
// member functions for class ComplementaryRefOptConstraint
// -----------------------------------------------------------------------
Int32 ComplementaryRefOptConstraint::getArity() const { return 0;}

ItemExpr * ComplementaryRefOptConstraint::copyTopNode(ItemExpr *derivedNode,
					    CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL)
    result = new (outHeap) ComplementaryRefOptConstraint(ucCols_, 
	    constraintName_, tabPtr_, tabDesc_, NULL, isMatchedForElimination_);
  else
    result = derivedNode;

  return OptConstraint::copyTopNode(result, outHeap);
}

const NAString ComplementaryRefOptConstraint::getText() const
{
  return "ComplementaryRefOptConstraint";
}

void ComplementaryRefOptConstraint::unparse(NAString &result,
				  PhaseEnum phase,
				  UnparseFormatEnum form,
				  TableDesc * tabId) const
{
  result += "ComplementaryRefOptConstraint";
  ucCols_.unparse(result,phase,form);
  result += "(";
  result += constraintName().getQualifiedNameAsAnsiString();
  result += ")";
}

// -----------------------------------------------------------------------
// member functions for class Aggregate
// -----------------------------------------------------------------------
Aggregate::~Aggregate() {}

NABoolean Aggregate::isAnAggregate() const { return TRUE; }

NABoolean Aggregate::containsAnAggregate() const { return TRUE; }

Int32 Aggregate::getArity() const
{
  // ##Should be same as Function::getNumChildren(), except added CMPASSERT here
  // (aggregates must have at least one child; stddev/variance can have more).

  if (!child(1)) return 1;	// most aggs have 1 child
  CMPASSERT(!child(2));		// no aggs have 3+ children
  return 2;			// STDDEV/VARIANCE may have 1 or 2
}

NABoolean Aggregate::operator== (const ItemExpr& other) const	// virtual meth
{
  if (ItemExpr::operator==(other)) return TRUE;

  if (getOperatorType() != other.getOperatorType()) return FALSE;

  const Aggregate &otherAgg = (const Aggregate &)other;

  if (getOperatorType() == ITM_MIN || getOperatorType() == ITM_MAX)
    {
      // Min/Max are order-sensitive
      ItemExprList arglist0(child(0), NULL);
      ItemExprList arglist1(otherAgg.child(0), NULL);
      if (arglist0.entries() != arglist1.entries()) return FALSE;
      for (CollIndex i = arglist0.entries(); i--; )
        if (arglist0[i] != arglist1[i]) return FALSE;
    }
  else
    {
      ValueIdSet argset0, argset1;
      child(0)->convertToValueIdSet(argset0, NULL, ITM_ITEM_LIST);
      otherAgg.child(0)->convertToValueIdSet(argset1, NULL, ITM_ITEM_LIST);
      if (argset0 != argset1) return FALSE;
    }

  return TRUE;
}

NABoolean Aggregate::duplicateMatch(const ItemExpr& other) const
{
  if (NOT genericDuplicateMatch(other))
    return FALSE;

  const Aggregate &ag = (Aggregate &)other;

  if (isDistinct_ != ag.isDistinct_)
    return FALSE;

  if (NOT isSensitiveToDuplicates())
    return FALSE;

  return TRUE;
}

NABoolean Aggregate::isCovered
                      (const ValueIdSet& newExternalInputs,
		       const GroupAttributes& coveringGA,
		       ValueIdSet& referencedInputs,
		       ValueIdSet& coveredSubExpr,
		       ValueIdSet& /*unCoveredExpr*/ ) const
{
  // ---------------------------------------------------------------------
  // If the operand of the aggregate isCovered(), then return its ValueId
  // in coveredSubExpr.
  // ---------------------------------------------------------------------
  ValueIdSet localSubExpr;
  for (Lng32 i = 0; i < (Lng32)getArity(); i++)
    {
      if ( coveringGA.covers(child(i)->getValueId(),
			     newExternalInputs,
			     referencedInputs,
			     &localSubExpr) )
	{
	  coveredSubExpr += child(i)->getValueId();
	}
    }

  // ---------------------------------------------------------------------
  // An aggregate function is coerced to fail the coverage test even
  // when its operand isCovered(). This is because the computation of
  // the aggregate function requires "raw" values produced by its
  // operand to be grouped. The aggregated values cannot be treated
  // in the same manner as the constituent raw values.
  // ---------------------------------------------------------------------
  return FALSE;  // sorry, i am a special case

} // Aggregate::isCovered()

// ----------------------------------------------------------------------
// 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.
// ----------------------------------------------------------------------
void Aggregate::getLeafValuesForCoverTest(ValueIdSet & leafValues, 
                                          const GroupAttributes& coveringGA,
                                          const ValueIdSet & newExternalInputs) const
{
  leafValues += getValueId();
} // Aggregate::getLeafValuesForCoverTest()

const NAString Aggregate::getText() const
{
  NAString result(CmpCommon::statementHeap());
  NABoolean dumpMvMode = (CmpCommon::getDefault(MVQR_LOG_QUERY_DESCRIPTORS) == DF_DUMP_MV);

  switch (getOperatorType())
    {
    case ITM_AVG:
      result = "avg";
      break;
    case ITM_MAX:
      result = "max";
      break;
    case ITM_MIN:
      result = "min";
      break;
    case ITM_SUM:
      result = "sum";
      break;
    case ITM_COUNT:
      result = "count";
      break;
    case ITM_COUNT_NONULL:
      if (dumpMvMode)
        result = "count";
      else
        result = "count_nonull";
      break;
    case ITM_GROUPING:
      result = "grouping";
      break;
    case ITM_ONE_ROW:
      result = "one_Row";
      break;
    case ITM_ONE_TRUE:
      result = "oneTrue";
      break;
    case ITM_ANY_TRUE:
      result = "anytrue";
      break;
    case ITM_ANY_TRUE_MAX:
      result = "anytruemax";
      break;
    case ITM_STDDEV:
      result = "stddev";
      break;
    case ITM_VARIANCE:
      result = "variance";
      break;
    case ITM_ONEROW:
      result = "oneRow";
      break;
    case ITM_PIVOT_GROUP:
      result = "pivot_group";
      break;
    default:
      result = "unknown aggr";
      break;
    } // switch

  if (isDistinct_ && !dumpMvMode) {
    result += " distinct";
    if (distinctId_ != NULL_VALUE_ID) {
      char buf[13]; // CollIndex is UInt32 with a max value of 4,294,967,295
                    // We need 10 + 2 + 1=13 bytes to store all possible
                    // values.
      snprintf(buf, sizeof(buf), "(%u)", (CollIndex)distinctId_);
      result += buf;
      // ## Perhaps a better way of displaying this would instead be:
      //	result += "(";
      //	result += distinctId_.getItemExpr()->getText();
      //	result += ")";
    }
  }

  return result;
} // Aggregate::getText()

void Aggregate::unparse(NAString &result,
			PhaseEnum phase,
			UnparseFormatEnum form,
			TableDesc * tabId) const
{
  if (form == USER_FORMAT_DELUXE)
    {
      Aggregate *ncThis = (Aggregate *)this;		// cast away constness!

      OperatorTypeEnum saveType  = getOperatorType();	// save
      ItemExpr        *saveChild = child(0);
      ValueId	       saveVid   = getOriginalChild()->getValueId();

      getOriginalChild()->setValueId(NULL_VALUE_ID);	// BEFORE setChild()!
      ncThis->setOperatorType(origOpType());		// set to "orig"
      ncThis->setChild(0, getOriginalChild());

      ItemExpr::unparse(result,phase, form, tabId);		// invoke superclass

      getOriginalChild()->setValueId(saveVid);		// BEFORE setChild()!
      ncThis->setOperatorType(saveType);		// restore
      ncThis->setChild(0, saveChild);
    }
  else
  {
    if ((CmpCommon::getDefault(MVQR_LOG_QUERY_DESCRIPTORS) == DF_DUMP_MV) && isDistinct_)
    {
      // Fix DISTINCT to be parsable.
      result += getText();
      result += "( DISTINCT ";
      child(0)->unparse(result, phase, form, tabId);
      result += ")";
    }
    else
      ItemExpr::unparse(result, phase, form, tabId);	// invoke our superclass method
  }
} // Aggregate::unparse()

ItemExpr * Aggregate::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  Aggregate *result;

  if (derivedNode == NULL)
    result = new (outHeap) Aggregate(getOperatorType());
  else
    result = (Aggregate *) derivedNode;

  if (inScalarGroupBy())
    result->setInScalarGroupBy();

  if (topPartOfAggr())
    result->setTopPartOfAggr();

  result->origChild_ = origChild_;
  result->isDistinct_ = isDistinct_;
  result->inScalarGroupBy_ = inScalarGroupBy_;
  result->distinctId_ = distinctId_;

  // Copy OLAP Window Function information.
  //
  result->isOLAP_ = isOLAP_;

  result->olapPartitionBy_ = (olapPartitionBy_ ? 
                              olapPartitionBy_->copyTree(outHeap) :
                              NULL);

  result->olapOrderBy_ = (olapOrderBy_ ?
                          olapOrderBy_->copyTree(outHeap) : 
                          NULL);

  result->frameStart_ = frameStart_;
  result->frameEnd_ = frameEnd_;

  result->rollupGroupIndex_ = rollupGroupIndex_;

  return ItemExpr::copyTopNode(result, outHeap);
}

// One heck of an implementation for a virtual function!
NABoolean Aggregate::isSensitiveToDuplicates() const
{
  switch (getOperatorType())
    {
    case ITM_MAX:
    case ITM_MIN:
    case ITM_ANY_TRUE:
    case ITM_ONE_TRUE:
    case ITM_GROUPING:
      return FALSE;

    case ITM_SUM:
    case ITM_COUNT:
    case ITM_COUNT_NONULL:
    case ITM_ONE_ROW:
    case ITM_ONEROW:
    case ITM_AVG:
    default:
      return TRUE;
    } // switch
}

// Another hack of an implementation for a virtual function!!
NABoolean Aggregate::evaluationCanBeStaged() const
{
  switch (getOperatorType())
    {
    case ITM_ONE_ROW:
      // See Aggregate::rewriteForStagedEvaluation()
      return FALSE;

    default:
      return TRUE;
    } // switch
}

ItemExpr * Aggregate::rewriteForElimination()
{
  // rewrite the aggregate function to return the result it would have
  // returned if it were called on a group with exactly one member

  // NOTE: this method doesn't delete the existing aggregate node, but
  // it may reuse some of the children of the original expression.

  ItemExpr *result = NULL;

  switch (getOperatorType())
    {
    case ITM_AVG:
    case ITM_MAX:
    case ITM_MIN:
    case ITM_SUM:
    case ITM_ONEROW:
    case ITM_ANY_TRUE:
    case ITM_PIVOT_GROUP:
      // return the value of the aggregate function's argument
      result = child(0);
      break;

    case ITM_COUNT:
      // the count of a single value is always 1
      result = new (CmpCommon::statementHeap()) SystemLiteral(1);
      break;

    case ITM_COUNT_NONULL:
      if (child(0)->getValueId().getType().supportsSQLnullLogical())
      {
        // generate a CASE expression: CASE WHEN arg IS NOT NULL THEN 1 ELSE 0
        result = new (CmpCommon::statementHeap())
	  Case(NULL,
	       new (CmpCommon::statementHeap())
	       IfThenElse(new (CmpCommon::statementHeap())
			  UnLogic(ITM_IS_NOT_NULL,
				  child(0)),
			  new (CmpCommon::statementHeap()) SystemLiteral(1),
			  new (CmpCommon::statementHeap()) SystemLiteral(0)));
      }
      else
      {
        result = new (CmpCommon::statementHeap()) SystemLiteral(1);
      }
      break;

    case ITM_ONE_TRUE:
      // return TRUE only if the argument is TRUE, FALSE otherwise
      result = new (CmpCommon::statementHeap()) UnLogic(ITM_IS_TRUE,child(0));
      break;

    default:
      ABORT("unknown aggregate function encountered");
    }

  result->synthTypeAndValueId();
  return result;
}

ItemExpr * Aggregate::rewriteForStagedEvaluation(ValueIdList &initialAggrs,
						 ValueIdList &finalAggrs,
						 NABoolean sameFormat)
{
  // Split the aggregate function into three parts: the initial part is
  // executed in multiple groupby nodes whose results are sent to a
  // single, "final" groupby node that executes the final aggregate expression.
  // More than one aggregate function may be evaluated in the initial and/or
  // final nodes, therefore a set parameter is used. The return value is
  // an item expression equivalent to the original expression "this". The
  // return value is not necessarily an aggregate function, while
  // initialAggr and finalAggr contain only aggregate functions.

  // NOTE: this method doesn't delete the existing aggregate node, and it
  // produces new value ids for all three parts returned.

  ItemExpr *result = NULL;
  Aggregate *partial;
  Aggregate *sumOfCounts;
  Aggregate *sumOfSums;

  switch (getOperatorType())
    {
    case ITM_AVG:
      assert(NOT sameFormat);

      // divide the sum of sums by the sum of counts, but return NULL
      // if the sum of counts is zero
      // in pseudo-SQL, that sounds like transforming avg(x) into:
      // CASE WHEN SUM(COUNT(x)) > 0 THEN SUM(SUM(x)) / SUM(COUNT(x))
      //      ELSE NULL

      sumOfCounts = new (CmpCommon::statementHeap())
	Aggregate(ITM_SUM,
		  new (CmpCommon::statementHeap()) Aggregate(ITM_COUNT_NONULL,
							    child(0)));
      partial = new (CmpCommon::statementHeap())
                     Aggregate(ITM_SUM, child(0));

      sumOfSums = new (CmpCommon::statementHeap())
	               Aggregate(ITM_SUM, partial);

      if (inScalarGroupBy())
      {
        partial->setInScalarGroupBy();
        sumOfSums->setInScalarGroupBy();
        sumOfCounts->setInScalarGroupBy();
        ((Aggregate *)(sumOfCounts->child(0).getPtr()))->setInScalarGroupBy();
      }

      // The sum of the counts cannot be zero if the binder typed the
      // avg as non-nullable.
      // An AVG on a non scalar group by on a non-nullable
      // expression is always non-nullable, the sum(sum(x)) is always
      // non-nullable and the sum(count(x)) is always > 0

      if (getValueId().getType().supportsSQLnullLogical())
      {
        result = new (CmpCommon::statementHeap())
	  Case(NULL,
	       new (CmpCommon::statementHeap())
	       IfThenElse(
			  new (CmpCommon::statementHeap())
			  BiRelat(ITM_GREATER,
				  sumOfCounts,
				  new (CmpCommon::statementHeap()) SystemLiteral(0)),
			  new (CmpCommon::statementHeap())
			  BiArith(ITM_DIVIDE,sumOfSums,sumOfCounts),
			  new (CmpCommon::statementHeap()) SystemLiteral()));
      }
      else
      {
        result = new (CmpCommon::statementHeap())
                     BiArith(ITM_DIVIDE,sumOfSums,sumOfCounts);
      }

      result->synthTypeAndValueId();

      // execute the initial sum and count in the initial set
      initialAggrs.insert(sumOfCounts->child(0)->getValueId());
      initialAggrs.insert(sumOfSums->child(0)->getValueId());
      finalAggrs.insert(sumOfCounts->getValueId());
      finalAggrs.insert(sumOfSums->getValueId());
      break;

    case ITM_COUNT:
    case ITM_COUNT_NONULL:
      // compute the sum of the counts
      partial = new (CmpCommon::statementHeap())
                  Aggregate(getOperatorType(),child(0));

      sumOfCounts = new (CmpCommon::statementHeap())
                  Aggregate(ITM_SUM, partial);

      if (inScalarGroupBy())
      {
        partial->setInScalarGroupBy();
        sumOfCounts->setInScalarGroupBy();
      }
      sumOfCounts->setTreatAsACount();
      sumOfCounts->setTopPartOfAggr();
      result = sumOfCounts;

      result->synthTypeAndValueId();

      // If we have to force the same type for the initial and final
      // aggregate expressions, then force the type of the sum to
      // be the same as the type of the count.
      if (sameFormat)
	result->getValueId().changeType(&(result->child(0)->
					getValueId().getType()));

      // execute the nested aggregate function in the initial set
      initialAggrs.insert(result->child(0)->getValueId());
      finalAggrs.insert(result->getValueId());
      break;

    case ITM_MAX:
    case ITM_MIN:
    case ITM_SUM:
    case ITM_ANY_TRUE:
    case ITM_ONEROW:
    case ITM_GROUPING:
      // in these cases, just do the same aggregate function twice
      partial = new (CmpCommon::statementHeap())
                     Aggregate(getOperatorType(), child(0));

      result = new (CmpCommon::statementHeap())
                    Aggregate(getOperatorType(), partial);

      if (getOperatorType() == ITM_GROUPING)
        {
          ((Aggregate *)partial)->setRollupGroupIndex(getRollupGroupIndex());
          ((Aggregate *)result)->setRollupGroupIndex(getRollupGroupIndex());
        }

      if (inScalarGroupBy())
      {
        partial->setInScalarGroupBy();
        ((Aggregate *)result)->setInScalarGroupBy();
      }
      ((Aggregate *)result)->setTopPartOfAggr();

      // fix case 10-081203-5622, soln 10-081203-7701 by preserving this'
      // "treatAsACount_ & amTopPartOfAggr_" attribute settings.
      if (treatAsACount()) {
        partial->setTreatAsACount();
        ((Aggregate*)result)->setTreatAsACount();
      }
      if (topPartOfAggr()) {
        partial->setTopPartOfAggr();
      }
        
      result->synthTypeAndValueId();

      // If we have to force the same type for the initial and final
      // aggregate expressions, then force the type of the sum to
      // be the same as the type of the sum/min/max etc...
      if (sameFormat)
	result->getValueId().changeType(&(result->child(0)->
					  getValueId().getType()));

      // execute the nested aggregate function in the initial set
      initialAggrs.insert(result->child(0)->getValueId());
      finalAggrs.insert(result->getValueId());
      break;

    case ITM_ONE_TRUE:
      partial = new (CmpCommon::statementHeap())
                     Aggregate(getOperatorType(), child(0));

      result = new (CmpCommon::statementHeap())
                    Aggregate(ITM_ANY_TRUE, partial);

      if (inScalarGroupBy())
      {
        partial->setInScalarGroupBy();
        ((Aggregate *)result)->setInScalarGroupBy();
      }

      result->synthTypeAndValueId();

      // If we have to force the same type for the initial and final
      // aggregate expressions, then force the type of the sum to
      // be the same as the type of the sum/min/max etc...
      if (sameFormat)
	result->getValueId().changeType(&(result->child(0)->
					  getValueId().getType()));

      // execute the nested aggregate function in the initial set
      initialAggrs.insert(result->child(0)->getValueId());
      finalAggrs.insert(result->getValueId());
      break;

    case ITM_ONE_ROW:
      // need another aggregate function that handles the case where
      // some servers return NULL rows
      ABORT("sorry, one row aggregates cannot be implemented in a staged fashion");
      break;

    default:
      ABORT("unknown aggregate function encountered");
    }

  return result;
}

ItemExpr * PivotGroup::rewriteForStagedEvaluation(ValueIdList &initialAggrs,
                                                  ValueIdList &finalAggrs,
                                                  NABoolean sameFormat)
{
  // Split the aggregate function into three parts: the initial part is
  // executed in multiple groupby nodes whose results are sent to a
  // single, "final" groupby node that executes the final aggregate expression.
  // More than one aggregate function may be evaluated in the initial and/or
  // final nodes, therefore a set parameter is used. The return value is
  // an item expression equivalent to the original expression "this". The
  // return value is not necessarily an aggregate function, while
  // initialAggr and finalAggr contain only aggregate functions.

  // NOTE: this method doesn't delete the existing aggregate node, and it
  // produces new value ids for all three parts returned.

  ItemExpr *result = NULL;
  Aggregate *partial;

  partial = new (CmpCommon::statementHeap())
    PivotGroup(getOperatorType(), child(0), pivotOptionsList_, isDistinct());
  
  result = new (CmpCommon::statementHeap())
    PivotGroup(ITM_PIVOT_GROUP, partial, NULL);
  
  if (inScalarGroupBy())
    {
      partial->setInScalarGroupBy();
      ((Aggregate *)result)->setInScalarGroupBy();
    }
  
  result->synthTypeAndValueId();
  
  // If we have to force the same type for the initial and final
  // aggregate expressions, then force the type of the sum to
  // be the same as the type of the sum/min/max etc...
  if (sameFormat)
    result->getValueId().changeType(&(result->child(0)->
					  getValueId().getType()));
  
  // execute the nested aggregate function in the initial set
  initialAggrs.insert(result->child(0)->getValueId());
  finalAggrs.insert(result->getValueId());
  
  return result;
}

// Aggregate::isEquivalentForBinding Determine if these two
// ItemExprs are equivalent.  If so, one may be eliminated and
// replaced with the other.
// Inputs:
//   ItemExpr *other - the ItemExpr being compared to 'this'
//
// Outputs: return value: Returns TRUE if the 'other' ItemExpr is
// equivalent to 'this'.  In order to be equivalent, they must:
//     - Have equivalent children
//       (determined by 'hasBaseEquivalenceForCodeGeneration()
//     - Be the same aggregate. (same operatorType)
//       (determined by 'hasBaseEquivalenceForCodeGeneration()
//     - have the same distinct settings and if distinct, must both
//       be distinct with respect to the immediate child.  This could
//       prevent otherwise equivalent distinct STDDEV and VARIANCE aggregates
//       from being eliminated.
//
NABoolean Aggregate::isEquivalentForBinding(const ItemExpr * other)
{

  // Make sure that the children are equivalent and that this and
  // other are the same operator
  //
  if (hasBaseEquivalenceForCodeGeneration(other))
    {
      // we know that other is an Aggregate, its operator type is the same,
      // and that the children are equivalent
      Aggregate * otherAggregate = (Aggregate *)other;

      // Both must have the same distinct settings.
      //
      if(isDistinct() != otherAggregate->isDistinct()) {
        return FALSE;
      }

      // Both must have the same inScalarGroupBy settings.
      //
      if(inScalarGroupBy() != otherAggregate->inScalarGroupBy()) {
        return FALSE;
      }

      // If both are distinct (sufficient to check one since we know
      // both are the same).
      //
      if(isDistinct()) {

        // If they are distinct, both must be distinct on the
        // immediate child.  VARIANCE and STDDEV are transformed into
        // a more complicated expression and the distinct valueid will
        // not be the immediate child.  So this means that the
        // distinct versions of VARIANCE and STDDEV will not be
        // considered for elimination even though they may qualify.
        // Furthermore, the 'this' version of a distinct VARIANCE or
        // STDDEV will not have its distinctID set properly until
        // after this routine is called (but the 'other' one will).
        //
        if(getDistinctValueId() != child(0)->getValueId()) {
          return FALSE;
        }

        if(otherAggregate->getDistinctValueId() !=
           otherAggregate->child(0)->getValueId()) {
          return FALSE;
        }
      }

      // the two values are equivalent.
      return TRUE;
    }

  return FALSE;
}

// Return the equivalent running sequence function operator type
//
OperatorTypeEnum Aggregate::mapOperTypeToRunning() const
{
  switch(getOperatorType()) {
  case ITM_AVG:
    return ITM_RUNNING_AVG;
    break;
  case ITM_COUNT:
    return ITM_RUNNING_COUNT;
    break;
  case ITM_COUNT_NONULL:
    return ITM_RUNNING_COUNT;
    break;
  case ITM_MAX:
    return ITM_RUNNING_MAX;
    break;
  case ITM_MIN:
    return ITM_RUNNING_MIN;
    break;
  case ITM_STDDEV:
    return ITM_RUNNING_SDEV;
    break;
  case ITM_SUM:
    return ITM_RUNNING_SUM;
    break;
  case ITM_VARIANCE:
    return ITM_RUNNING_VARIANCE;
    break;
  case ITM_RUNNING_RANK:
    return ITM_RUNNING_RANK;
    break;
  case ITM_RUNNING_DRANK:
    return ITM_RUNNING_DRANK;
    break;
  default:
    return INVALID_OPERATOR_TYPE;
  }
}
OperatorTypeEnum Aggregate::mapOperTypeToOlap() const
{
  switch(getOperatorType()) {
  case ITM_AVG:
    return ITM_OLAP_AVG;
    break;
  case ITM_COUNT:
    return ITM_OLAP_COUNT;
    break;
  case ITM_COUNT_NONULL:
    return ITM_OLAP_COUNT;
    break;
  case ITM_MAX:
    return ITM_OLAP_MAX;
    break;
  case ITM_MIN:
    return ITM_OLAP_MIN;
    break;
  case ITM_STDDEV:
    return ITM_OLAP_SDEV;
    break;
  case ITM_SUM:
    return ITM_OLAP_SUM;
    break;
  case ITM_VARIANCE:
    return ITM_OLAP_VARIANCE;
    break;
  case ITM_RUNNING_RANK:
    return ITM_OLAP_RANK;
    break;
  case ITM_RUNNING_DRANK:
    return ITM_OLAP_DRANK;
    break;
  default:
    return INVALID_OPERATOR_TYPE;
  }
}


// Return the equivalent moving sequence function operator type
//
OperatorTypeEnum Aggregate::mapOperTypeToMoving() const
{
  switch(getOperatorType()) {
  case ITM_AVG:
    return ITM_MOVING_AVG;
    break;
  case ITM_COUNT:
    return ITM_MOVING_COUNT;
    break;
  case ITM_COUNT_NONULL:
    return ITM_MOVING_COUNT;
    break;
  case ITM_MAX:
    return ITM_MOVING_MAX;
    break;
  case ITM_MIN:
    return ITM_MOVING_MIN;
    break;
  case ITM_STDDEV:
    return ITM_MOVING_SDEV;
    break;
  case ITM_SUM:
    return ITM_MOVING_SUM;
    break;
  case ITM_VARIANCE:
    return ITM_MOVING_VARIANCE;
    break;
  case ITM_RUNNING_RANK:
    return ITM_MOVING_RANK;
    break;
  case ITM_RUNNING_DRANK:
    return ITM_MOVING_DRANK;
    break;
  default:
    return INVALID_OPERATOR_TYPE;
  }
}
OperatorTypeEnum ItmSeqOlapFunction::mapOperTypeToRunning() const
{
  switch(getOperatorType()) {
  case ITM_OLAP_AVG:
    return ITM_RUNNING_AVG;
    break;
  case ITM_OLAP_COUNT:
    return ITM_RUNNING_COUNT;
    break;
  case ITM_OLAP_MAX:
    return ITM_RUNNING_MAX;
    break;
  case ITM_OLAP_MIN:
    return ITM_RUNNING_MIN;
    break;
  case ITM_OLAP_SDEV:
    return ITM_RUNNING_SDEV;
    break;
  case ITM_OLAP_SUM:
    return ITM_RUNNING_SUM;
    break;
  case ITM_OLAP_VARIANCE:
    return ITM_RUNNING_VARIANCE;
    break;
  case ITM_OLAP_RANK:
    return ITM_RUNNING_RANK;
    break;
  case ITM_OLAP_DRANK:
    return ITM_RUNNING_DRANK;
    break;
  default:
    return INVALID_OPERATOR_TYPE;
  }
}



OperatorTypeEnum ItmSeqOlapFunction::mapOperTypeToMoving() const
{
  switch(getOperatorType()) {
  case ITM_OLAP_AVG:
    return ITM_MOVING_AVG;
    break;
  case ITM_OLAP_COUNT:
    return ITM_MOVING_COUNT;
    break;
  case ITM_OLAP_MAX:
    return ITM_MOVING_MAX;
    break;
  case ITM_OLAP_MIN:
    return ITM_MOVING_MIN;
    break;
  case ITM_OLAP_SDEV:
    return ITM_MOVING_SDEV;
    break;
  case ITM_OLAP_SUM:
    return ITM_MOVING_SUM;
    break;
  case ITM_OLAP_VARIANCE:
    return ITM_MOVING_VARIANCE;
    break;
  case ITM_OLAP_RANK:
    return ITM_MOVING_RANK;
    break;
  case ITM_OLAP_DRANK:
    return ITM_MOVING_DRANK;
    break;
  default:
    return INVALID_OPERATOR_TYPE;
  }
}


// transformOlapFunction.
// Transform OLAP Window aggregate functions into their equivalent 
// sequence functions.
//
// Also verifies that all OLAP Window function are using the same Window
// specification (partition by and order by).  If not, an error message
// is put into the diags area.
// 
// Inputs - this - the Aggregate with OLAP information 
//                 (partition by and order by)
//
//          bindWA - Used to get current scope for error handling

// Returns - transformed expression.
//         - NULL on error
//
ItemExpr *Aggregate::transformOlapFunction(BindWA *bindWA)
{
  if(NOT isOLAP_) {
    // Not an OLAP aggregate.
    return this;
  }

  // If this is an illegal Frame Specification, then issue an error.
  //
  if ((frameStart_ > frameEnd_) || 
      (isFrameStartUnboundedFollowing()) || // frameStart_ == INT_MAX) || 
      (isFrameEndUnboundedPreceding())) //frameEnd_ == -INT_MAX ))
    {
      *CmpCommon::diags() << DgSqlCode(-4342);
      bindWA->setErrStatus();
      return NULL;
    } 

  if (!olapOrderBy_ && ( getOperatorType() == ITM_RUNNING_RANK || getOperatorType() == ITM_RUNNING_DRANK))
    {//The use of RANK or DENSE_RANK window functions without a window ORDER BY clause is not supported.
      *CmpCommon::diags() << DgSqlCode(-4344);
      bindWA->setErrStatus();
      return NULL;     
    }
  // Distinct is not supported for Window Functions.
  //
  if (this->isDistinct_)
    {
      *CmpCommon::diags() << DgSqlCode(-4341);
      bindWA->setErrStatus();
      return NULL;
    }

  BindScope *currScope = bindWA->getCurrentScope();

  // OLAP Window functions can only be in the select list
  //
  if (! currScope->context()->inSelectList())
    {
      *CmpCommon::diags() << DgSqlCode(-4346);
      bindWA->setErrStatus();
      return NULL;     

    }
 
  if (currScope->context()->inAggregate())
    {
      *CmpCommon::diags() << DgSqlCode(-4375) << DgString0(getTextUpper());
      bindWA->setErrStatus();
      return NULL;     

    }

  ValueIdList  partition_vil, order_vil;
  ItemExpr * tmpItemExpr = NULL;

  // Verify that all Window Functions within this scope, use the
  // same Window Specification (partition by and order by)
  //

  // The Sequence functions are bound in the environment (RETDesc) of
  // the child of the OLAP Sequence if one exists
  //
  RelExpr *sequenceNode = currScope->getSequenceNode();
  RETDesc *currentRETDesc = currScope->getRETDesc();
   
  currScope->setRETDesc(sequenceNode->child(0)->getRETDesc());

  if (olapPartitionBy_)
    {
      currScope ->context()->inOrderBy() = TRUE;
      currScope ->context()->inOlapPartitionBy() = TRUE;
      olapPartitionBy_->convertToValueIdList(partition_vil, bindWA, ITM_ITEM_LIST);
      currScope ->context()->inOlapPartitionBy() = FALSE;
      currScope ->context()->inOrderBy() = FALSE;

      if (bindWA->errStatus())
        return NULL;
    }

  if (olapOrderBy_)
    {
      currScope->context()->inOtherSequenceFunction() = TRUE;
      currScope ->context()->inOrderBy() = TRUE;
      currScope ->context()->inOlapOrderBy() = TRUE;
      olapOrderBy_->convertToValueIdList(order_vil, bindWA, ITM_ITEM_LIST);
      currScope ->context()->inOlapOrderBy() = FALSE;
      currScope ->context()->inOrderBy() = FALSE;
      currScope->context()->inOtherSequenceFunction() = FALSE;

      if (bindWA->errStatus())
        return NULL;
    }
    
  currScope->setRETDesc(currentRETDesc);
    
  // If this is the first Window Function to be bound in this scope,
  // remember the partition and order by lists.
  //
  if ( currScope->getIsFirstOlapWindowSpec() )
    { 
      currScope->setOlapPartition( partition_vil );
      currScope->setOlapOrder( order_vil );
      currScope->setIsFirstOlapWindowSpec ( FALSE );
    } 
  else 
    {
      // Check to see if the partition by and order by for this Window
      // Function is the same as all the others we have bound in this
      // scope so far.
      //
      NABoolean olap = TRUE;
      if (partition_vil.entries() != currScope->getOlapPartition().entries() ||
	  order_vil.entries() != currScope->getOlapOrder().entries())
        {
          olap = FALSE;
        }
      for(CollIndex i = 0; olap && i < partition_vil.entries(); i++) 
        {
          ItemExpr *ie = currScope->getOlapPartition()[i].getItemExpr();
          ItemExpr *otherIe = partition_vil[i].getItemExpr();
          if(!ie->hasBaseEquivalence(otherIe)) 
            {
              olap = FALSE;
            }
        }

      for(CollIndex i = 0;  olap && i < order_vil.entries(); i++) 
        {
          ValueId vid1, vid2;
          vid1 = currScope->getOlapOrder()[i];
          vid2 = order_vil[i];
          if (order_vil[i].getItemExpr()->getOperatorType() == ITM_INVERSE &&
              currScope->getOlapOrder()[i].getItemExpr()->getOperatorType() == ITM_INVERSE)
            {
              vid1 = currScope->getOlapOrder()[i].getItemExpr()->child(0).getValueId();
              vid2 = order_vil[i].getItemExpr()->child(0).getValueId();
            }
	 
          ItemExpr *ie = vid1.getItemExpr();
          ItemExpr *otherIe = vid2.getItemExpr();
          if( !ie->hasBaseEquivalence(otherIe)) 
            {
              olap = FALSE;
            }
        }

      if (! olap)
        {
          // The Window Specification for this Window Function is not
          // the same as the others we have bound so far in this scope.
          //
          *CmpCommon::diags() << DgSqlCode(-4340);
          bindWA->setErrStatus();
          return NULL;
        }
    }
 
    CollHeap *heap = CmpCommon::statementHeap();

    OperatorTypeEnum op = mapOperTypeToOlap();

    ItmSeqOlapFunction *seqFunc = new (heap)
                ItmSeqOlapFunction(op, child(0));

    seqFunc->setOLAPInfo(olapPartitionBy_, olapOrderBy_);
    seqFunc->setOlapWindowFrame(frameStart_, frameEnd_);
                                        
    return seqFunc;


}


QR::ExprElement Aggregate::getQRExprElem() const
{
  return QR::QRFunctionElem;
}


// -----------------------------------------------------------------------
// member functions for class Variance
// -----------------------------------------------------------------------
Variance::~Variance() {}

ItemExpr * Variance::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  Variance *result;

  if (derivedNode == NULL)
    result = new (outHeap) Variance(getOperatorType(), NULL, NULL, isDistinct());
  else
    result = (Variance *) derivedNode;

  return Aggregate::copyTopNode(result, outHeap);
}

// -----------------------------------------------------------------------
// member functions for class PivotGroup
// -----------------------------------------------------------------------
PivotGroup::PivotGroup(OperatorTypeEnum otype,
                       ItemExpr *child0,
                       NAList<PivotOption*> * pivotOptionsList,
                       NABoolean isDistinct)
  : Aggregate(otype, child0, NULL, isDistinct),
    pivotOptionsList_(pivotOptionsList),
    maxLen_(DEFAULT_MAX_LEN),
    delim_(","),
    orderBy_(FALSE)
{
  if (pivotOptionsList)
    {
      for (CollIndex i = 0; i < pivotOptionsList->entries(); i++)
	{
	  PivotOption * po = (*pivotOptionsList)[i];
	  switch (po->option_)
	    {
	    case DELIMITER_:
	      {
		delim_ = *po->stringVal_;
              }
              break;

	    case MAX_LENGTH_:
	      {
		maxLen_ = po->numericVal_;
              }
              break;

            case ORDER_BY_:
              {
                orderBy_ = TRUE;
                // optionNode_ contains the ItemExpr 
                orgReqOrder_ = (ItemExpr *)po->optionNode_; 
              }
              break;
            }
        }
    }
}

PivotGroup::~PivotGroup() {}

ItemExpr * PivotGroup::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  PivotGroup *result;

  if (derivedNode == NULL)
    result = new (outHeap) PivotGroup(getOperatorType(), NULL, NULL, isDistinct());
  else
    result = (PivotGroup *) derivedNode;

  result->pivotOptionsList_ = pivotOptionsList_;
  result->delim_ = delim_;
  result->orderBy_ = orderBy_;
  result->reqdOrder_ = reqdOrder_;
  result->orgReqOrder_ = orgReqOrder_;
  result->maxLen_ = maxLen_;

  return Aggregate::copyTopNode(result, outHeap);
}

// -----------------------------------------------------------------------
// member functions for class Function
// -----------------------------------------------------------------------
Function::Function(OperatorTypeEnum otype,
                   NAMemory *h,
		   Lng32   argumentCount,
		   ItemExpr *child0,
		   ItemExpr *child1,
		   ItemExpr *child2,
		   ItemExpr *child3,
		   ItemExpr *child4,
		   ItemExpr *child5)
           : ItemExpr(otype),
	     children_(h,argumentCount),
	     allowsSQLnullArg_(TRUE)
{
  Lng32 lastInserted = -1;
  ItemExpr *childx;

  for (Lng32 i = 0; i < (Lng32)argumentCount; i++)
    {
      childx = IFX i==0
	THENX child0
	ELSEX IFX i==1
	THENX child1
	ELSEX IFX i==2
	THENX child2
	ELSEX IFX i==3
	THENX child3
	ELSEX IFX i==4
	THENX child4
	ELSEX IFX i==5
	THENX child5
	ELSEX (ItemExpr *) NULL;

      CMPASSERT((Lng32)children_.entries() == i);

      children_.insertAt(i, childx);
    } // end for
}

Function::Function(OperatorTypeEnum otype, const LIST(ItemExpr *) &children, 
                   CollHeap *h)
         : ItemExpr(otype),
	   children_(h)
{
  Lng32 ne = children.entries();

  for (Lng32 i = 0; i < ne; i++)
    {
      children_.insertAt(i,children[i]);
    }
}

Function::~Function() {}

Lng32 Function::getNumChildren() const
{
  Lng32 count = children_.entries();
  // $$$$ Skip all the NULL children at the tail end.
  // $$$$ Assumes children that are missing in the middle
  // $$$$ should figure in the count, e.g., F(a, NULL, b, NULL, NULL)
  while ( (count > 0) AND (children_[count-1].getPtr() == NULL) )
    count--;
  return count;
}

ItemExpr * Function::copyTopNode(ItemExpr * derivedNode, CollHeap* outHeap)
{
  Function *result = NULL;
  if (derivedNode == NULL)
    ABORT("copyTopNode() can only be called for a derived class of Function");
  else
    result = (Function *)derivedNode;

  result->allowsSQLnullArg() = allowsSQLnullArg();

  // Make sure we copy the kids as well.
  Lng32 ne = children_.entries();
  for (Lng32 i = 0; i < ne; i++)
    result->children_.insertAt(i, children_[i]);

  return ItemExpr::copyTopNode(result, outHeap);
}

ExprValueId & Function::operator[] (Lng32 index)
{
 CMPASSERT( (index >= 0) AND (index < (Lng32)children_.entries()) );
 return children_[index];
}

const ExprValueId & Function::operator[] (Lng32 index) const
{
  CMPASSERT( (index >= 0) AND (index < (Lng32)children_.entries()) );
  return children_[index];
}

// -----------------------------------------------------------------------
// member functions for class BuiltinFunction
// -----------------------------------------------------------------------
BuiltinFunction::BuiltinFunction(OperatorTypeEnum otype,
                                 NAMemory *h,
				 Lng32  argumentCount,
				 ItemExpr *child0,
				 ItemExpr *child1,
				 ItemExpr *child2,
				 ItemExpr *child3,
				 ItemExpr *child4,
				 ItemExpr *child5)
     : Function(otype,h,argumentCount,child0,child1,child2,child3,child4,child5)
{
  switch (getOperatorType())
    {
    case ITM_NULLIFZERO:
    case ITM_QUERYID_EXTRACT:
    case ITM_TOKENSTR:
    case ITM_REVERSE: {
	allowsSQLnullArg() = FALSE;
      }
    break;

    default:
      {
      }
    break;
    }
}

BuiltinFunction::~BuiltinFunction() {}

Int32 BuiltinFunction::getArity() const
{
  return getNumChildren();
}

// -----------------------------------------------------------------------
// BuiltinFunction::isCovered()
// -----------------------------------------------------------------------
NABoolean BuiltinFunction::isCovered
                             (const ValueIdSet& newExternalInputs,
		              const GroupAttributes& coveringGA,
		              ValueIdSet& referencedInputs,
		              ValueIdSet& coveredSubExpr,
		              ValueIdSet& unCoveredExpr) const
{

  // ITM_CURRENT_USER function should appear as an input characteristic
  // of the root for it to be evaluated by the executor. And hence it
  // needs to be treated differently from other BuiltinFunctions. For
  // it to be propogated to the root, it should not be covered.
  // Case 10-010419-2366

  if (isAUserSuppliedInput())  // for user(x), current_timestamp, extract (fix)
     return FALSE;

  // A BuiltinFunction with no arguments (children)
  // is like a constant. It is always covered.
  Lng32 nc = getNumChildren();
  if (nc == 0)
    return TRUE;

  // ---------------------------------------------------------------------
  // A BuiltinFunction can contain values that are produced by
  // different sources. The BuiltinFunction is covered if each
  // operand is covered.
  // The coverage test insists on a complete coverage of all the
  // children.
  // ---------------------------------------------------------------------
  ValueIdSet childValues;
  for (Int32 i = 0; i < nc; i++)
    childValues += child(i).getValueId();
  return childValues.isCovered(newExternalInputs,
			      coveringGA,
			      referencedInputs,
			      coveredSubExpr,
			      unCoveredExpr);
} // BuiltinFunction::isCovered()

NABoolean BuiltinFunction::isCacheableExpr(CacheWA& cwa)
{
  switch (getOperatorType())
    {
    case ITM_NULLIFZERO:
    case ITM_QUERYID_EXTRACT:
    case ITM_TOKENSTR:
      {
	return ItemExpr::isCacheableExpr(cwa);
      }
    break;

    case ITM_NVL:
    case ITM_REVERSE:
      {
	return FALSE;
      }
    break;
    case ITM_JSONOBJECTFIELDTEXT:
    {
	    return FALSE;
    }
    break;

    default:
      {
	return Function::isCacheableExpr(cwa);
      }
    break;
    }
}

const NAString BuiltinFunction::getText() const
{
  NABoolean dumpMvMode = (CmpCommon::getDefault(MVQR_LOG_QUERY_DESCRIPTORS) == DF_DUMP_MV);

  switch (getOperatorType())
    {
    case ITM_ABS:
      return "abs";
    case ITM_ASCII:
      return "ascii";
    case ITM_AUTHNAME:
      return "authname";
    case ITM_AUTHTYPE:
      return "authtype";
    case ITM_BETWEEN:
      return "between";
    case ITM_BLOCK:
      return "block";
    case ITM_BOOL_RESULT:
      return "bool_result";
    case ITM_CASE:
      return "case";
    case ITM_CAST:
      return "cast";
    case ITM_CAST_CONVERT:
      return "cast_convert";
    case ITM_CAST_TYPE:
      return "typecast";
    case ITM_CHAR:
      return "char";
    case ITM_CHAR_LENGTH:
      return "char_length";
    case ITM_COALESCE:
      return "coalesce";
    case ITM_COMP_ENCODE:
      return "comp_encode";
    case ITM_COMP_DECODE:
      return "comp_decode";
    case ITM_CONCAT:
      return "||";				// "concat";
    case ITM_CONVERTFROMHEX:
      return "CONVERTFROMHEX";
    case ITM_CONVERTTOHEX:
      return "CONVERTTOHEX";
    case ITM_CONVERTTOBITS:
      return "CONVERTTOBITS";
    case ITM_CONVERTTIMESTAMP:
      return "converttimestamp";
    case ITM_SLEEP:
      return "sleep";
    case ITM_UNIX_TIMESTAMP:
      return "unix_timestamp";
    case ITM_CURRENT_TIMESTAMP:
      return "current_timestamp";
    case ITM_CURRENT_TIMESTAMP_RUNNING:
      return "current_timestamp_running";
    case ITM_CURRENT_USER:
      return "current_user";
    case ITM_DATEFORMAT:
      return "dateformat";
    case ITM_DAYOFMONTH:
      return "dayofmonth";
    case ITM_DAYOFWEEK:
      return "dayofweek";
    case ITM_DO_WHILE:
      return "do while";
    case ITM_WHILE:
      return "while";
    case ITM_EXPLODE_VARCHAR:
      return "explodevarchar";
    case ITM_EXTRACT:
      return "extract";
    case ITM_EXTRACT_ODBC:
      return "extract_odbc";
    case ITM_GREATEST:
     return "greatest";
    case ITM_LEAST:
     return "least";
    case ITM_IN:
      return "in";
    case ITM_INSTANTIATE_NULL:
      // getenv() calls are costly. avoid especially in release code.
#ifndef NDEBUG
      if (getenv("SIMPLE_DISPLAY")) return "iNull";
#endif
      return "instantiate_null";
    case ITM_JULIANTIMESTAMP:
      return "juliantimestamp";
    case ITM_EXEC_COUNT:
      return "execution_count";
    case ITM_CURR_TRANSID:
      return "current_transid";
    case ITM_LIKE:
    case ITM_LIKE_DOUBLEBYTE:
      return "like";
    case ITM_REGEXP:
      return "regexp";
    case ITM_LOWER:
    case ITM_LOWER_UNICODE:
      return "lower";
    case ITM_NARROW:
      return "narrow";
    case ITM_NULLIFZERO:
      return "nullifzero";
    case ITM_NVL:
      return "nvl";
    case ITM_JSONOBJECTFIELDTEXT:
      return "json_object_field_text";
    case ITM_QUERYID_EXTRACT:
      return "queryid_extract";
    case ITM_UPPER:
    case ITM_UPPER_UNICODE:
      return "upper";
    case ITM_UNICODE_CHAR:
      return "unicode_char";
    case ITM_NO_OP:
      return "no_op";
    case ITM_POSITION:
      return "position";
    case ITM_REPEAT:
      return "repeat";
    case ITM_REPLACE:
      return "replace";
    case ITM_REPLACE_NULL:
      return "replace null";
    case ITM_RETURN_TRUE:
      if (dumpMvMode)
        return "1";
      else
        return "return_true";
    case ITM_RETURN_FALSE:
      if (dumpMvMode)
        return "0";
      else
        return "return_false";
    case ITM_RETURN_NULL:
      if (dumpMvMode)
        return "null";
      else
        return "return_unknown";
    case ITM_SESSION_USER:
      return "session_user";
    case ITM_OCTET_LENGTH:
      return "octet_length";
    case ITM_HASH:
      return "hash";
    case ITM_HASH2_DISTRIB:
      return "hash2_distrib";
    case ITM_MOD:
      return "mod";
    case ITM_INVERSE:
      return "inverse";
    case ITM_SUBSTR:
    case ITM_SUBSTR_DOUBLEBYTE:
      return "substring";
    case ITM_TRANSLATE:
      return "translate";
    case ITM_TRIM:
    case ITM_TRIM_DOUBLEBYTE:
      return "trim";
    case ITM_IF_THEN_ELSE:
      return "if_then_else";
    case ITM_LESS_OR_LE:
      return "< or <=";
    case ITM_GREATER_OR_GE:
      return "> or >=";
    case ITM_RANGE_LOOKUP:
      return "range_lookup";
    case ITM_RANDOMNUM:
      return "randomNum";
    case ITM_RAND_SELECTION:
      return "randomSelection";
    case ITM_ROUND_ROBIN:
      return "Round_Robin";
    case ITM_PACK_FUNC:
      return "pack";
    case ITM_SAMPLE_VALUE:
      return "sample_size";
    case ITM_UNIQUE_SHORT_ID:
      return "unique_short_id";
    case ITM_UNIQUE_ID:
      return "unique_id";
    case ITM_HBASE_COLUMN_LOOKUP:
      return "hbase_column_lookup";
    case ITM_HBASE_COLUMNS_DISPLAY:
      return "hbase_columns_display";
    case ITM_HBASE_COLUMN_CREATE:
      return "hbase_column_create";
    case ITM_SEQUENCE_VALUE:
      return "seqnum";
    case ITM_ROWNUM:
      return "rownum";
    case ITM_USER:
      return "user";
    case ITM_UNIQUE_EXECUTE_ID:
      return "unique_execute_id";
    case ITM_GET_TRIGGERS_STATUS:
      return "get_triggers_status";
    case ITM_GET_BIT_VALUE_AT:
      return "get_bit_value_at";
    case ITM_IS_BITWISE_AND_TRUE:
      return "is_bitwise_and_true";
    case ITM_USERID:
      return "os_userid";
    case ITM_CURRENTEPOCH:
      return "current_epoch";
    case ITM_VSBBROWTYPE:
      return "vsbb_row_type";
    case ITM_VSBBROWCOUNT:
      return "vsbb_row_count";
    case ITM_INTERNALTIMESTAMP:
      return "internal_timestamp";
    case ITM_SCALAR_MIN:
      return "scalar_min";
    case ITM_SCALAR_MAX:
      return "scalar_max";
    case ITM_TOKENSTR:
      return "TOKENSTR";
    case ITM_REVERSE:
      return "REVERSE";

    // ZZZBinderFunction classes (for error messages only)
    case ITM_DATE_TRUNC_YEAR:
    case ITM_DATE_TRUNC_MONTH:
    case ITM_DATE_TRUNC_DAY:
    case ITM_DATE_TRUNC_HOUR:
    case ITM_DATE_TRUNC_MINUTE:
    case ITM_DATE_TRUNC_SECOND:
    case ITM_DATE_TRUNC_CENTURY:
    case ITM_DATE_TRUNC_DECADE:
      return "date_trunc";
    case ITM_DATEDIFF_YEAR:
    case ITM_DATEDIFF_MONTH:
    case ITM_DATEDIFF_DAY:
    case ITM_DATEDIFF_HOUR:
    case ITM_DATEDIFF_MINUTE:
    case ITM_DATEDIFF_SECOND:
    case ITM_DATEDIFF_QUARTER:
    case ITM_DATEDIFF_WEEK:
      return "datediff";
    case ITM_TSI_YEAR:
    case ITM_TSI_MONTH:
    case ITM_TSI_DAY:
    case ITM_TSI_HOUR:
    case ITM_TSI_MINUTE:
    case ITM_TSI_SECOND:
    case ITM_TSI_QUARTER:
    case ITM_TSI_WEEK:
      return "timestampdiff";
    case ITM_DAYNAME:
      return "dayname";
    case ITM_DAYOFYEAR:
      return "dayofyear";
    case ITM_DECODE:
      return "decode";
    case ITM_FIRSTDAYOFYEAR:
      return "firstdayofyear";
    case ITM_LAST_DAY:
      return "last_day";
    case ITM_NEXT_DAY:
      return "next_day";
    case ITM_INSERT_STR:
      return "insert";
    case ITM_LEFT:
      return "left";
    case ITM_LPAD:
      return "lpad";
    case ITM_MONTHNAME:
      return "monthname";
    case ITM_NULLIF:
      return "nullif";
    case ITM_ODBC_LENGTH:
      return "LENGTH";
    case ITM_QUARTER:
      return "quarter";
    case ITM_RIGHT:
      return "right";
    case ITM_RPAD:
      return "rpad";
    case ITM_SIGN:
      return "sign";
    case ITM_SPACE:
      return "space";
    case ITM_CODE_VALUE:
    case ITM_UNICODE_CODE_VALUE:
    case ITM_NCHAR_MP_CODE_VALUE:
      return "code_value";
    case ITM_WEEK:
      return "week";
    case ITM_ZEROIFNULL:
      return "zeroifnull";

      
    case ITM_LOBINSERT:
      return "lobinsert";

    case ITM_LOBSELECT:
      return "lobselect";

    case ITM_LOBDELETE:
      return "lobdelete";

    case ITM_LOBUPDATE:
      return "lobupdate";

    case ITM_LOBCONVERTHANDLE:
      return "lobconverthandle";

    case ITM_LOBCONVERT:
      return "lobconvert";

    case ITM_LOBLOAD:
      return "lobload";
    
    case ITM_AGGR_GROUPING_FUNC:
      return "aggr_grouping";

    case ITM_TO_TIMESTAMP:
      return "to_timestamp";

    case ITM_SPLIT_PART:
      return "split_part";

    default:
      return "unknown func";
    } // switch
} // BuiltinFunction::getText()

//## Yuk -- embedded English text -- this is not per I18N standards!
const NAString BuiltinFunction::getTextForError() const
{
  switch (getOperatorType())
    {
    case ITM_CHAR_LENGTH:
      return "CHARACTER_LENGTH, CHAR_LENGTH, or LENGTH";

    case ITM_LOWER:
      return "LOWER or LCASE";

    case ITM_POSITION:
      return "POSITION or LOCATE";

    case ITM_TRIM:
    case ITM_TRIM_DOUBLEBYTE:
      return "TRIM, LTRIM, or RTRIM";

    case ITM_UPPER:
      return "UPPER, UPSHIFT, or UCASE";

    default: return getTextUpper();
    } // switch
} // BuiltinFunction::getTextForError()

ItemExpr * BuiltinFunction::copyTopNode(ItemExpr * derivedNode,
					CollHeap* outHeap)
{
  ItemExpr *result = NULL;
  if (derivedNode == NULL)
    {
      switch (getOperatorType())
	{
	case ITM_NULLIFZERO:
        case ITM_ISIPV4:
        case ITM_ISIPV6:
        case ITM_MD5:
        case ITM_CRC32:
	case ITM_SOUNDEX:
        case ITM_REVERSE:
	  {
	    result = new (outHeap) BuiltinFunction(getOperatorType(),
						   outHeap, 1, child(0));
	  }
	break;

	case ITM_NVL:
	case ITM_QUERYID_EXTRACT:
	case ITM_TOKENSTR:
	  {
	    result = new (outHeap) BuiltinFunction(getOperatorType(),
						   outHeap, 2, child(0), child(1));
	  }
	break;
    case ITM_JSONOBJECTFIELDTEXT:
	{
	    result = new (outHeap) BuiltinFunction(getOperatorType(),
						   outHeap, 2, child(0), child(1));
	}
	break;
	default:
	  {
	    ABORT("copyTopNode() can only be called for a derived class of BuiltinFunction");
	  }
	break;
	}
    }
  else
    result = derivedNode;

  return Function::copyTopNode(result, outHeap);
}

ItemExpr * HashCommon::copyTopNode(ItemExpr * derivedNode,
				   CollHeap* outHeap)
{
  ItemExpr *result = NULL;

  if (derivedNode == NULL)
    ABORT("copyTopNode() can only be called for a derived class of Function");
  else
    result = derivedNode;

  return BuiltinFunction::copyTopNode(result, outHeap);
}

//++Triggers, 

// -----------------------------------------------------------------------
// member functions for class EvaluateOnceBuiltinFunction
// -----------------------------------------------------------------------


EvaluateOnceBuiltinFunction::~EvaluateOnceBuiltinFunction() {}

NABoolean EvaluateOnceBuiltinFunction::isAUserSuppliedInput() const    { return TRUE; }

NABoolean EvaluateOnceBuiltinFunction::isCovered(const ValueIdSet& newExternalInputs,
                               const GroupAttributes& newRelExprAnchorGA,
                               ValueIdSet& referencedInputs,
                               ValueIdSet& coveredSubExpr,
                               ValueIdSet& unCoveredExpr) const
{
	return FALSE;
}

//--Triggers, 

// -----------------------------------------------------------------------
// member functions for builtin functions
// -----------------------------------------------------------------------
Between::~Between()
{
  // NOTE: never destroy pDirectionVector_.
  // this is a pointer passed on to other objects as is.
  // if it is destroyed this may affect other items.

}

Concat::~Concat() {}

Case::~Case() {}

IfThenElse::~IfThenElse() {}

InstantiateNull::~InstantiateNull() {}

Hash::~Hash() {}

ReplaceNull::~ReplaceNull() {}

// -----------------------------------------------------------------------
// member functions for BoolVal
// -----------------------------------------------------------------------
BoolVal::~BoolVal() {}

NABoolean BoolVal::isCovered
                      (const ValueIdSet& newExternalInputs,
		       const GroupAttributes& coveringGA,
		       ValueIdSet& referencedInputs,
		       ValueIdSet& coveredSubExpr,
		       ValueIdSet& unCoveredExpr ) const
{
  // A BoolVal that returns a TRUE/FALSE/NULL unconditionally, i.e.,
  // its evaluation does not depend upon the boolean outcome of its
  // child subtree, is like a constant. It is always covered.
  if (getNumChildren() == 0)
    return TRUE;
  else
    // BoolVal is Covered if its operand is covered
    return coveringGA.covers(((ItemExpr *)child(0))->getValueId(),
			     newExternalInputs, referencedInputs,
			     &coveredSubExpr, &unCoveredExpr);
} // BoolVal::isCovered()

// -----------------------------------------------------------------------
// member functions for InverseOrder
// -----------------------------------------------------------------------
InverseOrder::~InverseOrder() {}

ItemExpr * InverseOrder::simplifyOrderExpr(OrderComparison *newOrder)
{
  OrderComparison resultOrder;
  ItemExpr *result = child(0)->simplifyOrderExpr(&resultOrder);

  // reverse the order of the simplified child
  if (resultOrder == SAME_ORDER)
    resultOrder = INVERSE_ORDER;
  else
    resultOrder = SAME_ORDER;

  if (newOrder)
    *newOrder = resultOrder;
  return result;
}

ItemExpr * InverseOrder::removeInverseOrder()
{
  return child(0);
}

// -----------------------------------------------------------------------
// member functions for PatternMatchingFunction.
// -----------------------------------------------------------------------
PatternMatchingFunction::~PatternMatchingFunction() {}

// -----------------------------------------------------------------------
// member functions for Like
// -----------------------------------------------------------------------
Like::~Like() {}

Regexp::~Regexp() {}


ItemExpr * Regexp::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  ItemExpr *result = NULL;

  if (derivedNode == NULL)
    {
      result = new (outHeap) Regexp(NULL, NULL,
	    numberOfNonWildcardChars_,
	    bytesInNonWildcardChars_,
	    patternAStringLiteral_,
	    oldDefaultSelForLikeWildCardUsed_,
	    beginEndKeysApplied_);
    }
  else
    result = derivedNode;

  return BuiltinFunction::copyTopNode(result, outHeap);

} // Regexp::copyTopNode()

ItemExpr * Like::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  ItemExpr *result = NULL;

  if (derivedNode == NULL)
    {
      switch (getArity())
	{
	case 2:
	  result = new (outHeap) Like(child(0), child(1),
	    numberOfNonWildcardChars_,
	    bytesInNonWildcardChars_,
	    patternAStringLiteral_,
	    oldDefaultSelForLikeWildCardUsed_,
	    beginEndKeysApplied_);
	  break;
	case 3:
	  result = new (outHeap) Like(child(0), child(1), child(2),
	    numberOfNonWildcardChars_,
	    bytesInNonWildcardChars_,
	    patternAStringLiteral_,
	    oldDefaultSelForLikeWildCardUsed_,
	    beginEndKeysApplied_);
	  break;
	default:
	  CMPASSERT(0 == 1);
	  break;
	}
    }
  else
    result = derivedNode;

  return BuiltinFunction::copyTopNode(result, outHeap);

} // Like::copyTopNode()

double PatternMatchingFunction::defaultSel()
{
  // if begin and end keys have been applied to this expression, then this means
  // that the original LIKE predicate was something like a%b. This was transformed
  // to >=a and < b and like %b. Here we would have already applied selectivity
  // to the first range predicate. We do not want to apply selectivity to the other
  // portions of the predicate. Hence return 1.0 for the last portion of the
  // predicate

  if ( beginEndKeysApplied( CmpCommon::statementHeap() ) )
     return 1.0;

  if (oldDefaultSelForLikeWildCardUsed_)
  {
    return ActiveSchemaDB()->getDefaults().getAsDouble(HIST_DEFAULT_SEL_FOR_LIKE_WILDCARD);
  }

  // For all other cases compute selectivity based on the number of non-wildcard
  // characters
  return computeSelForNonWildcardChars(); ;
}

void PatternMatchingFunction::setNumberOfNonWildcardChars(const LikePatternString &pattern)
{
  Int32 count = 0;
  Int32 byteCnt = 0;
  CharInfo::CharSet  cs = pattern.getPatternCharSet();

  LikePatternStringIterator i(pattern);

  while (i != LikePatternStringIterator::END_OF_PATTERN)
  {
    const char *currentChar = i.getCurrentChar();
    UInt16 number_bytes = Attributes::getFirstCharLength(currentChar, 8, cs);

    if (i == LikePatternStringIterator::NON_WILDCARD)
    {
        count++;
        byteCnt += number_bytes;
    }

    i += number_bytes + ((cs == CharInfo::UCS2) ? 1 : 0); // For UCS2, number_bytes is always 1
    i.determineCharType();
  }
  numberOfNonWildcardChars_ = count;
  bytesInNonWildcardChars_  = byteCnt ;
}

double PatternMatchingFunction::computeSelForNonWildcardChars()
{

  // get the default selectivity for like predicate
  double defaultSelectivity = CURRSTMT_OPTDEFAULTS->defSelForWildCard();

  // get the number of non_wildcard characters after the first wildcard char
  Int32 cnt = getNoOfNonWildcardChars();

  // Retuen default selectivity for the following cases:
  // 1. For some special cases, example when there is a dynamic parameter in the
  //    LIKE predicate, the LIKE expression is not optimized. In all such cases
  //    cnt is less than 0. For these, return the default selectivity
  // 2. if there are no non_wildcard characters in the like clause, then if the column
  //    is not nullable, we have already transformed the predicate to TRUE.
  //    For a nullable column, we apply default selectivity.
  // 3. If there is only one non_wildcard character, we go by the selectivity
  //    defined by HIST_DEFAULT_BASE_SEL_FOR_LIKE_WILDCARD,
  // 4. HIST_DEFAULT_SEL_FOR_LIKE_NO_WILDCARD is nearing 0 (e-16). We use default
  //    selectivity in that case.

  double reductionFactor = CURRSTMT_OPTDEFAULTS->defSelForNoWildCard();

  if ( (cnt <= 1) OR
       (reductionFactor <= MIN_SELECTIVITY) )
    return defaultSelectivity;

  // We compute selectivity as: if number of non-wild characters is 1, selectivity
  // is equal to default selectivity (which is 1/10 right now. If the number of
  // non-wild characters is 2, selectivity is 1/100. For number of non-wild characters
  // 3 or more, it is 1/1000. Multiplication factor each non-wildcard character is
  // defined by the CQD HIST_DEFAULT_SEL_FOR_LIKE_NO_WILDCARD

  Int32 nonWildCardChar = ((cnt > 4) ? 4 : cnt);

  defaultSelectivity = defaultSelectivity * pow(defaultSelectivity / reductionFactor, nonWildCardChar - 1);

  // Bind the selectivity between MIN_SELECTIVITY and 1.0

  if (defaultSelectivity < MIN_SELECTIVITY)
    return MIN_SELECTIVITY;
  if (defaultSelectivity > 1.0)
    return 1.0;
  return defaultSelectivity;
}

NABoolean PatternMatchingFunction::hasEquivalentProperties(ItemExpr * other)
{
  if (other == NULL)
    return FALSE;
  if (getOperatorType() != other->getOperatorType() || 
        getArity() != other->getArity())
    return FALSE;

  Like * tmp = (Like *) other;

  return 
      (this->numberOfNonWildcardChars_  == tmp->numberOfNonWildcardChars_) &&
      (this->bytesInNonWildcardChars_  == tmp->bytesInNonWildcardChars_) &&
      (this->patternAStringLiteral_ == tmp->patternAStringLiteral_ ) &&
      (this->oldDefaultSelForLikeWildCardUsed_ == tmp->oldDefaultSelForLikeWildCardUsed_) && 
      (this->beginEndKeysApplied_ == tmp->beginEndKeysApplied_ );

}

void PatternMatchingFunction::unparse(NAString &result,
		   PhaseEnum phase,
		   UnparseFormatEnum form,
		   TableDesc* tabId) const
{
  if (getArity() == 2)
    return CacheableBuiltinFunction::unparse(result, phase, form, tabId);
  else
  {
    result += "(";
    child(0)->unparse(result, phase, form, tabId);
    result += " like ";

    child(1)->unparse(result, phase, form, tabId);
    result += " escape ";

    child(2)->unparse(result, phase, form, tabId);
    result += ")";
  }                                               
}                                                 
                                                  

// -----------------------------------------------------------------------
// member functions for class ConvertHex
// -----------------------------------------------------------------------
ConvertHex::~ConvertHex() {}

ItemExpr * ConvertHex::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL)
    result = new (outHeap) ConvertHex(getOperatorType(), child(0));
  else
    result = derivedNode;

  return BuiltinFunction::copyTopNode(result, outHeap);

} // ConvertHex::copyTopNode()

// -----------------------------------------------------------------------
// member functions for class CharLength
// -----------------------------------------------------------------------
CharLength::~CharLength() {}

ItemExpr * CharLength::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL)
    result = new (outHeap) CharLength(child(0));
  else
    result = derivedNode;

  return BuiltinFunction::copyTopNode(result, outHeap);

} // CharLength::copyTopNode()

// -----------------------------------------------------------------------
// member functions for class OctetLength
// -----------------------------------------------------------------------
OctetLength::~OctetLength() {}

ItemExpr * OctetLength::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL)
    result = new (outHeap) OctetLength(child(0));
  else
    result = derivedNode;

  return BuiltinFunction::copyTopNode(result, outHeap);

} // OctetLength::copyTopNode()

// -----------------------------------------------------------------------
// member functions for class PositionFunc
// -----------------------------------------------------------------------
PositionFunc::~PositionFunc() {}

ItemExpr * PositionFunc::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL)
    result = new (outHeap) PositionFunc(child(0), child(1), child(2), child(3));
  else
    result = derivedNode;

  ((PositionFunc*)result)->collation_ = collation_;

  return BuiltinFunction::copyTopNode(result, outHeap);

} // PositionFunc::copyTopNode()

// -----------------------------------------------------------------------
// member functions for Substring
// -----------------------------------------------------------------------
Substring::~Substring() {}

ItemExpr * Substring::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  ItemExpr *result = NULL;

  if (derivedNode == NULL)
    {
      switch (getArity())
	{
	case 2:
	  result = new (outHeap) Substring(child(0), child(1));
	  break;
	case 3:
	  result = new (outHeap) Substring(child(0), child(1), child(2));
	  break;
	default:
	  CMPASSERT(0 == 1);
	  break;
	}
    }
  else
    result = derivedNode;

  return BuiltinFunction::copyTopNode(result, outHeap);

} // Substring::copyTopNode()

// -----------------------------------------------------------------------
// member functions for class ConvertTimestamp
// -----------------------------------------------------------------------
ConvertTimestamp::~ConvertTimestamp() {}

ItemExpr * ConvertTimestamp::copyTopNode(ItemExpr *derivedNode,
					 CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL)
    result = new (outHeap) ConvertTimestamp(child(0));
  else
    result = derivedNode;

  return BuiltinFunction::copyTopNode(result,outHeap);

} // ConvertTimestamp::copyTopNode()

SleepFunction::~SleepFunction() {}
ItemExpr * SleepFunction::copyTopNode(ItemExpr *derivedNode,
					 CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL)
    result = new (outHeap) SleepFunction(child(0));
  else
    result = derivedNode;

  return BuiltinFunction::copyTopNode(result,outHeap);

} // SleepFunction::copyTopNode()
NABoolean SleepFunction::isAUserSuppliedInput() const    { return TRUE; }

UnixTimestamp::~UnixTimestamp() {}

ItemExpr * UnixTimestamp::copyTopNode(ItemExpr *derivedNode,
					 CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL)
    result = new (outHeap) UnixTimestamp();
  else
    result = derivedNode;

  return BuiltinFunction::copyTopNode(result,outHeap);

} // UnixTimestamp::copyTopNode()

NABoolean UnixTimestamp::isAUserSuppliedInput() const    { return TRUE; }

// -----------------------------------------------------------------------
// member functions for class CurrentTimestamp
// -----------------------------------------------------------------------
CurrentTimestamp::~CurrentTimestamp() {}

ItemExpr * CurrentTimestamp::copyTopNode(ItemExpr *derivedNode,
					 CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL)
    result = new (outHeap) CurrentTimestamp(dtCode_, fractPrec_);
  else
    result = derivedNode;

  return BuiltinFunction::copyTopNode(result,outHeap);

} // CurrentTimestamp::copyTopNode()

NABoolean CurrentTimestamp::isAUserSuppliedInput() const    { return TRUE; }

ItemExpr * CurrentTimestamp::construct
(CollHeap * heap, 
 DatetimeType::Subtype dtCode ,
 Lng32 fractPrec)
{
  ItemExpr * ie = new(heap) CurrentTimestamp(dtCode, fractPrec);

  if ((fractPrec != SQLTimestamp::DEFAULT_FRACTION_PRECISION) ||
      (dtCode != DatetimeType::SUBTYPE_SQLTimestamp))
    {
      if (dtCode == DatetimeType::SUBTYPE_SQLDate)
        ie = new (heap)
          Cast(ie, new (heap) SQLDate(heap, FALSE));
      else if (dtCode == DatetimeType::SUBTYPE_SQLTime)
        ie = new (heap)
          Cast(ie, new (heap) SQLTime(heap, FALSE, fractPrec));
      else
        ie = new (heap)
          Cast(ie, new (heap) SQLTimestamp(heap, FALSE, fractPrec));
    }

  return ie;
}

// -----------------------------------------------------------------------
// member functions for class CurrentTimestampRunning
// -----------------------------------------------------------------------
CurrentTimestampRunning::~CurrentTimestampRunning() {}

ItemExpr * CurrentTimestampRunning::copyTopNode(ItemExpr *derivedNode,
						CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL)
    result = new (outHeap) CurrentTimestampRunning();
  else
    result = derivedNode;

  return BuiltinFunction::copyTopNode(result,outHeap);

} // CurrentTimestampRunning::copyTopNode()

// -----------------------------------------------------------------------
// member functions for class DateFormat
// -----------------------------------------------------------------------
DateFormat::~DateFormat() {}

ItemExpr * DateFormat::copyTopNode(ItemExpr *derivedNode,
				   CollHeap* outHeap)
{
  DateFormat *result;

  if (derivedNode == NULL)
    result = new (outHeap) DateFormat(child(0), 
                                      formatStr_, formatType_, 
                                      wasDateformat_);
  else
    result = (DateFormat*)derivedNode;

  result->frmt_ = frmt_;
  result->dateFormat_ = dateFormat_;

  return BuiltinFunction::copyTopNode(result,outHeap);

} // DateFormat::copyTopNode()

NABoolean DateFormat::hasEquivalentProperties(ItemExpr * other)
{
  if (other == NULL)
    return FALSE;
  if (getOperatorType() != other->getOperatorType() || 
        getArity() != other->getArity())
    return FALSE;

  DateFormat * df = (DateFormat *) other;

  return 
      (this->dateFormat_ == df->dateFormat_);
}

void DateFormat::unparse(NAString &result,
		      PhaseEnum phase,
                      UnparseFormatEnum form,
		      TableDesc * tabId) const
{
  if (wasDateformat_)
    result += "DATEFORMAT(";
  else if (formatType_ == FORMAT_TO_DATE)
    result += "TO_DATE(";
  else if (formatType_ == FORMAT_TO_CHAR)
    result += "TO_CHAR(";
  else
    result += "unknown(";

  child(0)->unparse(result, phase, form, tabId);

  result += ", ";

  if (wasDateformat_)
    {
      if (frmt_ == ExpDatetime::DATETIME_FORMAT_DEFAULT)
        result += "DEFAULT";
      else if (frmt_ == ExpDatetime::DATETIME_FORMAT_USA)
        result += "USA";
      else if (frmt_ == ExpDatetime::DATETIME_FORMAT_EUROPEAN)
        result += "EUROPEAN";
      else
        result += "unknown";
    }
  else
    {
      result += "'";
      result += formatStr_;
      result += "'";
    }

  result += ")";  
}

// -----------------------------------------------------------------------
// member functions for class DayOfWeek
// -----------------------------------------------------------------------
DayOfWeek::~DayOfWeek() {}

ItemExpr * DayOfWeek::copyTopNode(ItemExpr *derivedNode,
				  CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL)
    result = new (outHeap) DayOfWeek(child(0));
  else
    result = derivedNode;

  return BuiltinFunction::copyTopNode(result,outHeap);

} // DayOfWeek::copyTopNode()

// -----------------------------------------------------------------------
// member functions for class ExplodeVarchar
// -----------------------------------------------------------------------
ExplodeVarchar::~ExplodeVarchar() {}

ItemExpr * ExplodeVarchar::copyTopNode(ItemExpr *derivedNode,
				       CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL)
    result = new (outHeap) ExplodeVarchar(child(0), type_, forInsert_);
  else
    result = derivedNode;

  return BuiltinFunction::copyTopNode(result,outHeap);

} // ExplodeVarchar::copyTopNode()

// -----------------------------------------------------------------------
// member functions for class Extract
// -----------------------------------------------------------------------
Extract::~Extract() {}

NABoolean Extract::duplicateMatch(const ItemExpr & other) const
{
  if (NOT genericDuplicateMatch(other))
    return FALSE;

  Extract &o = (Extract &) other;

  // compare any local data members of the derived class
  // and return FALSE if they don't match
  if (extractField_ != o.extractField_)
    return FALSE;

  return TRUE;
}

ItemExpr * Extract::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL)
    result = new (outHeap) Extract(getExtractField(), child(0), getFieldFunction());
  else
    result = derivedNode;

  return BuiltinFunction::copyTopNode(result, outHeap);

} // Extract::copyTopNode()

ItemExpr * ExtractOdbc::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL)
    result = new (outHeap) ExtractOdbc(getExtractField(), child(0), getFieldFunction());
  else
    result = derivedNode;

  return BuiltinFunction::copyTopNode(result, outHeap);

} // Extract::copyTopNode()

NABoolean Extract::isAUserSuppliedInput() const             
{ 
   ItemExpr * extractChild = NULL;
   if ( child(0) && (child(0)->getOperatorType() == ITM_CAST) && 
	child(0)->child(0) )
      extractChild = child(0)->child(0)->castToItemExpr();
   else if (child(0))
	extractChild = child(0)->castToItemExpr();

   if ((CmpCommon::getDefault(COMP_BOOL_185) == DF_ON) &&
       (extractChild && extractChild->isAUserSuppliedInput()) &&
       (NOT(extractChild->doesExprEvaluateToConstant(FALSE))))
      return TRUE; 
   else
      return FALSE;
} // Extract::isAUserSuppliedInput() 

// ----------------------------------------------------------------------
// 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 it is expressions of the type
// extract(cast(timestamp))
// ----------------------------------------------------------------------
void Extract::getLeafValuesForCoverTest(ValueIdSet & leafValues, 
                                        const GroupAttributes& coveringGA,
                                        const ValueIdSet & newExternalInputs) const
{ 
  if (isAUserSuppliedInput())
    leafValues += getValueId();
  else
    BuiltinFunction::getLeafValuesForCoverTest(leafValues, coveringGA, newExternalInputs);
}


NABoolean Extract::hasEquivalentProperties(ItemExpr * other)
{
  if (other == NULL)
    return FALSE;
  if (getOperatorType() != other->getOperatorType() || 
        getArity() != other->getArity())
    return FALSE;

  Extract * tmp = (Extract *) other;

  return 
    (this->extractField_ == tmp->extractField_ ) &&
      (this->fieldFunction_ == tmp->fieldFunction_);
}

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

// -----------------------------------------------------------------------
// member functions for class JulianTimestamp
// -----------------------------------------------------------------------
JulianTimestamp::~JulianTimestamp() {}

ItemExpr * JulianTimestamp::copyTopNode(ItemExpr *derivedNode,
					CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL)
    result = new (outHeap) JulianTimestamp(child(0));
  else
    result = derivedNode;

  return BuiltinFunction::copyTopNode(result,outHeap);

} // JulianTimestamp::copyTopNode()

// Fix for cr 10-010718-3967
// We dont need this method, the reason this method was added was to return
// true, the ItemExpr method already returns false, so we don't need this
// method. So basically we want FALSE to be returned for JulianTimestamp all
// the time.
// NABoolean JulianTimestamp::isAUserSuppliedInput() const      { return TRUE; }

// -----------------------------------------------------------------------
// member functions for class StatementExecutionCount
// -----------------------------------------------------------------------

NABoolean StatementExecutionCount::isAUserSuppliedInput() const { return TRUE; }

ItemExpr * StatementExecutionCount::copyTopNode(ItemExpr *derivedNode,
						CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL)
    result = new (outHeap) StatementExecutionCount();
  else
    result = derivedNode;

  return BuiltinFunction::copyTopNode(result,outHeap);
}

// -----------------------------------------------------------------------
// member functions for class CurrentTransId
// -----------------------------------------------------------------------

NABoolean CurrentTransId::isAUserSuppliedInput() const { return TRUE; }

ItemExpr * CurrentTransId::copyTopNode(ItemExpr *derivedNode,
				       CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL)
    result = new (outHeap) CurrentTransId();
  else
    result = derivedNode;

  return BuiltinFunction::copyTopNode(result,outHeap);
}

// -----------------------------------------------------------------------
// member functions for class Upper
// -----------------------------------------------------------------------
Upper::~Upper() {}

ItemExpr * Upper::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL)
    result = new (outHeap) Upper(child(0));
  else
    result = derivedNode;

  return BuiltinFunction::copyTopNode(result, outHeap);

} // Upper::copyTopNode()

// -----------------------------------------------------------------------
// member functions for class Lower
// -----------------------------------------------------------------------
Lower::~Lower() {}

ItemExpr * Lower::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL)
    result = new (outHeap) Lower(child(0));
  else
    result = derivedNode;

  return BuiltinFunction::copyTopNode(result, outHeap);

} // Lower::copyTopNode()

// -----------------------------------------------------------------------
// member functions for class Trim
// -----------------------------------------------------------------------
Trim::~Trim() {}

ItemExpr * Trim::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL)
    result = new (outHeap) Trim(getTrimMode(), child(0), child(1));
  else
    result = derivedNode;

  return BuiltinFunction::copyTopNode(result, outHeap);

} // Trim::copyTopNode()

NABoolean Trim::hasEquivalentProperties(ItemExpr * other)
{
  if (other == NULL)
    return FALSE;
  if (getOperatorType() != other->getOperatorType() || 
        getArity() != other->getArity())
    return FALSE;

  Trim * t = (Trim *) other;

  return 
    (mode_ == t->mode_);
}
// -----------------------------------------------------------------------
// member functions for class Increment
// -----------------------------------------------------------------------
Increment::~Increment() {}

ItemExpr * Increment::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL)
    result = new (outHeap) Increment(child(0));
  else
    result = derivedNode;

  return BuiltinFunction::copyTopNode(result, outHeap);

} // Increment::copyTopNode()

// -----------------------------------------------------------------------
// member functions for class Decrement
// -----------------------------------------------------------------------
Decrement::~Decrement() {}

ItemExpr * Decrement::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL)
    result = new (outHeap) Decrement(child(0));
  else
    result = derivedNode;

  return BuiltinFunction::copyTopNode(result, outHeap);

} // Decrement::copyTopNode()

// -----------------------------------------------------------------------
// member functions for class TriRelational
// -----------------------------------------------------------------------

TriRelational::TriRelational(OperatorTypeEnum optype,
			     ItemExpr *val1Ptr,
			     ItemExpr *val2Ptr,
			     ItemExpr *val3Ptr)
     : BuiltinFunction(optype, CmpCommon::statementHeap(),
                       3, val1Ptr, val2Ptr, val3Ptr)
{
  CMPASSERT(optype == ITM_LESS_OR_LE OR
	 optype == ITM_GREATER_OR_GE);
}

TriRelational::~TriRelational() {}

ItemExpr * TriRelational::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL)
    result = new (outHeap) TriRelational(getOperatorType(),NULL,NULL,NULL);
  else
    result = derivedNode;

  return BuiltinFunction::copyTopNode(result, outHeap);
}

// -----------------------------------------------------------------------
// member functions for ScalarVariance
// -----------------------------------------------------------------------
ScalarVariance::~ScalarVariance() {}

ItemExpr *
ScalarVariance::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL)
    {
      CMPASSERT(getArity() == 3);
      result = new (outHeap)
	ScalarVariance(getOperatorType(), child(0), child(1), child(2));
    }
  else
    result = derivedNode;

  return BuiltinFunction::copyTopNode(result, outHeap);

} // ScalarVariance::copyTopNode()


// -----------------------------------------------------------------------
// member functions for UnPackCol
// -----------------------------------------------------------------------
//
UnPackCol::~UnPackCol() {}

ItemExpr *
UnPackCol::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL)
    {
      CMPASSERT(getArity() == 2);
      result = new (outHeap)
	UnPackCol(child(0),
		  child(1),
		  width_,
		  base_,
		  nullsPresent_,
		  type_->newCopy(outHeap));
    }
  else
    result = derivedNode;

  return BuiltinFunction::copyTopNode(result, outHeap);

} // UnPackCol::copyTopNode()

NABoolean UnPackCol::isCovered(const ValueIdSet& newExternalInputs,
                               const GroupAttributes& newRelExprAnchorGA,
                               ValueIdSet& referencedInputs,
                               ValueIdSet& coveredSubExpr,
                               ValueIdSet& unCoveredExpr) const
{
  // ---------------------------------------------------------------------
  // If the operand is covered, then return its ValueId in coveredSubExpr.
  // ---------------------------------------------------------------------
  ValueIdSet localSubExpr;
  for(Lng32 i = 0; i < (Lng32)getArity(); i++)
  {
    if(newRelExprAnchorGA.covers(child(i)->getValueId(),
                                 newExternalInputs,
                                 referencedInputs,
                                 &localSubExpr))
    {
      coveredSubExpr += child(i)->getValueId();
    }
  }

  // ---------------------------------------------------------------------
  // The UnPackCol function is coerced to fail the coverage test even when
  // its operands isCovered(). This is because only the UnPackCol node can
  // evaluate the function. The function is associated with a UnPackCol
  // node at the very beginning and we don't allow it to be pushed down
  // even if the function's operands are covered at the node's child.
  // ---------------------------------------------------------------------
  return FALSE;
}

void UnPackCol::getLeafValuesForCoverTest(ValueIdSet& leafValues, 
                                          const GroupAttributes& coveringGA,
                                          const ValueIdSet & newExternalInputs) const
{
  // UnPackCol is considered a leaf operator for cover test.
  leafValues += getValueId();
}

// -----------------------------------------------------------------------
// member functions for RowsetArrayScan
// -----------------------------------------------------------------------
//
RowsetArrayScan::~RowsetArrayScan() {}

ItemExpr *
RowsetArrayScan::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL) {
    CMPASSERT(getArity() == 2);
    result = new (outHeap)
      RowsetArrayScan(child(0),
                      child(1),
                      maxNumElem_,
                      elemSize_,
                      elemNullInd_,
                      elemType_->newCopy(outHeap),
                      getOperatorType());
  }
  else
    result = derivedNode;

  return BuiltinFunction::copyTopNode(result, outHeap);

}

NABoolean RowsetArrayScan::isCovered(const ValueIdSet& newExternalInputs,
                                     const GroupAttributes& newRelExprAnchorGA,
                                     ValueIdSet& referencedInputs,
                                     ValueIdSet& coveredSubExpr,
                                     ValueIdSet& unCoveredExpr) const
{
  // ---------------------------------------------------------------------
  // If the operand is covered, then return its ValueId in coveredSubExpr.
  // ---------------------------------------------------------------------
  ValueIdSet localSubExpr;
  for (Lng32 i = 0; i < (Lng32)getArity(); i++) {
    if (newRelExprAnchorGA.covers(child(i)->getValueId(),
                                  newExternalInputs,
                                  referencedInputs,
                                  &localSubExpr)) {
      coveredSubExpr += child(i)->getValueId();
    }

    coveredSubExpr += localSubExpr;

  }

  // ---------------------------------------------------------------------
  // The RowsetArrayScan function is coerced to fail the coverage test even
  // when its operands isCovered(). This is because only the RowsetArrayScan
  // node can evaluate the function. The function is associated with a
  // RowsetArrayScan node at the very beginning and we don't allow it to be
  // pushed down even if the function's operands are covered at the node's
  // child.
  // ---------------------------------------------------------------------
  return FALSE;
}

void RowsetArrayScan::getLeafValuesForCoverTest(ValueIdSet& leafValues, 
                                                const GroupAttributes& coveringGA,
                                                const ValueIdSet & newExternalInputs) const
{
  // RowsetArrayScan is considered a leaf operator for cover test.
  leafValues += getValueId();
}

// -----------------------------------------------------------------------
// member functions for RowsetArrayInto
// -----------------------------------------------------------------------
//
RowsetArrayInto::~RowsetArrayInto() {}

ItemExpr *
RowsetArrayInto::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL) {
    CMPASSERT(getArity() == 2);
    result = new (outHeap)
      RowsetArrayInto(child(0),
                      child(1),
                      maxNumElem_,
                      elemSize_,
                      elemNullInd_,
                      hostVarType_->newCopy(outHeap),
                      getOperatorType());
  }
  else
    result = derivedNode;

  return BuiltinFunction::copyTopNode(result, outHeap);
}

NABoolean RowsetArrayInto::isCovered(const ValueIdSet& newExternalInputs,
                                     const GroupAttributes& newRelExprAnchorGA,
                                     ValueIdSet& referencedInputs,
                                     ValueIdSet& coveredSubExpr,
                                     ValueIdSet& unCoveredExpr) const
{
  // ---------------------------------------------------------------------
  // If the operand is covered, then return its ValueId in coveredSubExpr.
  // ---------------------------------------------------------------------
  ValueIdSet localSubExpr;
  for (Lng32 i = 0; i < (Lng32)getArity(); i++) {
    if (newRelExprAnchorGA.covers(child(i)->getValueId(),
                                  newExternalInputs,
                                  referencedInputs,
                                  &localSubExpr)) {
      coveredSubExpr += child(i)->getValueId();
    }
    coveredSubExpr += localSubExpr;
  }

  // ---------------------------------------------------------------------
  // The RowsetArrayInto function is coerced to fail the coverage test even
  // when its operands isCovered(). This is because only the RowsetArrayInto
  // node can evaluate the function. The function is associated with a
  // RowsetArrayInto node at the very beginning and we don't allow it to be
  // pushed down even if the function's operands are covered at the node's
  // child.
  // ---------------------------------------------------------------------
  return FALSE;
}

void RowsetArrayInto::getLeafValuesForCoverTest(ValueIdSet& leafValues, 
                                                const GroupAttributes& coveringGA,
                                                const ValueIdSet & newExternalInputs) const
{
  // RowsetArrayScan is considered a leaf operator for cover test.
  leafValues += getValueId();
}

// -----------------------------------------------------------------------
// member functions for class RangeLookup
// -----------------------------------------------------------------------

RangeLookup::RangeLookup(ItemExpr *val1Ptr,
			 const RangePartitioningFunction *partFunc) :
     BuiltinFunction(ITM_RANGE_LOOKUP, CmpCommon::statementHeap(), 1, val1Ptr),
     partFunc_(partFunc)
{
}

RangeLookup::~RangeLookup() {}

ItemExpr * RangeLookup::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL)
    result = new (outHeap) RangeLookup(NULL,partFunc_);
  else
    result = derivedNode;

  return BuiltinFunction::copyTopNode(result, outHeap);
}

Lng32 RangeLookup::splitKeysLen()
{
  // we assume a dense array of character strings, with #parts + 1 entries
  // (no NULL terminators, no fillers)
  return (partFunc_->getCountOfPartitions() + 1) *
    partFunc_->getRangePartitionBoundaries()->getEncodedBoundaryKeyLength();
}

void RangeLookup::copySplitKeys(char *tgt, Lng32 tgtLen)
{
  CMPASSERT(tgtLen = splitKeysLen());
  const RangePartitionBoundaries * b =
    partFunc_->getRangePartitionBoundaries();
  Lng32 numEntries = partFunc_->getCountOfPartitions() + 1;
  Lng32 entryLen   = b->getEncodedBoundaryKeyLength();
  Lng32 offset     = 0;

  for (Lng32 i = 0; i < numEntries; i++)
    {
      str_cpy_all(&tgt[offset],
		  b->getBinaryBoundaryValue(i),
		  entryLen);
      offset += entryLen;
    }
}

Lng32 RangeLookup::getNumOfPartitions()
{
  return partFunc_->getCountOfPartitions();
}

Lng32 RangeLookup::getEncodedBoundaryKeyLength()
{
  return partFunc_->getRangePartitionBoundaries()->
    getEncodedBoundaryKeyLength();
}

// -----------------------------------------------------------------------
// member functions for class PackFunc
// -----------------------------------------------------------------------

PackFunc::PackFunc(ItemExpr* val1Ptr,
                   ItemExpr* pf,
                   Lng32 base,
                   Lng32 width,
                   NABoolean nullsPresent)
 : BuiltinFunction(ITM_PACK_FUNC,
                   CmpCommon::statementHeap(),
                   2,val1Ptr,pf),
   isFormatInfoValid_(TRUE),
   base_(base),
   width_(width),
   nullsPresent_(nullsPresent),
   type_(NULL)
{
  deriveTypeFromFormatInfo();
}

PackFunc::PackFunc(ItemExpr* val1Ptr,
                  ItemExpr* pf,
                  const NAType* unpackType)
 : BuiltinFunction(ITM_PACK_FUNC,
                   CmpCommon::statementHeap(),
                   2,val1Ptr,pf),
   isFormatInfoValid_(FALSE)
{
  deriveFormatInfoFromUnpackType(unpackType);
}

void PackFunc::deriveTypeFromFormatInfo()
{
  CMPASSERT(isFormatInfoValid_);

  // The packing factor must be stored as a constant.
  NABoolean negateIt;
  ConstValue* pfconst = child(1)->castToConstValue(negateIt);
  CMPASSERT(pfconst AND negateIt == FALSE);

  // The packing factor must be stored as a long in the constant.
  CMPASSERT(pfconst->getStorageSize() == sizeof(Lng32));
  CMPASSERT(pfconst->getType()->getTypeQualifier() == NA_NUMERIC_TYPE);
  Lng32 pf;
  memcpy(&pf,pfconst->getConstValue(),sizeof(Lng32));

  Lng32 dataSizeInBytes = (width_ < 0 ? (-width_-1)/8+1 : width_);
  Lng32 packedRowSizeInBytes = (base_ + dataSizeInBytes);
  type_ = new(CmpCommon::statementHeap()) SQLChar(CmpCommon::statementHeap(), packedRowSizeInBytes,FALSE);
}

void PackFunc::deriveFormatInfoFromUnpackType(const NAType* unpackType)
{
  CMPASSERT(unpackType);

  // Packing of varying length column not (yet?) supported.
  // It should have been enforced when the packed table is created.
  CMPASSERT(NOT DFS2REC::isAnyVarChar(unpackType->getFSDatatype()));

  // Save four byte for the packing factor to be stored.
  Lng32 pfSizeInBytes = sizeof(Int32);

  // The packing factor must be stored as a constant.
  NABoolean negateIt;
  ConstValue* pfconst = child(1)->castToConstValue(negateIt);
  CMPASSERT(pfconst AND negateIt == FALSE);

  // The packing factor must be stored as a long in the constant.
  CMPASSERT(pfconst->getStorageSize() == sizeof(Lng32));
  CMPASSERT(pfconst->getType()->getTypeQualifier() == NA_NUMERIC_TYPE);
  Lng32 pf;
  memcpy(&pf,pfconst->getConstValue(),sizeof(Lng32));

  // No of bits reserved for null indicators.
  nullsPresent_ = unpackType->supportsSQLnullPhysical();
  Lng32 nullIndLenInBytes = (nullsPresent_ ? (pf-1)/8+1 : 0);
  base_ = pfSizeInBytes + nullIndLenInBytes;

  // Storage size for the actual packed column values in bytes.
  Lng32 dataSizeInBytes;

  // For bit precision integers, width needs to be in negative no of bits.
  if(unpackType->getFSDatatype() == REC_BPINT_UNSIGNED)
  {
    width_ = ((SQLBPInt*)unpackType)->getDeclaredLength();
    dataSizeInBytes = (width_*pf-1)/8+1;
    width_ = -width_;
  }
  else
  {
    width_ = unpackType->getNominalSize();
    dataSizeInBytes = width_ * pf;
  }

  // Now, the length of the contents of a packed record in bytes.
  Lng32 packedRowSizeInBytes = (base_ + dataSizeInBytes);

  // Synthesize type of the packed column.
  type_ = new(CmpCommon::statementHeap()) SQLChar(CmpCommon::statementHeap(), packedRowSizeInBytes,FALSE);
  isFormatInfoValid_ = TRUE;
}

PackFunc::~PackFunc() {}

NABoolean PackFunc::isCovered(const ValueIdSet& newExternalInputs,
                              const GroupAttributes& newRelExprAnchorGA,
                              ValueIdSet& referencedInputs,
                              ValueIdSet& coveredSubExpr,
                              ValueIdSet& unCoveredExpr) const
{
  // ---------------------------------------------------------------------
  // If the operand is covered, then return its ValueId in coveredSubExpr.
  // ---------------------------------------------------------------------
  ValueIdSet localSubExpr;
  for(Lng32 i = 0; i < (Lng32)getArity(); i++)
  {
    if(newRelExprAnchorGA.covers(child(i)->getValueId(),
                                 newExternalInputs,
                                 referencedInputs,
                                 &localSubExpr))
    {
      coveredSubExpr += child(i)->getValueId();
    }
  }

  // ---------------------------------------------------------------------
  // The packing function is coerced to fail the coverage test even when
  // its operands isCovered(). This is because only the Pack node can
  // evaluate a packing function. The function is associated with a Pack
  // node at the very beginning and we don't allow it to be pushed down
  // even if the function's operands are covered at the Pack node's child.
  // ---------------------------------------------------------------------
  return FALSE;
}

void PackFunc::getLeafValuesForCoverTest(ValueIdSet& leafValues, 
                                         const GroupAttributes& coveringGA,
                                         const ValueIdSet & newExternalInputs) const
{
  // see note in isCovered().
  leafValues += getValueId();
}

ItemExpr* PackFunc::copyTopNode(ItemExpr* derivedNode, CollHeap* outHeap)
{
  ItemExpr* result;

  if(derivedNode == NULL)
    result = new (outHeap) PackFunc (child(0),child(1));
  else
    result = derivedNode;

  return BuiltinFunction::copyTopNode(result,outHeap);
}

UDFunction::~UDFunction()
{
  delete udfDesc_;
}

Int32 UDFunction::getArity() const
{
  return getNumChildren(); // Function class member function.
}

const NAString UDFunction::getText() const
{
  return functionName_.getExternalName();
}

HashValue UDFunction::topHash()
{
  HashValue result = ItemExpr::topHash();

  // hash any local data members of the derived class
  result ^= functionName_.getExternalName() + actionName_;

  return result;
}

NABoolean Function::duplicateMatch(const ItemExpr & other) const
{
  if (NOT genericDuplicateMatch(other))
    return FALSE;

  return TRUE;
}

NABoolean UDFunction::duplicateMatch(const ItemExpr & other) const
{
  // Check to see if the arguments are the same, among other things.
  if (NOT genericDuplicateMatch(other))
    return FALSE;

  UDFunction &o = (UDFunction &) other;

  // compare all local data members of the derived class
  // and return FALSE if they don't match
  if (functionName_.getExternalName() != o.functionName_.getExternalName() ||
      actionName_                     != o.actionName_  ||
      hasSubquery_                    != o.hasSubquery_ ||
      inputVars_                      != o.inputVars_   ||
      outputVars_                     != o.outputVars_)
    return FALSE;

  if (udfDesc_ && o.udfDesc_) // RoutineDesc pointers
    if (!(*udfDesc_ == *o.udfDesc_))
      return FALSE;

  if (udfDesc_ != NULL || o.udfDesc_ != NULL) // Both must be NULL to proceed.
    return FALSE;


  return TRUE;
}

ItemExpr *UDFunction::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  UDFunction *result;

  if (derivedNode == NULL)
    result = new (outHeap) UDFunction(functionName_, getArity(), outHeap);
  else
    result = (UDFunction *) derivedNode;

  result->heap_        = outHeap;
  result->functionName_= functionName_;
  result->functionNamePos_= functionNamePos_;
  result->actionName_  = actionName_  ;
  result->udfDesc_     = udfDesc_ != NULL ? 
                           new (outHeap) RoutineDesc(*udfDesc_, outHeap) : NULL;
  result->hasSubquery_ = hasSubquery_ ;
  result->inputVars_   = inputVars_   ;
  result->outputVars_  = outputVars_  ;


  return Function::copyTopNode(result, outHeap);
}

void UDFunction::unparse(NAString &result,
		      PhaseEnum phase,
                      UnparseFormatEnum form,
		      TableDesc * tabId) const
{
  NAString kwd(getText(), CmpCommon::statementHeap());
  if (form == USER_FORMAT_DELUXE) kwd.toUpper();
  result += kwd;
  result += "(";
  CollIndex lastComma = getNumChildren() -1;
  for (CollIndex i=0; i<(CollIndex ) getNumChildren(); i++)
  {
     child(i)->unparse(result,phase,form,tabId);
     if (i < lastComma) result += ",";
  }
  result += ")";

}

ExprValueId &UDFunction::operator[] (Lng32 index)
{
  return Function::operator[](index);
}
const ExprValueId &UDFunction::operator[] (Lng32 index) const
{
  return Function::operator[](index);
}

ItemExpr *UDFunction::containsUDF()
{
  return this;
}

NABoolean UDFunction::containsIsolatedUDFunction()
{
  NABoolean containsIsolatedUDF(FALSE);

  for (CollIndex i=0; i < (CollIndex) getNumChildren(); i++)
  {
    if (child(i)->containsIsolatedUDFunction() == TRUE)
      containsIsolatedUDF = TRUE;
  }

  if (containsIsolatedUDF == TRUE) 
    return TRUE;

  // We didn't have one as an input parameter, check to see if we
  // are isolated..
  const RoutineDesc *rdesc = getRoutineDesc();
  if (rdesc == NULL || rdesc->getEffectiveNARoutine() == NULL ) return FALSE;  
  return ( rdesc->getEffectiveNARoutine()->isIsolate() ? TRUE : FALSE ) ;
} // UDFunction::containsIsolatedUDFunction

// Get the output degree of this function.  If it is >1, getOutputItem
// should be used to get the ItemExpr of each output.
int UDFunction::getOutputDegree()
{
  CCMPASSERT(getRoutineDesc() != NULL);
  if (!getRoutineDesc()) return -1; // Routine desc not set.  Error.
  else 
    return getRoutineDesc()->getOutputColumnList().entries();
}

// Get i'th output argument of UDF as ItemExpr.
ItemExpr *UDFunction::getOutputItem(unsigned int i)
{
  CCMPASSERT(getRoutineDesc() != NULL);
  if (!getRoutineDesc()) return NULL; // Routine desc not set.  Error.
  else 
  {
    if (i < getRoutineDesc()->getOutputColumnList().entries())
      return getRoutineDesc()->getOutputColumnList()[i].getItemExpr();
    else return NULL; // 'i' out of bounds.  Error.
  }
}

ItemExpr * NotIn::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  NotIn *result;

  if (derivedNode == NULL)
    result = new (outHeap) NotIn();
  else
    result = (NotIn *) derivedNode;

  //copy the data members
  result->equivEquiPredicate_ = equivEquiPredicate_;
  result->equivNonEquiPredicate_ = equivNonEquiPredicate_;
  result->isOneInnerBroadcastRequired_ = isOneInnerBroadcastRequired_;

  return BiRelat::copyTopNode(result, outHeap);
}

ValueId NotIn::createEquivEquiPredicate() const
{
  CMPASSERT ( child(0)->getOperatorType() != ITM_ITEM_LIST && 
              child(1)->getOperatorType() != ITM_ITEM_LIST) 

  ItemExpr * newPred = new (CmpCommon::statementHeap()) 
                        BiRelat(ITM_EQUAL, 
                                child(0),
                                child(1));
   
  newPred->synthTypeAndValueId(TRUE);
  
  return newPred->getValueId();
}
ValueId NotIn::createEquivNonEquiPredicate() const
{
  CMPASSERT ( child(0)->getOperatorType() != ITM_ITEM_LIST && 
              child(1)->getOperatorType() != ITM_ITEM_LIST) 

  ItemExpr * newPred = new (CmpCommon::statementHeap()) 
                        BiRelat(ITM_NOT_EQUAL, 
                                child(0),
                                child(1));
            
  newPred = new (CmpCommon::statementHeap()) 
                        UnLogic(ITM_IS_TRUE, newPred);
 
  newPred = new (CmpCommon::statementHeap()) 
                        UnLogic(ITM_NOT, newPred);

  newPred->synthTypeAndValueId(TRUE);
    
  return newPred->getValueId();
}

void NotIn::cacheEquivEquiPredicate()
{
      
  if (getEquivEquiPredicate() == NULL_VALUE_ID)
  {
    ValueId vid = createEquivEquiPredicate();
        
    ItemExpr * itm = vid.getItemExpr();
        
    ((BiRelat *)itm)->setIsNotInPredTransform(TRUE); 
        
    ((BiRelat *)itm)->setOuterNullFilteringDetected(
                          getOuterNullFilteringDetected());
    ((BiRelat *)itm)->setInnerNullFilteringDetected(
                          getInnerNullFilteringDetected());

    setEquivEquiPredicate(vid);
  }
}

void NotIn::cacheEquivNonEquiPredicate()
{
  if (getEquivNonEquiPredicate() == NULL_VALUE_ID )
  {
    setEquivNonEquiPredicate(
		  createEquivNonEquiPredicate());
  }
}


void  NotIn::cacheIsOneInnerBroadcastRequired()
{

  if (isOneInnerBroadcastRequired_ == NotIn::NOT_SET)
  {

    isOneInnerBroadcastRequired_ = NotIn::NOT_REQUIRED;

    ItemExpr * child0 = child(0);
    const NAType &outerType = child0->getValueId().getType();

    if (outerType.supportsSQLnull()  &&
        !getOuterNullFilteringDetected())
    {
      isOneInnerBroadcastRequired_ = NotIn::REQUIRED;
    }
  }
  
}//NotIn::cacheIsOneInnerBroadcastRequired()




// -----------------------------------------------------------------------
// member functions for class BiLogic
// -----------------------------------------------------------------------
Int32 BiLogic::getArity() const { return 2; }

NABoolean BiLogic::isAPredicate() const { return TRUE; }

// return true iff we're an expansion of a LIKE predicate
NABoolean BiLogic::isLike() const
{
  switch (getOperatorType()) {
  case ITM_AND:
  case ITM_OR:
    {
      Int32 arity = getArity();
      for (Int32 x = 0; x < arity; x++) {
        switch (child(x)->getOperatorType()) {
        case ITM_GREATER_EQ:
        case ITM_LESS:
          if (!((BiRelat*)child(x).getPtr())->derivativeOfLike())
            return FALSE; // we're not an expansion of a LIKE predicate
          else // we may be part of an expansion of a LIKE predicate
            continue; // keep looking
          break;
        default:
          return FALSE; // we're not an expansion of a LIKE predicate
          break;
        }
      }
      return TRUE; // yes, we are an expansion of a LIKE predicate
    }
    break;
  default:
    return FALSE; // we're not an expansion of a LIKE predicate
  }
}

// -----------------------------------------------------------------------
// BiLogic::isCovered()
// -----------------------------------------------------------------------
NABoolean BiLogic::isCovered
                      (const ValueIdSet& newExternalInputs,
		       const GroupAttributes& coveringGA,
		       ValueIdSet& referencedInputs,
		       ValueIdSet& coveredSubExpr,
		       ValueIdSet& unCoveredExpr) const
{
  if (getOperatorType() == ITM_OR)
    {
      // ----------------------------------------------------------------
      // The subtree that is rooted in an OR can contain values that
      // are produced by different sources. The entire expression tree
      // including the OR at the root is covered, if the subtree that
      // is rooted in the OR is covered. Otherwise it is not covered.
      // The coverage test insists on a complete coverage of all the
      // expressions at the leaves.
      // ----------------------------------------------------------------
      ValueIdSet leafValues;
      getLeafValuesForCoverTest(leafValues, coveringGA, newExternalInputs);
      return leafValues.isCovered(newExternalInputs,
				  coveringGA,
				  referencedInputs,
				  coveredSubExpr,
				  unCoveredExpr);
    }
  else
    return ItemExpr::isCovered(newExternalInputs,
			       coveringGA,
			       referencedInputs,
			       coveredSubExpr,
			       unCoveredExpr);
} // BiLogic::isCovered()

NABoolean BiLogic::duplicateMatch(const ItemExpr& other) const
{
  return genericDuplicateMatch(other);
}

ItemExpr * BiLogic::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  BiLogic *result;

  if (derivedNode == NULL)
    result = new (outHeap) BiLogic(getOperatorType());
  else
    result = (BiLogic*)derivedNode;

  result->setNumLeaves(getNumLeaves());
  result->createdFromINlist_ = createdFromINlist_;

  return ItemExpr::copyTopNode(result, outHeap);
}

ItemExpr* BiLogic::getINlhs() 
{
  if (createdFromINlist() && child(1)->getOperatorType() == ITM_EQUAL)
    return child(1)->child(0);
  else
    return NULL;
}

const NAString BiLogic::getText() const
{
  switch (getOperatorType())
    {
    case ITM_AND:
      return "and";
    case ITM_OR:
      return "or";
    default:
      return "unknown BiLogic";
    } // switch
} // BiLogic::getText()

QR::ExprElement BiLogic::getQRExprElem() const
{
  return QR::QRBinaryOperElem;
}

// -----------------------------------------------------------------------
// member functions for class UnLogic
// -----------------------------------------------------------------------
Int32 UnLogic::getArity() const { return 1; }

NABoolean UnLogic::isAPredicate() const { return TRUE; }

const NAString UnLogic::getText() const
{
  switch (getOperatorType())
    {
    case ITM_NOT:
      return "not";
    case ITM_IS_TRUE:
      return "is true";
    case ITM_IS_FALSE:
      return "is false";
    case ITM_IS_NULL:
      return "is null";
    case ITM_IS_NOT_NULL:
      return "is not null";
    case ITM_IS_UNKNOWN:
      return "is unknown";
    case ITM_IS_NOT_UNKNOWN:
      return "is not unknown";
    default:
      return "unknown UnLogic??";
    } // switch
} // UnLogic::getText()

NABoolean UnLogic::duplicateMatch(const ItemExpr & other) const
{
  if (NOT genericDuplicateMatch(other))
    return FALSE;

  return TRUE;
}

ItemExpr * UnLogic::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL)
    result = new (outHeap) UnLogic(getOperatorType());
  else
    result = derivedNode;

  return ItemExpr::copyTopNode(result, outHeap);
}

QR::ExprElement UnLogic::getQRExprElem() const
{
  return QR::QRUnaryOperElem;
}

// -----------------------------------------------------------------------
// member functions for class BiRelat
// -----------------------------------------------------------------------
NABoolean BiRelat::derivativeOfLike()
{
  if (originalLikeExprId() != NULL_VALUE_ID)
    return TRUE;
  else
    return FALSE;
}

void BiRelat::adjustRowcountAndUecForLike(const ColStatDescSharedPtr& colStatDesc,
					CostScalar rowCountBeforePreds,
					CostScalar totalUecBeforePreds,
					CostScalar baseUecBeforePreds)
{
  // This range predicate is a derivative of Like predicate.
  // Hence we cannot use the usual selectivity obtained after
  // applying range predicates. Here we use a portion of the
  // default selectivity for like predicates to obtain the
  // resultant rowcount. We still continue to use the histograms
  // obtained after applying range predicates the usual way
  // The selectivity would be applied to the inital rowcount
  // before any predicates were applied.

  ColStatsSharedPtr colStats = colStatDesc->getColStatsToModify() ;

  CostScalar nrc  = MIN_ONE_CS(rowCountBeforePreds * getLikeSelectivity());
  CostScalar nuec = MIN_ONE_CS(totalUecBeforePreds * getLikeSelectivity());
  CostScalar baseuec = MIN_ONE_CS(baseUecBeforePreds * getLikeSelectivity());


  if ( colStats->isUnique() )
  {
    // If this is a UNIQUE column, UEC == rowcount
    nuec = nrc;
  }
  else
  {
    nuec = MINOF(nrc, nuec);
  }

  HistogramSharedPtr hist = colStats->getHistogramToModify() ;
  hist->condenseToSingleInterval();
  colStats->setIsCompressed(TRUE);

  // first, set the aggregate values
  colStats->setRowsAndUec  ( nrc, nuec );
  colStats->setRedFactor   ( csOne );
  colStats->setUecRedFactor( csOne );
  colStats->setBaseUec(baseuec);

  // Set first interval's rowcount and uec.
  hist->getFirstInterval().setRowsAndUec( nrc, nuec );

  // from this point forward, we're going to consider this a fake histogram
  colStats->setFakeHistogram();
}

Int32 BiRelat::getArity() const { return 2; }

NABoolean BiRelat::isAPredicate() const { return TRUE; }

const NAString BiRelat::getText() const
{
  switch (getOperatorType())
    {
    case ITM_EQUAL:
      return "=";
    case ITM_NOT_EQUAL:
      return "<>";
    case ITM_LESS:
      return "<";
    case ITM_LESS_EQ:
      return "<=";
    case ITM_GREATER:
      return ">";
    case ITM_GREATER_EQ:
      return ">=";
    default:
      return "unknown BiRelat";
    } // switch

 } // BiRelat::getText()

NABoolean BiRelat::duplicateMatch(const ItemExpr& other) const
{
  if (NOT genericDuplicateMatch(other))
    return FALSE;

  const BiRelat &o = (BiRelat &) other;

  if (specialNulls_ != o.specialNulls_ OR
      specialMultiValuePredicateTransformation_ !=
      o.specialMultiValuePredicateTransformation_ OR
      directionVector_ != o.directionVector_ /* ptr comparison only */ OR
      isaPartKeyPred_ != o.isaPartKeyPred_ OR
      originalLikeExprId_ != o.originalLikeExprId_ OR
      likeSelectivity_ != o.likeSelectivity_ OR
      derivedFromMCRP_ != o.derivedFromMCRP_ OR
      preferForSubsetScanKey_ != o.preferForSubsetScanKey_
      )
    return FALSE;


  // do this if this a range predicate derived from a MCRP
  // A MCRP (MultiColumnRangePredicate) is a predicate of the form
  // (a, b, c) > (1, 2, 3). Such a predicate is transformed to
  // (a >= 1) and ((a, b, c) > (1, 2, 3)). Notice the transformation
  // adds predicate (a >= 1). The derivedFromMCRP flag is set to TRUE
  // for predicate (a >= 1).
  if ((derivedFromMCRP_ == TRUE) &&
      (listOfComparisonExprs_ != o.listOfComparisonExprs_))
  {
    if (listOfComparisonExprIds_.entries() != o.listOfComparisonExprIds_.entries())
      return FALSE;

    for (CollIndex i=0; i < listOfComparisonExprIds_.entries(); i++)
    {
      if (listOfComparisonExprIds_[i] != o.listOfComparisonExprIds_[i])
        return FALSE;
    }
  }

  return TRUE;
}

ItemExpr * BiRelat::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  BiRelat *result;

  if (derivedNode == NULL)
    result = new (outHeap) BiRelat(getOperatorType());
  else
    result = (BiRelat *) derivedNode;

  // copy the data members
  result->specialNulls_ = specialNulls_;
  result->specialMultiValuePredicateTransformation_ =
    specialMultiValuePredicateTransformation_;
  result->isaPartKeyPred_ = isaPartKeyPred_;
  result->originalLikeExprId_ = originalLikeExprId_;

  result->setDirectionVector(directionVector_);
  result->likeSelectivity_ = likeSelectivity_;
  result->derivedFromMCRP_ = derivedFromMCRP_;
  result->listOfComparisonExprs_ = listOfComparisonExprs_;
  result->listOfComparisonExprIds_ = listOfComparisonExprIds_;
  result->leftMCRPChildList_ = leftMCRPChildList_;
  result->rightMCRPChildList_ = rightMCRPChildList_;
  result->preferForSubsetScanKey_ = preferForSubsetScanKey_;

  result->createdFromINlist_ = createdFromINlist_;
  
  result->collationEncodeComp_  = collationEncodeComp_;
  result->isNotInPredTransform_ = isNotInPredTransform_;
  result->outerNullFilteringDetected_= outerNullFilteringDetected_;
  result->innerNullFilteringDetected_ = innerNullFilteringDetected_;

  result->rollupColumnNum_ = rollupColumnNum_;

  result->flags_ = flags_;

  return ItemExpr::copyTopNode(result, outHeap);
}

void BiRelat::getLeftMCRPChildList(ValueIdList & leftMCRPChildList)
{
  if ((!isDerivedFromMCRP()) ||
      (!listOfComparisonExprIds_.entries()))
    return;

  if (leftMCRPChildList_.entries())
  {
    leftMCRPChildList = leftMCRPChildList_;
    return;
  }

  // iterate over the list of comparisons
  for(CollIndex i=0; i < listOfComparisonExprIds_.entries(); i++)
  {
    //get comparison at location i
    BiRelat * comparison = (BiRelat *) listOfComparisonExprIds_[i].getItemExpr();

    ItemExpr * leftChild = (ItemExpr *) comparison->child(0);
    ItemExpr * rightChild = (ItemExpr *) comparison->child(1);
    leftMCRPChildList_.insert(leftChild->getValueId());
    rightMCRPChildList_.insert(rightChild->getValueId());
  }

  leftMCRPChildList = leftMCRPChildList_;
}

void BiRelat::getRightMCRPChildList(ValueIdList & rightMCRPChildList)
{
  if ((!isDerivedFromMCRP()) ||
      (!listOfComparisonExprIds_.entries()))
    return;

  if (rightMCRPChildList_.entries())
  {
    rightMCRPChildList = rightMCRPChildList_;
    return;
  }

  // iterate over the list of comparisons
  for(CollIndex i=0; i < listOfComparisonExprIds_.entries(); i++)
  {
    //get comparison at location i
    BiRelat * comparison = (BiRelat *) listOfComparisonExprIds_[i].getItemExpr();

    ItemExpr * leftChild = (ItemExpr *) comparison->child(0);
    ItemExpr * rightChild = (ItemExpr *) comparison->child(1);
    leftMCRPChildList_.insert(leftChild->getValueId());
    rightMCRPChildList_.insert(rightChild->getValueId());
  }

  rightMCRPChildList = rightMCRPChildList_;
}

QR::ExprElement BiRelat::getQRExprElem() const
{
  return QR::QRBinaryOperElem;
}

OperatorTypeEnum BiRelat::getRelaxedComparisonOpType() const
{
  switch (getOperatorType())
   {
   case ITM_LESS:
     return ITM_LESS_EQ;

   case ITM_GREATER:
     return ITM_GREATER_EQ;

   case ITM_NOT_EQUAL:
     CMPASSERT(0); // the relaxed form would be TRUE,
                   // but we don't handle that right now

   default:
     break;
   }

 return getOperatorType();
}


// Member functions for class KeyRangeCompare //

const NAString KeyRangeCompare::getText() const
{

  NAString result("", CmpCommon::statementHeap());

  switch (getOperatorType())
    {
    case ITM_EQUAL:
      result += "=";
      break;
    case ITM_NOT_EQUAL:
      result += "<>";
      break;
    case ITM_LESS:
      result += "<";
      break;
    case ITM_LESS_EQ:
      result += "<=";
      break;
    case ITM_GREATER:
      result += ">";
      break;
    case ITM_GREATER_EQ:
      result += ">=";
      break;
    default:
      result +=  "unknown BiRelat";
      return result;
    } // switch

  result += " (KEY_RANGE_COMPARE)";

  return result;

 } // KeyRangeCompare::getText()

// -----------------------------------------------------------------------
// member functions for class ConstValue
// -----------------------------------------------------------------------
// constructor for an untyped NULL constant
ConstValue::ConstValue()
: ItemExpr(ITM_CONSTANT)
     , isNull_(IS_NULL)
     , type_(new (CmpCommon::statementHeap()) SQLUnknown(CmpCommon::statementHeap(), TRUE))
     , value_(NULL)
     , storageSize_(0)
     , text_(new (CmpCommon::statementHeap()) NAString("NULL", CmpCommon::statementHeap()))
     , textIsValidatedSQLLiteralInUTF8_(FALSE)
     , isSystemSupplied_(FALSE)
     , locale_strval(0)
     , locale_wstrval(0)
     , isStrLitWithCharSetPrefix_(FALSE)
     , rebindNeeded_(FALSE)
{
}

// constructor for a numeric constant
ConstValue::ConstValue(Lng32 intval, NAMemory * outHeap)
           : ItemExpr(ITM_CONSTANT)
           , isNull_(IS_NOT_NULL)
           , textIsValidatedSQLLiteralInUTF8_(FALSE)
           , type_(new (CmpCommon::statementHeap()) SQLInt(CmpCommon::statementHeap(), TRUE, FALSE))
	   , isSystemSupplied_(FALSE)
           , locale_strval(0)
           , locale_wstrval(0)
           , isStrLitWithCharSetPrefix_(FALSE)
           , rebindNeeded_(FALSE)
{
  Int64 lintval = intval;
  char buf[TEXT_DISPLAY_LENGTH];
  char * S = buf;
  Int32 len = 0;
  sprintf(S,"%d %n",intval, &len);
  S[len++] = '\0';
  text_ = new (outHeap) NAString(S, outHeap);
  storageSize_ = sizeof(Lng32);
  value_ = (void *)( new (outHeap) char[storageSize_] );
  // copy the bit pattern as is
  memcpy(value_,(void *)(&intval),(Int32)storageSize_);
}

ConstValue::ConstValue(const NAString & strval,
             enum CharInfo::CharSet charSet,
             enum CharInfo::Collation collation,
             enum CharInfo::Coercibility coercibility,
             NAMemory * outHeap)
: ItemExpr(ITM_CONSTANT), isNull_(IS_NOT_NULL),
  textIsValidatedSQLLiteralInUTF8_(FALSE), isStrLitWithCharSetPrefix_(FALSE),
  isSystemSupplied_(FALSE), locale_wstrval(0), rebindNeeded_(FALSE)
{
   initCharConstValue(strval, charSet, collation, coercibility, FALSE, outHeap);
   locale_strval = new (outHeap) NAString
    ((char*)strval.data(), strval.length(), outHeap);
}

void ConstValue::initCharConstValue
(
     const NAString & strval,
     enum CharInfo::CharSet charSet,
     enum CharInfo::Collation collation,
     enum CharInfo::Coercibility coercibility,
     NABoolean isCaseInSensitive,
     NAMemory * outHeap
     )
{

  if (strval.length() == 0)
    {
      // create a varchar constant of length 0, in this case.
      type_ = new (outHeap)
		SQLVarChar(outHeap, 0, FALSE, FALSE, FALSE,
			   charSet, collation, coercibility);
      storageSize_ = type_->getVarLenHdrSize();
      value_ = (void *)( new (outHeap) 
			 char[storageSize_] );
      str_pad((char *)value_, (Int32)storageSize_, '\0');
    }
  else
    {

      // A "mini-cache" to avoid proc call, for performance,
      // local to the SINGLE-byte-charset NAString ctor
      // (distinct from the double-byte-charset ctor to prevent cache churn).
      static THREAD_P CharInfo::CharSet cachedCS  = CharInfo::UnknownCharSet;
      static THREAD_P Int32               cachedBPC = 1;
      if (cachedCS != charSet) {
        cachedCS = charSet;
	cachedBPC = CharInfo::maxBytesPerChar(charSet);
      }
      Int32 num_of_chars = (Int32)strval.length() / cachedBPC;
      if (CharInfo::isVariableWidthMultiByteCharSet(charSet))
      {
        Int32 actualCharsCount = ComputeStrLenInUCS4chars
          ( strval.data()             // const char * pStr
          , (Int32) strval.length()   // const Int32  strLenInBytes
          , charSet                   // const CharInfo::CharSet cs
          );
        CMPASSERT(actualCharsCount >= 0); // no errors
        type_ = new (outHeap) SQLChar (outHeap,  CharLenInfo ( actualCharsCount
                                                    , strval.length() // str len in bytes
                                                    )
                                      , FALSE           // allowSQLnull
                                      , FALSE           // isUpShifted
                                      , FALSE           // isCaseInsensitive
                                      , FALSE           // varLenFlag
                                      , charSet
                                      , collation
                                      , coercibility
                                      , /*encoding*/charSet
                                      );
      }
      else
      type_ = new (outHeap)
		SQLChar(outHeap, num_of_chars, FALSE, FALSE, FALSE, FALSE,
			charSet, collation, coercibility);


      storageSize_ = strval.length();
      value_ = (void *)( new (outHeap)
			 char[storageSize_] );
      memcpy(value_, (void *)(strval.data()), (Int32)storageSize_);
    }

  ((CharType*)type_)->setCaseinsensitive(isCaseInSensitive);

  text_ = new (outHeap)
    NAString(strval,
	     outHeap);
  textIsValidatedSQLLiteralInUTF8_ = FALSE;
}

ConstValue::ConstValue(const NAWString& wstrval,
             enum CharInfo::CharSet charSet,
             enum CharInfo::Collation collation,
             enum CharInfo::Coercibility coercibility,
             NAMemory * outHeap,
             enum CharInfo::CharSet strLitPrefixCharSet
)
 : ItemExpr(ITM_CONSTANT), isNull_(IS_NOT_NULL),
   isSystemSupplied_(FALSE),
   value_(0),
   text_(0),
   locale_strval(0),
   locale_wstrval(0),
   isStrLitWithCharSetPrefix_(FALSE),
   rebindNeeded_(FALSE)
{
   initCharConstValue(wstrval, charSet, collation, coercibility, FALSE, outHeap,
                      strLitPrefixCharSet);

   locale_wstrval = new (CmpCommon::statementHeap()) NAWString
      (wstrval.data(), wstrval.length(), CmpCommon::statementHeap());
}

void ConstValue::initCharConstValue(const NAWString& strval,
             enum CharInfo::CharSet charSet,
             enum CharInfo::Collation collation,
             enum CharInfo::Coercibility coercibility,
             NABoolean isCaseInSensitive,
             NAMemory * outHeap,
             enum CharInfo::CharSet strLitPrefixCharSet)
{
  if (strval.length() == 0)
    {
      // create a varchar constant of length 0, in this case.
      type_ = new (outHeap)
		SQLVarChar(outHeap, 0, FALSE, FALSE, FALSE,
			   charSet, collation, coercibility);
      storageSize_ = type_->getVarLenHdrSize();
      value_ = (void *)( new (outHeap) 
			 NAWchar[storageSize_] );
      wc_str_pad((NAWchar *)value_, (Int32)storageSize_, '\0');
    }
  else
    {
      // A "mini-cache" to avoid proc call, for performance,
      // local to the DOUBLE-byte-charset NAString ctor
      // (distinct from the single-byte-charset ctor to prevent cache churn).
      static CharInfo::CharSet cachedCS  = CharInfo::UNICODE;
      static Int32               cachedBPC = sizeof(NAWchar);

      if (cachedCS != charSet) {
        cachedCS = charSet;

        if (cachedCS == CharInfo::UnknownCharSet) {
          cachedCS = CharInfo::UNICODE;
          cachedBPC = sizeof(NAWchar);
        } else {
          cachedBPC = CharInfo::maxBytesPerChar(cachedCS);

          // make sure the incoming charset is double-byte
          CMPASSERT(cachedBPC == (Int32)sizeof(NAWchar));
        }
      }


      Int32 num_of_chars = (Int32)strval.length();

      type_ = new (outHeap)
		SQLChar(outHeap, num_of_chars, FALSE, FALSE, FALSE, FALSE,
			charSet, collation, coercibility);

      storageSize_ = cachedBPC * strval.length();
      value_ = (void *)( new (outHeap) 
			 NAWchar[storageSize_] );
      memcpy(value_, (void *)(strval.data()), (Int32)storageSize_);
    }

  ((CharType*)type_)->setCaseinsensitive(isCaseInSensitive);

  text_ = new (outHeap)
	    NAString((char*)strval.data(), storageSize_,
	     outHeap);
  textIsValidatedSQLLiteralInUTF8_ = FALSE;
}


ConstValue::ConstValue(NAString strval, NAWString wstrval,
             enum CharInfo::Collation collation,
             enum CharInfo::Coercibility coercibility,
             NAMemory * outHeap)
 : ItemExpr(ITM_CONSTANT), isNull_(IS_NOT_NULL),
   value_(0),
   text_(0),
   textIsValidatedSQLLiteralInUTF8_(FALSE),
   isSystemSupplied_(FALSE),
   isStrLitWithCharSetPrefix_(FALSE),
   rebindNeeded_(FALSE)
{
   initCharConstValue(strval, CharInfo::UnknownCharSet,
          collation, coercibility, FALSE, outHeap);

/*
   type_ =  new (CmpCommon::statementHeap())
       SQLVarChar(0, FALSE, FALSE,
                  CharInfo::UnknownCharSet, collation, coercibility);

   storageSize_ = type_->getVarLenHdrSize();
*/

   locale_strval = new (CmpCommon::statementHeap()) NAString
    ((char*)strval.data(), strval.length(), CmpCommon::statementHeap());

   locale_wstrval = new (CmpCommon::statementHeap()) NAWString
    (wstrval.data(), wstrval.length(), CmpCommon::statementHeap());
}


const NAType* ConstValue::pushDownType(NAType& newType,
				       enum NABuiltInTypeEnum defaultQualifier)
{
   if ( newType.getTypeQualifier() == NA_CHARACTER_TYPE &&
        type_ -> getTypeQualifier() == NA_CHARACTER_TYPE
      )
   {
     CharType &newCT = (CharType&)newType;
     enum CharInfo::CharSet newCS = ((const CharType&)newType).getCharSet();
     CharType* ct = (CharType*)type_;

     if ( ct ->getCharSet() != newCS ) {

       if ( newCS == CharInfo::UNICODE ) {
	 assert(locale_wstrval);
         // fix 10-070329-5979 by passing in the case-sensitivity flag.
         // Should re-implement this with collation some day.
	 initCharConstValue(*locale_wstrval, newCS,
			    ct->getCollation(),
			    ct->getCoercibility(),
                            ct->isCaseinsensitive());
       } else {

	 if ( locale_strval == NULL ) {

	   assert(locale_wstrval);

	   // init locale_strval from locale_wstrval
	   Lng32 wlen = (Lng32)(locale_wstrval->length());
	   Lng32 bufLen = wlen * CharInfo::maxBytesPerChar(newCS) + 1; // add the NULL
	   char* buf = new (CmpCommon::statementHeap()) char[bufLen];

	   Lng32 cLen = UnicodeStringToLocale(newCS, locale_wstrval->data(), wlen,
					     buf, bufLen, TRUE, FALSE);

	   if ( cLen == 0 ) {  // If conversion fails, do not change the type.
	     NADELETEBASIC(buf,CmpCommon::statementHeap());
	     return type_;
	   }

	   locale_strval = new (CmpCommon::statementHeap()) NAString
	     (buf, cLen, CmpCommon::statementHeap());

	   NADELETEBASIC(buf,CmpCommon::statementHeap());
	 }


	 // fix 10-040527-6468 (CQD infer_charset doesn't work with
	 // kanji character set correctly). We do not change this ConstValue
	 // object's attributes if the lendth of the literal is odd. The
	 // compatibility check code will catch the incompatible error (e.g.,
	 // T.KANJI_C1 = _unknown'abc').
	 if ( CharInfo::is_NCHAR_MP(newCS) == FALSE ||
	      locale_strval -> length() % SQL_DBCHAR_SIZE == 0
	      )
	   {
             // fix 10-070329-5979 by passing in the case-sensitivity flag.
             // Should re-implement this with collation some day.
	     initCharConstValue(*locale_strval, newCS,
				ct->getCollation(),
				ct->getCoercibility(),
                                ct->isCaseinsensitive());
	   }
       }
     }
     return synthesizeType();
   }

   return &newType;
}

// this constructor creates a constant of the given type and initializes
// it with the value.
ConstValue::ConstValue(const NAType * type, void * value, Lng32 value_len,
		       NAString * literal, NAMemory * outHeap)
  : ItemExpr(ITM_CONSTANT)
  , isNull_(IS_NOT_NULL)
  , type_(type)
  , isSystemSupplied_(FALSE)
  , locale_strval(0)
  , locale_wstrval(0)
  , isStrLitWithCharSetPrefix_(FALSE)
  , rebindNeeded_(FALSE)
{
  CMPASSERT(value_len > 0);
  CMPASSERT(type_);
  storageSize_ = value_len;
  value_ = (void *)( new (outHeap) char[storageSize_] );
  memcpy(value_,(void *)value,(Int32)storageSize_);

  if(type)
    type_ = type->newCopy(outHeap);

  NABoolean isNull = FALSE;

  // If a literal was not supplied, call a method to convert
  // the value from its binary form to UTF-8 and add any necessary
  // syntax modifiers like the charset and date and time qualifiers
  if (literal == NULL)
    {
      if (type_)
        textIsValidatedSQLLiteralInUTF8_ =
          type_->createSQLLiteral((const char *)value,
                                  text_,
                                  isNull,
                                  outHeap);
      DCMPASSERT(textIsValidatedSQLLiteralInUTF8_); // for now
      if (!textIsValidatedSQLLiteralInUTF8_)
        text_ = new (outHeap) NAString("<unknown value>", outHeap);
    }
  else
    {
      text_ = new (outHeap) NAString(*literal, outHeap);
      textIsValidatedSQLLiteralInUTF8_ = FALSE;
      if (type->supportsSQLnull())
        {
          // call the NAType base class method
          // just to check for a NULL value (sets isNull)
          NAString *dummyPtr;

          type->NAType::createSQLLiteral((const char *) value,
                                         dummyPtr,
                                         isNull,
                                         outHeap);
        }
    }

  if (isNull)
    isNull_ = IS_NULL;
}

/*soln:10-050710-9594 begin */

ConstValue::ConstValue(const NAType * type, void * value, Lng32 value_len,
		       NAString *lstrval, NAWString *wstrval, 
                     NAString * literal, NAMemory * outHeap, IsNullEnum isNull)
  : ItemExpr(ITM_CONSTANT)
  , isNull_(isNull)
  , type_(type)
  , isSystemSupplied_(FALSE)
  , locale_strval(0)
  , locale_wstrval(0)
  , isStrLitWithCharSetPrefix_(FALSE)
  , rebindNeeded_(FALSE)
{
  CMPASSERT(value_len > 0);
  CMPASSERT(type_);
  storageSize_ = value_len;
  value_ = (void *)( new (outHeap) char[storageSize_] );
  memcpy(value_,(void *)value,(Int32)storageSize_);

  if(type)
    type_ = type->newCopy(outHeap);

  // If a literal was not supplied, the text for this constant
  // is the bit pattern for the given value. Note that embedded
  // ascii nulls in the bit pattern are copied as is.
  if (literal == NULL)
    text_ = new (outHeap)
      NAString((char *)value,(UInt32)value_len, CmpCommon::statementHeap());
  else
    text_ = new (outHeap) NAString
      (*literal, outHeap);
  textIsValidatedSQLLiteralInUTF8_ = FALSE;

  if(lstrval)
     locale_strval = new (outHeap) NAString
      ((char*)lstrval->data(), lstrval->length(), outHeap);

  if(wstrval)
     locale_wstrval = new (outHeap) NAWString
      ((NAWchar *)wstrval->data(), wstrval->length(), outHeap);
}

/*soln:10-050710-9594 end */

// constructor for an extremal (min or max) value of a given type
// The allowNull parameter specifies whether NULL should be considered
// when generating the value; if it is TRUE and we want the max value,
// and the type is nullable, then NULL will be returned instead of the
// max non-null value.
ConstValue::ConstValue(const NAType * type,
		       const NABoolean wantMinValue,
		       const NABoolean includeNull,
                       NAMemory * outHeap)
: ItemExpr(ITM_CONSTANT)
, isNull_(IsNullEnum(type->supportsSQLnull() && includeNull && !wantMinValue))
, type_(type)
, isSystemSupplied_(FALSE)
, locale_strval(0)
, locale_wstrval(0)
, isStrLitWithCharSetPrefix_(FALSE)
, rebindNeeded_(FALSE)
{
  assert(type_);

  storageSize_ = type->getTotalSize();

  assert(storageSize_ > 0);

  char *storage = new (outHeap) char[storageSize_];
  value_ = (void *)storage;

  // if nullable, make the null indicator bytes 0 or NULL
  // depending on whether min or max value is needed.
  if (type->supportsSQLnull())
    {
      short indicatorVal;

      // the min value is non-NULL, the max value is the NULL
      // value unless we want the max non-NULL value
      if (wantMinValue || !includeNull)
	indicatorVal = 0;
      else
	indicatorVal = -1;

      // move the NULL indicator into the first few bytes of the value
      switch (type->getSQLnullHdrSize())
	{
	case 2:
	  *(short *)value_ = indicatorVal;
          break;
	case 4:
	  *(Lng32 *)value_ = (Lng32) indicatorVal;
          break;
	default:
	  CMPASSERT(0); // unsupported type of NULL indicator
	}
    }

  Lng32 startOfData = type->getSQLnullHdrSize();
  Lng32 templen = storageSize_ - startOfData;

  if (wantMinValue) // min value
  {
    type->minRepresentableValue(&storage[startOfData],
                                &templen,
                                NULL,
                                outHeap);
    text_ = new (outHeap) NAString("<min>", outHeap);
  }
  else
  {
    type->maxRepresentableValue(&storage[startOfData],
                                &templen,
                                NULL,
                                outHeap);
   text_ = new (outHeap) NAString("<max>", outHeap);
  }
  textIsValidatedSQLLiteralInUTF8_ = FALSE;
}

// A copy constructor used by the SampleSize derived class
//
ConstValue::ConstValue(OperatorTypeEnum otype,
                       ConstValue *other,
                       NAMemory * outHeap)
  : ItemExpr(otype)
//  , isNull_(other.isNull())
  , type_(other->getType())
  , storageSize_(other->getStorageSize())
  , textIsValidatedSQLLiteralInUTF8_(other->textIsValidatedSQLLiteralInUTF8_)
  , isSystemSupplied_(other->isSystemSupplied_)
  , locale_strval(other->locale_strval)
  , locale_wstrval(other->locale_wstrval)
  , isStrLitWithCharSetPrefix_(other->isStrLitWithCharSetPrefix_)
  , rebindNeeded_(other->rebindNeeded_)
{
  value_ = (void *)( new (outHeap) char[storageSize_] );
  memcpy(value_,(void *)other->getConstValue(),(Int32)storageSize_);
  text_ = new (outHeap)
               NAString(other->getText(), outHeap);
}

ConstValue::ConstValue(const ConstValue& s, NAHeap *h)
  : ItemExpr(ITM_CONSTANT), isNull_(s.isNull_), type_(s.type_)
  , storageSize_(s.storageSize_)
  , textIsValidatedSQLLiteralInUTF8_(s.textIsValidatedSQLLiteralInUTF8_)
  , isSystemSupplied_(s.isSystemSupplied_)
  , isStrLitWithCharSetPrefix_(s.isStrLitWithCharSetPrefix_)
  , rebindNeeded_(s.rebindNeeded_)
{
  if (s.value_) {
    value_ = (void *)( new (h) char[storageSize_] );
    memcpy(value_,(void *)s.value_,(Int32)storageSize_);
  }
  if (s.text_) {
    text_ = new (h) NAString(*s.text_, h);
  }
}

ConstValue::ConstValue(const ConstValue& s)
  : ItemExpr(ITM_CONSTANT), isNull_(s.isNull_), type_(s.type_)
  , storageSize_(s.storageSize_), value_(s.value_)
  , textIsValidatedSQLLiteralInUTF8_(s.textIsValidatedSQLLiteralInUTF8_)
  , text_(s.text_), isSystemSupplied_(s.isSystemSupplied_)
  , isStrLitWithCharSetPrefix_(s.isStrLitWithCharSetPrefix_)
  , rebindNeeded_(s.rebindNeeded_)
{
}

ConstValue::~ConstValue()
{
  // type_ can be shared by multiple consts --
  // see ConstValue::copyTopNode for a good example --
  // so we must not delete it!
     // delete type_;
  NADELETEBASIC((char*)value_,CmpCommon::statementHeap());   // value_ is a void*

  if (text_)
    NADELETEBASIC((NAString*)text_,CmpCommon::statementHeap());
}

NABoolean ConstValue::isAUserSuppliedInput() const    { return TRUE; }

void ConstValue::changeStringConstant(const NAString* strval)
{
   NADELETEBASIC((char*)value_,CmpCommon::statementHeap());   // value_ is a void*

   if (strval -> length() == 0)
   {
     // create a varchar constant of length 0, in this case.
     storageSize_ = type_->getVarLenHdrSize();
     value_ = (void *)( new (CmpCommon::statementHeap()) char[storageSize_] );
     str_pad((char *)value_, (Int32)storageSize_, '\0');
   } else {
     storageSize_ = strval -> length();
     value_ = (void *)( new (CmpCommon::statementHeap()) char[storageSize_] );
     memcpy(value_,(void *)(strval -> data()),(Int32)storageSize_);
   }

   *text_ = *strval;
}

NABoolean ConstValue::isAFalseConstant() const
{
  NABoolean result = FALSE;

  if (type_->getTypeQualifier() == NA_BOOLEAN_TYPE && !isNull())
    {
      CMPASSERT(storageSize_ == sizeof(Int32));
      if (*(reinterpret_cast<Int32 *>(value_)) == 0)
        result = TRUE; // that means the constant is FALSE!!
    }

  return result;          
}

NABoolean ConstValue::isExactNumeric() const
{
  return (type_->getTypeQualifier() == NA_NUMERIC_TYPE AND
	  ((NumericType *)type_)->isExact());
}

// exact numeric value can only be returned for certain types
// and if the value is within max largeint range.
NABoolean ConstValue::canGetExactNumericValue() const
{
  if (isExactNumeric())
    {
      NumericType &t = (NumericType &) *type_;

      // if unsigned largeint and value greater than largeint max,
      // cannot return exact numeric value.
      if ((t.getFSDatatype() == REC_BIN64_UNSIGNED) &&
          ((*(UInt64*)value_) > LLONG_MAX))
        return FALSE;

      // for now we can't do it for arbitrary exact numeric types, sorry
      if (NOT t.isDecimal() AND
	  NOT t.isComplexType() AND
	  NOT t.supportsSQLnull() AND
	  NOT t.getPrefixSize())
        return TRUE;
    }
  return FALSE;
}

Int64 ConstValue::getExactNumericValue(Lng32 &scale) const
{
  CMPASSERT(canGetExactNumericValue());

  Int64 result = 0;
  NumericType &t = (NumericType &) *type_;

  // for now we are looking at a binary representation of a number
  // that is either 2, 4, or 8 bytes.
  scale = t.getScale();
  CMPASSERT(t.getNominalSize() == storageSize_);
  switch (storageSize_)
    {
    case 1:
      if (t.isUnsigned())
	result = *((UInt8 *) value_);
      else
	result = *((Int8 *) value_);
      break;

    case 2:
      if (t.isUnsigned())
	result = *((unsigned short *) value_);
      else
	result = *((short *) value_);
      break;

    case 4:
      if (t.isUnsigned())
	result = uint32ToInt64(*((ULng32 *) value_));
      else
	result = *((Lng32 *) value_);
      break;

    case 8:
      if (t.isUnsigned())
        {
          if ((*(UInt64*)value_) > LLONG_MAX)
            {
              CMPASSERT(0);
            }
          else
            result = *(UInt64*)value_;
        }
      else
        result = *((Int64 *) value_);
      break;

    default:
      CMPASSERT(0);
      break;
    }

  return result;
}

NABoolean ConstValue::canGetApproximateNumericValue() const
{
  // return TRUE if this is an approximate numeric type or if we
  // can return an exact numeric value
  return (type_->getTypeQualifier() == NA_NUMERIC_TYPE &&
          ((!((NumericType *) type_)->isExact() ||
            canGetExactNumericValue())));
}

double ConstValue::getApproximateNumericValue() const
{
  CMPASSERT(canGetApproximateNumericValue());

  switch (type_->getFSDatatype())
    {
    case REC_IEEE_FLOAT32:
      return *((float *) value_);

    case REC_IEEE_FLOAT64:
      return *((double *) value_);

    default:
      {
        Int32 scale;
        double tempResult = (double) getExactNumericValue(scale);
        return tempResult * pow(10,-scale);
      }
    }
}

void ConstValue::getOffsetsInBuffer(int &nullIndOffset,
                                    int &vcLenOffset,
                                    int &dataOffset)
{
  int nextOffset = 0;

  // This uses the alignment method of the ConstVal, which is slightly
  // different from other formats, no alignment is used.
  // See also method ExpGenerator::placeConstants()
  if (type_->supportsSQLnull())
    {
      nullIndOffset = nextOffset;
      nextOffset += type_->getSQLnullHdrSize();
    }
  else
    nullIndOffset = -1;

  if (type_->isVaryingLen())
    {
      vcLenOffset = nextOffset;
      nextOffset += type_->getVarLenHdrSize();
    }
  else
    vcLenOffset = -1;

  dataOffset = nextOffset;
}

// The implementation checks for identity rather than equality,
// that is, the following method returns TRUE when the two
// ConstValues are identical in all respects except that they
// are implemented in two different storage locations.
NABoolean ConstValue::operator== (const ItemExpr& other) const	// virtual meth
{
  if (ItemExpr::operator==(other)) return TRUE;

  if (getOperatorType() != other.getOperatorType()) return FALSE;

  const ConstValue &otherConst = (const ConstValue &)other;

  // There is room for more creativity here, but it requires
  // the use of type conversion functions.

  if (type_ != otherConst.type_) return FALSE;

  if (storageSize_ != otherConst.storageSize_) return FALSE;

  // Perform a byte-by-byte comparison of the bit pattern for the value.
  if (memcmp(value_, otherConst.value_, (size_t)storageSize_)) return FALSE;

  return TRUE;
}

ConstValue * ConstValue::castToConstValue(NABoolean & negate_it)
{
  negate_it = FALSE;
  return this;
}

Int32 ConstValue::getArity() const { return 0; }

NAString ConstValue::getConstStr(NABoolean transformNeeded) const
{
  if ((*text_ == "<min>") || (*text_ == "<max>"))
    return *text_ ;

  if (getType()->getTypeQualifier() == NA_DATETIME_TYPE &&
      getType()->getPrecision() != SQLDTCODE_MPDATETIME)
  {
    return getType()->getSimpleTypeName() + " '" + *text_ + "'";
  }
  else if(getType()->getTypeQualifier() == NA_CHARACTER_TYPE)
  {
    CharType* chType = (CharType*)getType();
    NAString txt;

    if ( transformNeeded )
      txt = getText();
    else
      txt = getTextForQuery(QUERY_FORMAT);

    // if result doesn't have a charset specifier already, add one
    if (txt.index(SQLCHARSET_INTRODUCER_IN_LITERAL) == 0)
      return txt;
    else
      return chType->getCharSetAsPrefix() + txt;
  }
  else
  {
    return *text_;
  }
}

// Genesis 10-980402-1556 (see Binder)
ConstValue * ConstValue::toUpper(CollHeap *h)
{
  ConstValue *cv;

  if (isNull()) return this;                  // nothing to be done

  const CharType *typ = (const CharType *)getType();

  if (getType()->getTypeQualifier() != NA_CHARACTER_TYPE)
    return this;

  switch(typ->getCharSet())
    {
      case CharInfo::KSC5601_MP:
      case CharInfo::KANJI_MP:
        {
          // MP does not allow SQL upper/lower functions
          // to be applicable to KANJI/KSC5601 charsets.
          return this;
        }

      case CharInfo::UNICODE:
        {
          // upshift the text and put it into wcUpshift
          NAWString wcUpshift(h);
          unicode_char_set::to_upper((NAWchar *)value_,
                                     typ->getStrCharLimit(),
                                     wcUpshift);

          // create new ConstValue with the upshifted text
          cv = new (h) ConstValue(wcUpshift,
                                  typ->getCharSet(),
                                  typ->getCollation(),
                                  typ->getCoercibility());
	  cv->changeType(typ);
          break;
        }

      default:
        {
          const unsigned char *c = (const unsigned char*)(text_->data());

          // check if it's already upshifted
          for (; *c; c++)
            if (islower(*c)) break;
          if (!*c) return this;

          // upshift the text and return a new constant
          NAString upshift(*text_);
          upshift.toUpper();
          cv = new (h) ConstValue(upshift,
                                  typ->getCharSet(),
                                  typ->getCollation(),
                                  typ->getCoercibility());
          cv->changeType(typ);
          break;
        }
    }

  CMPASSERT(*typ == *cv->getType());
  return cv;
}

const NAString ConstValue::getText4CacheKey() const
{
  if(getType()->getTypeQualifier() != NA_CHARACTER_TYPE) {
    return getText();
  }
  else {
    NAString result = getText();

    // we want to return _charset'strfoo' instead of 'strfoo'.
    // This is to fix genesis case 10-040616-0347 "NF: query cache does not
    // work properly on || for certain character set". The root cause here
    // was ItemExpr::generateCacheKey() incorrectly returning the same string
    // keys for both
    //   select ?p1 || _ksc5601'arg' from ...
    //   select ?p1 || _kanji'arg from ...
    // The solution is to make them different via charset prefixes.
    if (result.index(SQLCHARSET_INTRODUCER_IN_LITERAL) != 0)
      result.prepend(((CharType*)getType())->getCharSetAsPrefix());

    return result;
  }
}

const NAString ConstValue::getTextForQuery() const
{
  if(getType()->getTypeQualifier() == NA_CHARACTER_TYPE)
    {
      NAString result("\'", CmpCommon::statementHeap());
      if (text_) result += *text_;
      RemoveTrailingZeros(result);

      result += "\'";
      return result;
    }
  else
    return *text_;
}

const NAString ConstValue::getTextForQuery(UnparseFormatEnum form) const
{
  if(getType()->getTypeQualifier() != NA_CHARACTER_TYPE ||
     textIsValidatedSQLLiteralInUTF8_)
    return *text_;

  //
  // getType()->getTypeQualifier() == NA_CHARACTER_TYPE)
  //

  NABoolean charSetConvFailed = FALSE;
  switch (form)
  {
  case QUERY_FORMAT:
  case MV_SHOWDDL_FORMAT:
  case USER_FORMAT_DELUXE:
    {
      NAString result((NAMemory *)CmpCommon::statementHeap());
      if (text_)
      {
        switch (((CharType*)getType())->getCharSet())
        {
        case CharInfo::UCS2:
          {
            // Assume that *text_ contains Unicode UCS-2/UTF-16 encoding values.
            // For SeaQuest, query text should be in Unicode UTF-8 encoding format.
            NAString *utf8Str = unicodeToChar ( (const NAWchar *)text_->data() // source
                                              , text_->length/*in_bytes*/() / BYTES_PER_NAWCHAR
                                              , CharInfo::UTF8                 // target CS
                                              , CmpCommon::statementHeap()     // heap for target
                                              );
            if (utf8Str) // Translation was successful
            {
              result += *utf8Str;
              delete utf8Str;
              utf8Str = NULL;
            }
            else // Translation failed - Assume *text_ already in UTF-8 encoding
            {
              result += *text_;
              charSetConvFailed = TRUE;
            }
          }
          break;
        case CharInfo::ISO88591:
          {
            NAString utf8String = Latin1StrToUTF8 ( *text_, CmpCommon::statementHeap() );
            if (utf8String.isNull()) // Translation failed -  Assume *text_ already in UTF-8 encoding
            {
              result += *text_;
              charSetConvFailed = TRUE;
            }
            else // Translation was successful
              result += utf8String;
          }
          break;
          // case CharInfo::SJIS:
          //   {
          //     NAString utf8Str2 = SjisStrToUTF8 ( *text_, CmpCommon::statementHeap() );
          //     if (utf8Str2.isNull()) // Translation failed -  Assume *text_ already in UTF-8 encoding
          //     {
          //       result += *text_;
          //       charSetConvFailed = TRUE;
          //     }
          //     else // Translation was successful
          //       result += utf8Str2;
          //   }
          //   break;
        default: // Assume *text_ already in UTF-8 encoding
          result += *text_;
          break;
        } // switch (((CharType*)getType())->getCharSet())

      } // if (text_)

      RemoveTrailingZeros(result);

      NAString extStrLit;
      if (result.isNull())
        extStrLit = "''";
      else if (charSetConvFailed)
      {
        extStrLit  = "'";
        extStrLit += result;
        extStrLit += "'";
      }
      else
        ToQuotedString(extStrLit/*out*/, result/*in - internalString*/, TRUE/*in - encloseInQuotes*/);

      return extStrLit;
    }
    break;

  default:
    return getTextForQuery();
    break;
  } // switch (((CharType*)getType())->getCharSet())

  return getTextForQuery(); // to keep the C++ compiler happy
}

const NAString ConstValue::getText() const
{
  if(getType()->getTypeQualifier() == NA_CHARACTER_TYPE)
    {
      NAString result(CmpCommon::statementHeap());
      if (!textIsValidatedSQLLiteralInUTF8_)
        result += "\'";
      if (text_) result += *text_;
      if (!textIsValidatedSQLLiteralInUTF8_)
        result += "\'";

      // Change imbedded NULL and \377 chars to \0 and \377
      // This comes up in key values quite often.
      size_t index;
      while((index = result.first('\0')) != NA_NPOS
	    && index != result.length())
	result(index,1) = "\\0";
      while((index = result.first('\377')) != NA_NPOS
	    && index != result.length())
	result(index,1) = "\\377";

      return result;
    }
  else
    return *text_;
}

NABoolean ConstValue::isEmptyString() const
{
  if (getType()->getTypeQualifier() == NA_CHARACTER_TYPE) {
    if (text_ && text_->length() == 0) { return TRUE; }
  }
  return FALSE;
}

void ConstValue::unparse(NAString &result,
			 PhaseEnum /*phase*/,
			 UnparseFormatEnum form,
			 TableDesc * tabId) const
{
  if (form == EXPLAIN_FORMAT)
    {
      // for EXPLAIN, abbreviate very long text values:
      // drop any repeated text from the end, and drop any text that
      // is more than 30 characters

      NAString fullText(getText(), CmpCommon::statementHeap());
      const Int32 tooLong = 30;     // keep strings shorter than this
      const Int32 shortEnough = 10; // leave strings of this length alone

      // get the full text in query text format first
      fullText = getTextForQuery(QUERY_FORMAT);

      // then truncate it if too long
      if (fullText.length() > shortEnough)
	{
	  NABoolean truncated = FALSE;
	  // the last character often is a quote and should be preserved
	  char lastchar = fullText[fullText.length()-1];

	  // more than <tooLong> characters are unlikely to convey
	  // a lot of extra info
	  if (fullText.length() > tooLong)
	    {
	      fullText.remove(tooLong);
              // if there are unprintable characters in the string,
              // remove entire escape sequences
              if (fullText.last('\\') != NA_NPOS)
                fullText.remove(fullText.last('\\'));
              truncated = TRUE;
	    }

	  // try to reduce the text even further if the information is
	  // repetitive at the end of the string
	  CollIndex len = fullText.length();

	  // skip the last character unless we have already removed it
	  if (NOT truncated)
	    len--;

          // remove repeating patterns of length 1, 2, or 4 from the end
          // of the string (patterns could be ' ', '\0', '377', etc.)
	  while (len >= 8 AND fullText(len-4,4) == fullText(len-8,4))
	    len -= 4;
	  while (len >= 4 AND fullText(len-2,2) == fullText(len-4,2))
	    len -= 2;
	  while (len >= 2 AND fullText(len-1,1) == fullText(len-2,1))
	    len -= 1;

	  // remove all the repetitive information except 3 characters
	  // but only if it's worth it (we have to add 4 extra characters
	  // to indicate the omission and want to leave 3 repeating chars...)
	  if (len+7 < fullText.length())
	    {
	      fullText.remove(len+3);
	      truncated = TRUE;
	    }

	  if (truncated)
	    {
	      fullText += " ...";
	      fullText += lastchar;
	    }
	}
      result += fullText;
    }
  else if ((form == MVINFO_FORMAT) || (form == QUERY_FORMAT) ||
           (form == MV_SHOWDDL_FORMAT) || (form == COMPUTED_COLUMN_FORMAT))
    {
    if (getType()->getTypeQualifier() == NA_CHARACTER_TYPE)
      {
        CharType* chType = (CharType*)getType();

        if (form == MVINFO_FORMAT)
          result += getText();
        else
          {
            if (!textIsValidatedSQLLiteralInUTF8_)
              result += chType->getCharSetAsPrefix();

            if ((form == MV_SHOWDDL_FORMAT) || (form == QUERY_FORMAT))
              result += getTextForQuery(form);
            else
              result += getTextForQuery();
          }
      }
    else
      {
        if (getType()->getTypeQualifier() == NA_DATETIME_TYPE &&
            !textIsValidatedSQLLiteralInUTF8_)
        {
          if (getType()->getTypeName() == "DATE")
              result += " DATE '";
          else if (getType()->getTypeName() == "TIME")
              result += " TIME '";
          else if (getType()->getTypeName() == "TIMESTAMP")
              result += " TIMESTAMP '";
        }
        result += getText();
        if (getType()->getTypeQualifier() == NA_DATETIME_TYPE &&
            !textIsValidatedSQLLiteralInUTF8_)
          result += "'";
      }
    } // MVINFO_FORMAT || QUERY_FORMAT || MV_SHOWDDL_FORMAT || COMPUTED_COLUMN_FORMAT
  else if ((form == USER_FORMAT_DELUXE) ||
	   (form == HIVE_MD_FORMAT))
    {
      if (getType()->getTypeQualifier() == NA_CHARACTER_TYPE)
        {
          // Intentionally not adding the string literal character set prefix
          // to avoid updating the regression test expected results.
          result += getTextForQuery(form);
        }
      else
        result += getText();
    }
  else
    {
      // in all other cases use the getText() method
      result += getText();
    }
}

const NAString * ConstValue::getRawText() const
{
  return text_;
}

HashValue ConstValue::topHash()
{
  HashValue result = ItemExpr::topHash();

  // hash any local data members of the derived class
  result ^= isNull();

  if (NOT isNull())
    {
      // hash binary representation of value, but no more than 10
      // bytes (diminishing return for hashing very long strings)
      Int32 maxc = MINOF(storageSize_, 10);
      for (Int32 i=0; i < maxc; i++)
	result ^= ((char *)value_)[i];
    }

  return result;
}

NABoolean ConstValue::duplicateMatch(const ItemExpr & other) const
{
  if (NOT genericDuplicateMatch(other))
    return FALSE;

  ConstValue &o = (ConstValue &) other;

  // compare any local data members of the derived class
  // and return FALSE if they don't match
  if (NOT (*type_ == *(o.type_)))
    return FALSE;

  if (isNull() != o.isNull())
    return FALSE;

  if (isNull())
    return TRUE;

  if (storageSize_ != o.storageSize_)
    return FALSE;

  if (str_cmp((char *) value_, (char *)o.value_, storageSize_) != 0 OR
      isSystemSupplied_ != o.isSystemSupplied_)
    return FALSE;

  return TRUE;
}

ItemExpr * ConstValue::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  ConstValue *result;

  if (derivedNode == NULL)
    {
      // According to the constructor that initiates isNull_ to NULL the value_
      // void pointer is set to NULL, however there are places in the code
      // like SearchKeyBounds::::computeMissingKeyValue() that creates a 
      // ConstValue with isNull set to IS_NULL and Value set to NULL
      // indicator.  So it is not right to assume that when isNULL is set
      // value will be empty.  So creating an empty ConstValue only when
      // isNULL() is true and value_ not set, otherwise we go to else
      // and call a constructor that copies isNULL_ flag along with value_
      if (isNull() && !value_)
        {
          //CMPASSERT(!value_);
          result = new (outHeap) ConstValue; // a NULL
        }
      else
        {
          /* soln:10-050710-9594 begin */
          /* Changed the constructor that is being called so that value
           * of locale_strval and locale_wstrval are not lost
           */
          result = new (outHeap) ConstValue(type_,value_,storageSize_,
                                            locale_strval, locale_wstrval,
                                            text_,outHeap, isNull_);
          
          /* soln:10-050710-9594 end */

          result->textIsValidatedSQLLiteralInUTF8_ =
            textIsValidatedSQLLiteralInUTF8_;
          result->setRebindNeeded(isRebindNeeded());
        }
    }
  else
    result = (ConstValue *) derivedNode;

  return ItemExpr::copyTopNode(result, outHeap);
}

NABoolean ConstValue::isCovered(const ValueIdSet& /* newExternalInputs */,
				const GroupAttributes& /* coveringGA */,
				ValueIdSet& /* referencedInputs */,
				ValueIdSet& /* coveredSubExpr */,
				ValueIdSet& /*unCoveredExpr*/) const
{
  // ---------------------------------------------------------------------
  // Constants are always covered
  // ---------------------------------------------------------------------
  return TRUE;
} // ConstValue::isCovered()

// ------------------------------------------------------------------------
// computeHashValues creates a hash value for a constant.
// Hash value is created only for character and numeric column types
// ------------------------------------------------------------------------
UInt32 ConstValue::computeHashValue(const NAType& columnType) 
{
  UInt32 hashValue = 0;
  switch ( getType()->getTypeQualifier() )
   {
     case NA_CHARACTER_TYPE:
       {
         UInt32 flags = ExHDPHash::NO_FLAGS;
         const CharType *cType = (CharType *)(&columnType);

         if(cType->getCharSet() == CharInfo::UNICODE) {
           flags = ExHDPHash::SWAP_TWO;
         }
     // For a case-insensitive char type, it is necessary to upper-case the 
     // boundary value first before compute the hash. This is to mimic the
     // run-time behavior where values of such char type are always 
     // upper shifted before case-insensitive comparison, being hashed or
     // encoded. Upshifting has already been done during encoding step.
         hashValue = ExHDPHash::hash((char*)(getConstValue()), flags, getStorageSize());
       }
       break;

     case NA_NUMERIC_TYPE :

       // only handle non-big NUMERICs that require 8-or-less bytes to store
       // for now.
       if ( getType()->getTypeName() == LiteralNumeric AND
            columnType.getTypeName() == LiteralNumeric AND
            columnType.getNominalSize() <= 8
          ) 
       {

         // 10-080124-0055 (Skewbuster numeric uneven distribution 
         // different scales).
         // Convert the constant to the exact NUMERIC type of the column
         // before applying the hash on it. This is necessary because for
         // example 4 bytes is sufficient to represent a small scale boundary 
         // value such as 1.0, while the storage size of the column can be 
         // 8-bytes. Without converting the number of bytes of the value to 
         // that of the column, the hashing result can be different.
         // 
         // There is still a chance that the skews are not busted when the
         // fact table side has a scale smaller than that of the dimension
         // table. For example numeric(18,2) on fact side and 
         // numeric(18, 4) on dimension side. In this case, the hash values 
         // computed for the fact table side will not match the actual 
         // values used for repartition or hashing because a CAST will be 
         // used on the fact side and repartition and hashing will use the
         // output from the CAST.

         const SQLNumeric& type = (const SQLNumeric&)(columnType);

         Lng32 len = type.getNominalSize();

         char result[8];

         // Ignore errors because the boundary value pointed by cvPtr
         // is read from the histogram table and should be have been cleared
         // off any precision or scale problems by the update histogram
         // utility.
         short retCode = convDoIt((char*)(getConstValue()),
                  getStorageSize(),
                  (short)getType()->getFSDatatype(), 
                  getType()->getPrecision(),
                  getType()->getScale(), 
                  result,
                  len, 
                  (short)(type.getFSDatatype()), 
                  type.getPrecision(), 
                  type.getScale(), 
                  NULL /* null varchar ptr*/, 0 /* varchar len*/);

         DCMPASSERT(retCode == ex_expr::EXPR_OK);

         UInt32 flags = ExHDPHash::NO_FLAGS;

         switch(type.getFSDatatype()) {
         case REC_NUM_BIG_UNSIGNED:
         case REC_NUM_BIG_SIGNED:
         case REC_BIN16_SIGNED:
         case REC_BIN16_UNSIGNED:
           flags = ExHDPHash::SWAP_TWO;
           break; 
         case REC_BIN32_SIGNED:
         case REC_BIN32_UNSIGNED:
         case REC_IEEE_FLOAT32:
           flags = ExHDPHash::SWAP_FOUR;
           break;
         case REC_BIN64_SIGNED:
         case REC_BIN64_UNSIGNED:
         case REC_IEEE_FLOAT64:
           flags = ExHDPHash::SWAP_EIGHT;
           break;
         }

         hashValue = ExHDPHash::hash(result, flags, len);
       }
       break;
 
     default:
       break;
   }
  return hashValue;
}

// -----------------------------------------------------------------------
// does the value of this constant (if char) has trailing blanks
// -----------------------------------------------------------------------
NABoolean ConstValue::valueHasTrailingBlanks()
{
   NABoolean hasATrailingBlanks = FALSE;

   if (value_ && (getType()->getTypeQualifier() == NA_CHARACTER_TYPE))
   {
      const CharType *typ = (const CharType *)getType();
      if (typ->getCharSet() == CharInfo::UNICODE)
      {
          NAWchar* nawCharVal = (NAWchar *) value_;
          Int32 bytesPerChar = (CharInfo::maxBytesPerChar)(typ->getCharSet());
          Int32 lastPos = (storageSize_/bytesPerChar)-1;
          if ((lastPos >= 0) && (nawCharVal[lastPos] == L' '))
          { 
             hasATrailingBlanks = TRUE;
          }
      }
      else
      {
          char* charVal = (char *) value_;
          Int32 lastPos = storageSize_-1;
          if ((lastPos >= 0) && (charVal[lastPos] == ' '))
          {
             hasATrailingBlanks = TRUE;
          }
          
      }
   }
   return hasATrailingBlanks;
}

QR::ExprElement ConstValue::getQRExprElem() const
{
  return QR::QRScalarValueElem;
}

// -----------------------------------------------------------------------
// member functions for class RenameCol
// -----------------------------------------------------------------------
Int32 RenameCol::getArity() const { return (child(0) ? 1 : 0); }

const NAString RenameCol::getText() const
{
  return ("rename as " + newColRefName_->getColName());
}

HashValue RenameCol::topHash()
{
  HashValue result = ItemExpr::topHash();

  // hash any local data members of the derived class
  result ^= newColRefName_->getColRefAsString();

  return result;
}

NABoolean RenameCol::duplicateMatch(const ItemExpr & other) const
{
  if (NOT genericDuplicateMatch(other))
    return FALSE;

  RenameCol &o = (RenameCol &) other;

  // compare any local data members of the derived class
  // and return FALSE if they don't match
  if (NOT (*newColRefName_ == *(o.newColRefName_)))
    return FALSE;

  return TRUE;
}

ItemExpr * RenameCol::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL)
  {
    RenameCol *newRename = new (outHeap)
      RenameCol(NULL,
		new (outHeap)
		ColRefName(newColRefName_->getColName(),
			   newColRefName_->getCorrNameObj(),
                           outHeap));
    newRename->setTargetColumnClass(getTargetColumnClass());
    result = newRename;
  }
  else
    result = derivedNode;

  return ItemExpr::copyTopNode(result, outHeap);
}

// -----------------------------------------------------------------------
// member functions for class Convert
// -----------------------------------------------------------------------
Int32 Convert::getArity() const { return 1; }

HashValue Convert::topHash()
{
  HashValue result = ItemExpr::topHash();

  // hash any local data members of the derived class

  return result;
}

ItemExpr * Convert::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  Convert *result;

  if (derivedNode == NULL)
    result = new (outHeap) Convert(NULL);
  else
    result = (Convert *) derivedNode;

  return ItemExpr::copyTopNode(result, outHeap);
}

// -----------------------------------------------------------------------
// member functions for class Assign
// -----------------------------------------------------------------------
Int32 Assign::getArity() const  { return 2; }

NABoolean Assign::isCovered(const ValueIdSet& newExternalInputs,
			    const GroupAttributes& coveringGA,
			    ValueIdSet& referencedInputs,
			    ValueIdSet& coveredSubExpr,
			    ValueIdSet& unCoveredExpr ) const
{
  // ---------------------------------------------------------------------
  // Compute the referenced input values, covered subexpressions and
  // uncovered expressions for the Assign.
  // ---------------------------------------------------------------------
  // The target is never covered
  if (coveringGA.covers(getSource(), newExternalInputs,
			referencedInputs,
			&coveredSubExpr, &unCoveredExpr))
    coveredSubExpr += getSource();

  // ---------------------------------------------------------------------
  // Regardless of whether its operands are covered, the Assignment
  // must be performed by the RelExpr with which it is associated.
  // ---------------------------------------------------------------------
  return FALSE;  // sorry, i am a special case
} // Assign::isCovered()

ItemExpr * Assign::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  Assign *result;

  if (derivedNode == NULL)
    result = new (outHeap) Assign(NULL, NULL);
  else
    result = (Assign *) derivedNode;

  return ItemExpr::copyTopNode(result, outHeap);
}

HashValue Assign::topHash()
{
  HashValue result = ItemExpr::topHash();

  // hash any local data members of the derived class

  return result;
}

// -----------------------------------------------------------------------
// member functions for class ItemList
// -----------------------------------------------------------------------
Int32 ItemList::getArity() const { return 2; }

NABoolean ItemList::isCovered
                      (const ValueIdSet& newExternalInputs,
		       const GroupAttributes& coveringGA,
		       ValueIdSet& referencedInputs,
		       ValueIdSet& coveredSubExpr,
		       ValueIdSet& unCoveredExpr) const
{
  ValueId exprId;
  NABoolean exprIsCovered = TRUE;

  NABoolean coverFlag;

  for (Lng32 i = 0; i < (Lng32)getArity(); i++)
    {
      ItemExpr *thisChild = (ItemExpr *)child(i);
      ItemExprList childList(thisChild,0);
      for (CollIndex j = 0; j < childList.entries(); j++)
	{
	  // Recurse, inserting leaf valueids into the cov/uncov sets
	  // without looking at or setting the local exprIsCovered var
	  exprId = childList[j]->getValueId();
	  coverFlag = coveringGA.covers(exprId,
					newExternalInputs,
					referencedInputs,
					&coveredSubExpr,
					&unCoveredExpr);
	  if (coverFlag)
	    coveredSubExpr += exprId;

	  exprIsCovered &= coverFlag;

	} // for j'th item in list

    } // for i'th child

  return exprIsCovered;

} // ItemList::isCovered()

ItemExpr * ItemList::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  ItemList *result;

  if (derivedNode == NULL)
    result = new (outHeap) ItemList(NULL,NULL);
  else
    result = (ItemList *) derivedNode;

  return ItemExpr::copyTopNode(result, outHeap);
}

NABoolean ItemList::duplicateMatch(const ItemExpr& other) const
{
  if (NOT genericDuplicateMatch(other))
    return FALSE;

  return TRUE;
}

NABoolean ItemList::hasEquivalentProperties(ItemExpr * other)
{
  if (other == NULL)
    return FALSE;
  if (getOperatorType() != other->getOperatorType() || 
        getArity() != other->getArity())
    return FALSE;

  ItemList * otherList = (ItemList *) other;

  return 
      (this->numOfItems() == otherList->numOfItems()) && 
      (this->constChild() == otherList->constChild()) ;
}
// -----------------------------------------------------------------------
// member functions for Subquery operators
// -----------------------------------------------------------------------
Int32 Subquery::getArity() const
{
  switch (getOperatorType())
    {
    case ITM_ROW_SUBQUERY:
    case ITM_EXISTS:
    case ITM_NOT_EXISTS:
      return 0;
    default:
      return 1;
    }
} // Subquery::getArity()

// Virtual method
NABoolean Subquery::isASubquery() const { return TRUE; }

NABoolean Subquery::isAnAnySubquery() const
{
  switch (getOperatorType())
    {
    case ITM_EQUAL_ANY:
    case ITM_NOT_EQUAL_ANY:
    case ITM_GREATER_ANY:
    case ITM_GREATER_EQ_ANY:
    case ITM_LESS_EQ_ANY:
    case ITM_LESS_ANY:
      return TRUE;
    default:
      return FALSE;
    }

} // Subquery::isAnAnySubquery()

NABoolean Subquery::isAnAllSubquery() const
{
  switch (getOperatorType())
    {
    case ITM_EQUAL_ALL:
    case ITM_NOT_EQUAL_ALL:
    case ITM_GREATER_ALL:
    case ITM_GREATER_EQ_ALL:
    case ITM_LESS_EQ_ALL:
    case ITM_LESS_ALL:
      return TRUE;
    default:
      return FALSE;
    }

} // Subquery::isAnAnySubquery()

const NAString Subquery::getText() const
{
  return "unknown subquery";
} // Subquery::getText()

void Subquery::addLocalExpr(LIST(ExprNode *) &xlist,
			    LIST(NAString) &llist) const
{
  xlist.insert(tableExpr_);
  llist.insert("Subquery");
}

NABoolean Subquery::containsSubquery()
{
  return TRUE;
} // Subquery::containsSubquery

// <aviv> BEGIN
ItemExpr *
Subquery::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  ItemExpr *result;
  if (derivedNode == NULL) {
	RelExpr* tableExprCopy = tableExpr_->copyTree(outHeap);
    result = new (outHeap) Subquery(getOperatorType(), tableExprCopy);
  }
  else
    result = derivedNode;

  ((Subquery *)result)->setAvoidHalloweenR2(getAvoidHalloweenR2());
  return ItemExpr::copyTopNode(result, outHeap);
}

// output degree functions to handle multi-output subqueries.
// Returns the number of outputs and the ItemExpr for each.
Int32 Subquery::getOutputDegree()
{
  if (!getRETDesc()) return -1; // Routine desc not set.  Error.
  else 
    return getRETDesc()->getColumnList()->entries();
}

ItemExpr *Subquery::getOutputItem(UInt32 i) 
{ 
  if (!getRETDesc()) return NULL; // Routine desc not set.  Error.
  else 
  {
    if (i < getRETDesc()->getColumnList()->entries())
      return getRETDesc()->getValueId(i).getItemExpr();
    else return NULL; // 'i' out of bounds.  Error.
  }
}
// <aviv> END


// -----------------------------------------------------------------------
// member functions for row subquery operators
// -----------------------------------------------------------------------
const NAString RowSubquery::getText() const
{
  //return "row subquery";
  NAString tmp(CmpCommon::statementHeap());
  if (getSubquery()->child(0))
    getSubquery()->child(0)->unparse(tmp);	// unparse below the subq root
  else
    getSubquery()->unparse(tmp);		// unparse the tuple
  return tmp;
}

ItemExpr *
RowSubquery::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  ItemExpr *result;
  if (derivedNode == NULL) {
	RelExpr* tableExprCopy = getSubquery()->copyTree(outHeap);
    result = new (outHeap) RowSubquery(tableExprCopy);
  }
  else
    result = derivedNode;

  return Subquery::copyTopNode(result, outHeap);
}

// -----------------------------------------------------------------------
// member functions for Quantified comparison subquery operators
// -----------------------------------------------------------------------
const NAString QuantifiedComp::getText() const
{
  switch (getOperatorType())
    {
    case ITM_EQUAL_ANY:
      return "= any";
    case ITM_NOT_EQUAL_ANY:
      return "<> any";
    case ITM_GREATER_ANY:
      return "> any";
    case ITM_GREATER_EQ_ANY:
      return ">= any";
    case ITM_LESS_EQ_ANY:
      return "<= any";
    case ITM_LESS_ANY:
      return "< any";
    case ITM_EQUAL_ALL:
      return "= all";
    case ITM_NOT_EQUAL_ALL:
      return "<> all";
    case ITM_GREATER_ALL:
      return "> all";
    case ITM_GREATER_EQ_ALL:
      return ">= all";
    case ITM_LESS_EQ_ALL:
      return "<= all";
    case ITM_LESS_ALL:
      return "< all";
    default:
      return "? any|all ";
    }

} // QuantifiedComp::getText()

// Instead of this next function, we could add a wildcard to OperatorTypeEnum
// and augment the OperatorType::match() function in ExprNode.cpp...
static NABoolean isQuantifiedComp(const ItemExpr *ie)
{
  switch (ie->getOperatorType())
    {
    case ITM_EQUAL_ANY:
    case ITM_NOT_EQUAL_ANY:
    case ITM_GREATER_ANY:
    case ITM_GREATER_EQ_ANY:
    case ITM_LESS_EQ_ANY:
    case ITM_LESS_ANY:
    case ITM_EQUAL_ALL:
    case ITM_NOT_EQUAL_ALL:
    case ITM_GREATER_ALL:
    case ITM_GREATER_EQ_ALL:
    case ITM_LESS_EQ_ALL:
    case ITM_LESS_ALL:
      return TRUE;
    default:
      return FALSE;
    }

} // isQuantifiedComp()


// <aviv> BEGIN
ItemExpr *
QuantifiedComp::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  QuantifiedComp *result;
  if (derivedNode == NULL) {
    RelExpr* tableExprCopy = getSubquery()->copyTree(outHeap);

    // NOTICE: using child(0) here is based on the Subquery and ItemExpr constructors
    //         This is bad programming !!! A solution could be to change the order of
    //		   the parameters in this ctor and using defaults (NULL), yet it involves
    //		   changes in many other places in the code <aviv>
    result = new (outHeap) QuantifiedComp(getOperatorType(),
                                          (child(0))->copyTree(outHeap),
                                          tableExprCopy,
                                          getAvoidHalloweenR2());
  }
  else
    result = (QuantifiedComp*)derivedNode;

  result->createdFromINlist_ = createdFromINlist_;
  result->createdFromALLpred_ = createdFromALLpred_;

  return Subquery::copyTopNode(result, outHeap);
}
// <aviv> END


// -----------------------------------------------------------------------
// member functions for In subquery operators
// -----------------------------------------------------------------------
const NAString InSubquery::getText() const { return "in"; }

// <aviv> BEGIN
ItemExpr *
InSubquery::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  ItemExpr *result;
  if (derivedNode == NULL) {
	RelExpr* tableExprCopy = getSubquery()->copyTree(outHeap);

	// NOTICE: using child(0) here is based on the Subquery and ItemExpr constructors
	//         This is bad programming !!! A solution could be to change the order of
	//		   the parameters in this ctor and using defaults (NULL), yet it involves
	//		   changes in many other places in the code <aviv>
    result = new (outHeap) InSubquery(getOperatorType(), (child(0))->copyTree(outHeap), tableExprCopy);
  }
  else
    result = derivedNode;

  return Subquery::copyTopNode(result, outHeap);
}
// <aviv> END


// --------------------------------------------------------------
// member functions for Abs operator
// --------------------------------------------------------------

ItemExpr * Abs::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL)
    result = new (outHeap) Abs(child(0));
  else
    result = derivedNode;

  return BuiltinFunction::copyTopNode(result, outHeap);
}

// --------------------------------------------------------------
// member functions for CodeVal operator
// --------------------------------------------------------------

ItemExpr * CodeVal::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL)
    result = new (outHeap) CodeVal(getOperatorType(), child(0));
  else
    result = derivedNode;

  return BuiltinFunction::copyTopNode(result, outHeap);
}

const NAString CodeVal::getText() const
{
  // to fix case 10-040504-4753  (Incorrect error text when using NULL as k
  // CODE_VALUE function parameter). The operator type for CodeVal is
  // NO_OPERATOR_TYPE until after the type is synthesized. getText() can be
  // called before that (e.g., in checkForSQLnullChild()).
  //
  // Use the general code_value name for such case.
  //
  if (getOperatorType() == NO_OPERATOR_TYPE )
     return "code_value";
  else
     return BuiltinFunction::getText();
}


// --------------------------------------------------------------
// member functions for AggrMinMax
// --------------------------------------------------------------

ItemExpr * AggrMinMax::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL)
    result = new (outHeap) AggrMinMax(NULL, NULL);
  else
    result = derivedNode;

  return BuiltinFunction::copyTopNode(result, outHeap);
}

// --------------------------------------------------------------
// member functions for AggrGrouping function
// --------------------------------------------------------------
ItemExpr * AggrGrouping::copyTopNode(ItemExpr * derivedNode, CollHeap* outHeap)
{
  AggrGrouping *result;

  if (derivedNode == NULL)
    result = new (outHeap) AggrGrouping(-1);
  else
    result = (AggrGrouping*)derivedNode;

  result->rollupGroupIndex_ = rollupGroupIndex_;

  return BuiltinFunction::copyTopNode(result, outHeap);
}

// -----------------------------------------------------------------------
// member functions for Exists subquery operators
// -----------------------------------------------------------------------

Exists::Exists(RelExpr  * tableExpr)
     : Subquery(ITM_EXISTS, tableExpr) {}

Exists::~Exists() {}

const NAString Exists::getText() const 
{
  if (isNotExists())
    return "not_exists";
  else
    return "exists";
}

// <aviv> BEGIN
ItemExpr *
Exists::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  ItemExpr *result;
  if (derivedNode == NULL) {
	RelExpr* tableExprCopy = getSubquery()->copyTree(outHeap);
    result = new (outHeap) Exists(tableExprCopy);
    if (isNotExists())
      result->setOperatorType(getOperatorType());
  }
  else
    result = derivedNode;

  return Subquery::copyTopNode(result, outHeap);
}
// <aviv> END


// --------------------------------------------------------------
// member functions for Between operator
// --------------------------------------------------------------
ItemExpr * Between::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL)
  {
    result = new (outHeap) Between(NULL,NULL,NULL);
    ((Between*)result)->leftBoundryIncluded_ = leftBoundryIncluded_;
    ((Between*)result)->rightBoundryIncluded_ = rightBoundryIncluded_;

    // NOTICE: we are copying the pointer, not the allocating new memory
    // and copying the object. because of this the vector must never be
    // destroyed in any destructor
    ((Between*)result)->pDirectionVector_ = pDirectionVector_;

  }
  else
    result = derivedNode;

  return BuiltinFunction::copyTopNode(result, outHeap);
}

void Between::unparse(NAString &result,
		      PhaseEnum phase,
                      UnparseFormatEnum form,
		      TableDesc * tabId) const
{
  child(0)->unparse(result,phase,form,tabId);

  result += " ";
  NAString kwd(getText(), CmpCommon::statementHeap());
  if (form == USER_FORMAT_DELUXE) kwd.toUpper();
  result += kwd;
  result += " ";

  child(1)->unparse(result,phase,form,tabId);

  kwd = " and ";
  if (form == USER_FORMAT_DELUXE) kwd.toUpper();
  result += kwd;

  child(2)->unparse(result,phase,form,tabId);
}

NABoolean Between::hasEquivalentProperties(ItemExpr * other)
{
  if (other == NULL)
    return FALSE;
  if (getOperatorType() != other->getOperatorType() || 
        getArity() != other->getArity())
    return FALSE;

  Between * tmp = (Between *) other;

  return 
    (this->leftBoundryIncluded_ == tmp->leftBoundryIncluded_) &&
    (this->rightBoundryIncluded_ == tmp->rightBoundryIncluded_ ) &&
    (this->pDirectionVector_ == tmp->pDirectionVector_);

}
// --------------------------------------------------------------
// member functions for BoolResult operator
// --------------------------------------------------------------

BoolResult::~BoolResult() {}

ItemExpr * BoolResult::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL)
    result = new (outHeap) BoolResult(NULL);
  else
    result = derivedNode;

  return BuiltinFunction::copyTopNode(result, outHeap);
}

// --------------------------------------------------------------
// member functions for BoolVal operator
// --------------------------------------------------------------
ItemExpr * BoolVal::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL)
    {
      if (getArity() == 0)
	result = new (outHeap) BoolVal(getOperatorType());
      else
	result = new (outHeap) BoolVal(getOperatorType(), NULL);
    }
  else
    result = derivedNode;

  return ItemExpr::copyTopNode(result, outHeap);
}

// --------------------------------------------------------------
// member functions for Case operator
// --------------------------------------------------------------
ItemExpr * Case::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL)
    result = new (outHeap) Case(NULL, NULL);
  else
    result = derivedNode;

  //++MV bug fix
  if (caseOperand_)
	((Case*) result)->caseOperand_ = caseOperand_->copyTree(outHeap);

  ((Case*) result)->caseOperandWasNullable_ = caseOperandWasNullable_;
  //--MV

  return BuiltinFunction::copyTopNode(result, outHeap);
}


// 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.
// Added another parameter boolean ifThenEsleExists, which would be passed
// from the parent ifThenElse to its children. This will ensure that if there
// is more than two levels of if_then_else nesting, then even the inner
// if then else is correctly fixed. Sol: 10-041025-1038
void Case::fixIfThenElse(ItemExpr * expr, ValueIdSet& coveredSubExpr, NABoolean ifThenElseExists) const
{
  if ((! expr) ||
      (expr->getOperatorType() != ITM_IF_THEN_ELSE))
    return;

  // remove expr from coveredSubExpr, if it is there
  if (coveredSubExpr.contains(expr->getValueId()))
    {
      ifThenElseExists = TRUE;
      coveredSubExpr.remove(expr->getValueId());
    }

  // and add all its children to it
  for (Lng32 index = 0; index < expr->getArity(); index++)
    {
      if (expr->child(index))
	{
	  if (expr->child(index)->getOperatorType() == ITM_IF_THEN_ELSE)
	    fixIfThenElse(expr->child(index), coveredSubExpr, ifThenElseExists);
	  else if (ifThenElseExists)
	    coveredSubExpr.insert(expr->child(index)->getValueId());
	}
    }
}

NABoolean Case::isCovered
                  (const ValueIdSet& newExternalInputs,
		   const GroupAttributes& coveringGA,
		   ValueIdSet& referencedInputs,
		   ValueIdSet& coveredSubExpr,
		   ValueIdSet& unCoveredExpr ) const
{
  ValueIdSet coveredSubExprForCase ;
  NABoolean retVal =
  BuiltinFunction::isCovered(newExternalInputs, coveringGA,
			       referencedInputs, coveredSubExprForCase,
			       unCoveredExpr);

  // The case expression is covered as a unit. Parts of a case 
  // expression must not be pushed down independently of each other
  // as this cause divide by zero type errors (if the case expression
  // has different branches for the zero and non-zero cases, see soln.
  // 10-081107-7119). We do not column references and leaf values
  // to be counted as covered if they are. We use the getLeafValuesForCoverTest
  // for this purpose. Note that Case::getLeafValuesForCoverTest() returns 
  // itself.
  const ValueIdSet emptySet;
  //coveredSubExprForCase.getLeafValuesForCoverTest(coveredSubExpr, coveringGA, emptySet);
  coveredSubExprForCase.getLeafValuesForCoverTest(coveredSubExpr, coveringGA, newExternalInputs);

  return retVal;

}

void Case::unparse(NAString &result,
		       PhaseEnum phase,
		       UnparseFormatEnum form,
		       TableDesc * tabId) const
{
  // Is this for MV use?
  if ((form != MV_SHOWDDL_FORMAT) &&
      (form != QUERY_FORMAT) &&
      (form != COMPUTED_COLUMN_FORMAT) )
  {
    // No - sorry, use the default code.
    ItemExpr::unparse(result,phase, form, tabId);
  }
  else
  {
    // Yes - avoid the parenthasis:
    // Instead of "case (when....)"
    // Do "case when ...
    result += "case";
    child(0)->unparse(result, phase, form, tabId);
  }
}

void Case::getLeafValuesForCoverTest(ValueIdSet & leafValues, 
                                     const GroupAttributes& coveringGA,
                                     const ValueIdSet & newExternalInputs) const
{
  leafValues += getValueId();
} // Case::getLeafValuesForCoverTest()

NABoolean Case::hasEquivalentProperties(ItemExpr * other)
{
  if (other == NULL)
    return FALSE;
  if (getOperatorType() != other->getOperatorType() || 
        getArity() != other->getArity())
    return FALSE;

  Case * otherCase = (Case *) other;

  return  
      (this->getCaseOperand()== otherCase->getCaseOperand()) && 
      (this->caseOperandWasNullable() == otherCase->caseOperandWasNullable());
}
// --------------------------------------------------------------
// member functions for Cast operator
// --------------------------------------------------------------

Cast::Cast(ItemExpr *val1Ptr, const NAType *type, OperatorTypeEnum otype,
	   NABoolean checkForTrunc, NABoolean noStringTrunWarnings)
  :
  CacheableBuiltinFunction(otype, 1, val1Ptr), type_(type),
  reverseDataErrorConversionFlag_(FALSE),
  flags_(0)
{
  ValueId vid = val1Ptr ? val1Ptr->getValueId() : NULL_VALUE_ID;

  checkForTruncation_ = FALSE;
  if (checkForTrunc)
    if (vid == NULL_VALUE_ID)
      checkForTruncation_ = TRUE;
    else if ( type && type->getTypeQualifier()         == NA_CHARACTER_TYPE &&
              vid.getType().getTypeQualifier() == NA_CHARACTER_TYPE )
    {
       if ( type->getNominalSize() < vid.getType().getNominalSize() )
        checkForTruncation_ = TRUE;
       else
       { // If UTF8 and *any* chance of truncation error
         // Ex: casting CHAR(8 BYTES) to CHAR(3) 
          if ( ((CharType *)type)->getCharSet() == CharInfo::UTF8  &&
               ((CharType *)type)->getStrCharLimit() < vid.getType().getNominalSize() )
          checkForTruncation_ = TRUE;
       }
    }
             
  setNoStringTruncationWarnings(noStringTrunWarnings);
}

Cast::Cast(ItemExpr *val1Ptr, ItemExpr *errorOutPtr, const NAType *type,
	   OperatorTypeEnum otype, NABoolean checkForTrunc,
           NABoolean reverseDataErrorConversionFlag,
           NABoolean noStringTrunWarnings)
  :
  CacheableBuiltinFunction(otype, 2, val1Ptr, errorOutPtr), type_(type),
  reverseDataErrorConversionFlag_(reverseDataErrorConversionFlag),
  flags_(0)
{
  checkForTruncation_ = checkForTrunc;
  setNoStringTruncationWarnings(noStringTrunWarnings);
}

Cast::~Cast() {}

ConstValue * Cast::castToConstValue(NABoolean & negate_it)
{
  return child(0)->castToConstValue(negate_it);
}

ItemExpr * Cast::foldConstants(ComDiagsArea * diagsArea,
			       NABoolean newTypeSynthesis)
{
  // Convert a cast on top of a constant into a new constant with
  // the correct type. The reason for implementing this special
  // case of constant folding is that the optimizer needs to generate
  // the actual binary representation of constants in some cases
  // (e.g. when generating the split ranges of a partitioning scheme).

  ItemExpr *result = this;

  if (child(0)->getOperatorType() == ITM_CONSTANT)
    {
      const NAType &t = child(0)->getValueId().getType();

      // simple case, the cast is unnecessary because the child
      // already has the correct type: eliminate this node
      if (t == *type_)
	return child(0);

      // try one more case, mapping of numeric data types:

    }

  return ItemExpr::foldConstants(diagsArea,newTypeSynthesis);
}

NABoolean Cast::isCovered
                   (const ValueIdSet& newExternalInputs,
		    const GroupAttributes& coveringGA,
		    ValueIdSet& referencedInputs,
		    ValueIdSet& coveredSubExpr,
		    ValueIdSet& unCoveredExpr) const
{
  NABoolean coverFlag = TRUE;
  if (coveringGA.covers(getExpr()->getValueId(),
			newExternalInputs, referencedInputs,
			&coveredSubExpr, &unCoveredExpr))
    coveredSubExpr += getExpr()->getValueId();
  else
    coverFlag = FALSE;

  if (getOperatorType() == ITM_INSTANTIATE_NULL)
    return FALSE; //
  else
    return coverFlag;
} // Cast::isCovered()

// MV -- 
// If this is a Cast over an NATypeToItem, return this ValueId instead
// of the child's. This fixes a problem with using the TupleList for the
// MVLog command.
void Cast::getLeafValuesForCoverTest(ValueIdSet & leafValues, 
                                     const GroupAttributes& coveringGA,
                                     const ValueIdSet & newExternalInputs) const
{
  if(ITM_NATYPE == child(0)->getOperatorType())
  {
    leafValues += getValueId();
  }
  else
  {
    // Otherwise - call the super class.
    BuiltinFunction::getLeafValuesForCoverTest(leafValues, coveringGA, newExternalInputs);
  }
}

ItemExpr * Cast::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL)
    {
      result = new (outHeap) Cast(NULL, type_->newCopy(outHeap),
		this->getOperatorType(), this->checkForTruncation_);

      // Fix CR 10-010426-2464: Copy other members of the class as well
      ((Cast *)result)->reverseDataErrorConversionFlag_ =
		this->reverseDataErrorConversionFlag_;

      ((Cast *)result)->flags_ = this->flags_;
    }
  else
    result = derivedNode;

  return BuiltinFunction::copyTopNode(result, outHeap);
}

ItemExpr * CastConvert::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL)
    result = new (outHeap) CastConvert(NULL, getType()->newCopy(outHeap));
  else
    result = derivedNode;

  return BuiltinFunction::copyTopNode(result, outHeap);
}

ItemExpr * CastType::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL)
    result = new (outHeap) 
      CastType(NULL, 
               (getType() ? getType()->newCopy(outHeap) : NULL));
  else
    result = derivedNode;
  
  ((CastType*)result)->makeNullable_ = makeNullable_;

  return BuiltinFunction::copyTopNode(result, outHeap);
}

NABoolean Cast::isEquivalentForCodeGeneration(const ItemExpr * other)
  {
  NABoolean rc = FALSE;        // assume failure

  if (hasBaseEquivalenceForCodeGeneration(other))
    {
    // we know that other is a Cast, and that the children are equivalent
    Cast * otherCast = (Cast *)other;
    const NAType & otherCastType = *(otherCast->type_);

    if (type_->operator==(otherCastType))
      if (checkForTruncation_ == otherCast->checkForTruncation_)
        rc = TRUE;        // the two casts can be produced by the same code
    }

  return rc;
  }

NABoolean Cast::hasEquivalentProperties(ItemExpr * other)
{
  if (other == NULL)
    return FALSE;
  if (getOperatorType() != other->getOperatorType() || 
        getArity() != other->getArity())
    return FALSE;

  Cast * tmp = (Cast *) other;
  
  return  
      (this->type_->operator == (*(tmp->type_) )) &&
      (this->checkForTruncation_ == tmp->checkForTruncation_ ) &&
      (this->reverseDataErrorConversionFlag_ == tmp->reverseDataErrorConversionFlag_ ) &&
    //      (this->noStringTruncationWarnings_ == tmp->noStringTruncationWarnings_  ) &&
      (this->flags_ == tmp->flags_);
}
// --------------------------------------------------------------
// member functions for CharFunc operator
// --------------------------------------------------------------

ItemExpr * CharFunc::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL) {
    result = new (outHeap) CharFunc(charSet_, child(0));
  }
  else
    result = derivedNode;

  return BuiltinFunction::copyTopNode(result, outHeap);
}


// --------------------------------------------------------------
// member functions for IfThenElse operator
// --------------------------------------------------------------
ItemExpr * IfThenElse::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL)
    result = new (outHeap) IfThenElse(NULL, NULL, NULL);
  else
    result = derivedNode;

  return BuiltinFunction::copyTopNode(result, outHeap);
}

NABoolean IfThenElse::isCharTypeMatchRulesRelaxable()
{
   NABoolean ok =
             child(0)->isCharTypeMatchRulesRelaxable() &&
             child(1)->isCharTypeMatchRulesRelaxable();

   if (child(2).getPtr() != NULL)
      ok = ok && child(2)->isCharTypeMatchRulesRelaxable();

   return ok;
}

void IfThenElse::unparse(NAString &result,
		       PhaseEnum phase,
		       UnparseFormatEnum form,
		       TableDesc * tabId) const
{
  // Is this for MV use?
  if ( (form != MV_SHOWDDL_FORMAT) &&
       (form != QUERY_FORMAT) &&
       (form != COMPUTED_COLUMN_FORMAT))
  {
    // No - sorry, use the default code.
    ItemExpr::unparse(result, phase, form, tabId);
  }
  else
  {
    // Instead of: case( if_then_else(cond1, op1, if_then_else(cond2, op2, op3)))
    // do this: CASE WHEN cond1 THEN op1 WHEN cond2 THEN op2 ELSE op3 END
    result += " WHEN ";
    child(0)->unparse(result, phase, form, tabId);
    result += " THEN ";
    child(1)->unparse(result, phase, form, tabId);
    // Any more nested conditions?
    if (child(2)->getOperatorType() == ITM_IF_THEN_ELSE)
    {
      // Yes - Recursive call to the next condition
      child(2)->unparse(result, phase, form, tabId);
    }
    else
    {
      // No - Do the ELSE.
      result += " ELSE ";
      child(2)->unparse(result, phase, form, tabId);
      result += " END ";
    }
  }
}

//----------------------------------------------------------------
// member functions of RaiseError operator
//----------------------------------------------------------------

RaiseError::~RaiseError() {}

const NAString RaiseError::getText() const
{
  return NAString("RaiseError(") + getConstraintName() + ")";
}

ItemExpr * RaiseError::copyTopNode (ItemExpr *derivedNode, CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL)
  {
	if (getArity() > 0) // Do we have string expressions?
	  result = new (outHeap) RaiseError(getSQLCODE(),
					    getConstraintName(),
					    child(0)->copyTree(outHeap),
					    outHeap);
	else
	  result = new (outHeap) RaiseError(getSQLCODE(),
					    getConstraintName(),
					    getTableName(),
					    outHeap);
  }
  else
    result = derivedNode;

  return BuiltinFunction::copyTopNode(result, outHeap);
}

// --------------------------------------------------------------
// member functions for Narrow operator
// --------------------------------------------------------------

Narrow::~Narrow() {}

// Note:  We simply inherit isCovered() from Cast

ItemExpr * Narrow::copyTopNode(ItemExpr *derivedNode,
			       CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL)
  {
    // Begin_Fix 10-040114-2431
    // 02/18/2004
    // changed to copy data member matchChildNullability_
    result = new (outHeap) Narrow(NULL,
                                  NULL,
                                  getType()->newCopy(outHeap),
                                  ITM_NARROW,
                                  FALSE,
                                  matchChildNullability_);
    // End_Fix 10-040114-2431

    ((Narrow*)result)->setMatchChildType(matchChildType());
  }
  else
    result = derivedNode;

  // $$$
  // $$$ shouldn't this last line instead be something like
  // $$$   Cast::copyTopNode(result, outHeap); ?!!??
  return ItemExpr::copyTopNode(result, outHeap);
}

NABoolean Narrow::hasEquivalentProperties(ItemExpr * other)
{
  if (other == NULL)
    return FALSE;
  if (getOperatorType() != other->getOperatorType() || 
        getArity() != other->getArity())
    return FALSE;

  Narrow * tmp = (Narrow *) other;

  return 
    (this->matchChildNullability_ == tmp->matchChildNullability_);

}
// -----------------------------------------------------------------------
// member functions for class InstantiateNull
// -----------------------------------------------------------------------

// ----------------------------------------------------------------------
// 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.
// ----------------------------------------------------------------------
void InstantiateNull::getLeafValuesForCoverTest(ValueIdSet & leafValues, 
                                                const GroupAttributes& coveringGA,
                                                const ValueIdSet & newExternalInputs) const
{
  leafValues += getValueId();
} // InstantiateNull::getLeafValuesForCoverTest()

ItemExpr * InstantiateNull::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL)
    result = new (outHeap)
      InstantiateNull(NULL, getType()->newCopy(outHeap));
  else
    result = derivedNode;

  ((InstantiateNull *)result)->beginLOJTransform_ = beginLOJTransform_;
  return BuiltinFunction::copyTopNode(result, outHeap);
}

NABoolean InstantiateNull::isAColumnReference( )
  { 
    if (child(0)) {
     /*  return child(0)->isAColumnReference();
     commenting this line out as it causes regression tests to fail */
      if ((child(0)->getOperatorType() != ITM_VALUEIDUNION) &&
	  (NOT child(0)->isAnAggregate()))
	  return TRUE;
    }
      return FALSE;
  }

NABoolean InstantiateNull::hasEquivalentProperties(ItemExpr * other)
{
  if (other == NULL)
    return FALSE;
  if (getOperatorType() != other->getOperatorType() || 
        getArity() != other->getArity())
    return FALSE;

  InstantiateNull * tmp = (InstantiateNull *) other;

  return  
    (this->NoCheckforLeftToInnerJoin == tmp->NoCheckforLeftToInnerJoin ) &&
    (this->beginLOJTransform_ == tmp->beginLOJTransform_ );
}

// InstantiateNull is never equivalent to another instance.  Even when
// two instances are similar, they cannot be considered equivalent
// since they may have come from different outer joins.  The
// InstantiateNull ItemExpr operates in the context of a join, but
// this is not recorded in the data members of the class.
NABoolean InstantiateNull::isEquivalentForCodeGeneration(const ItemExpr * other)
{
  return FALSE;
}



// --------------------------------------------------------------
// member functions for BitOperFunc operator
// --------------------------------------------------------------
Int32 BitOperFunc::getArity() const
{
  if (child(0) == NULL)
    return 0;
  else if (child(1) == NULL)
    return 1;
  else if (child(2) == NULL)
    return 2;
  else
    return 3;
}

ItemExpr * BitOperFunc::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL)
    result = new (outHeap) BitOperFunc(getOperatorType(), NULL,NULL);
  else
    result = derivedNode;

  return BuiltinFunction::copyTopNode(result, outHeap);
}

const NAString BitOperFunc::getText() const
{
  switch (getOperatorType())
    {
    case ITM_BITAND:       return "bitand";
    case ITM_BITOR:        return "bitor";
    case ITM_BITXOR:       return "bitxor";
    case ITM_BITNOT:       return "bitnot";
    case ITM_BITEXTRACT:   return "bitextract";
    default:
      return "unknown bit func";
    } // switch
}

// --------------------------------------------------------------
// member functions for CompEncode operator
// --------------------------------------------------------------

CompEncode::~CompEncode() {}

ItemExpr * CompEncode::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL)
    result = new (outHeap) CompEncode(NULL, 
                                      descFlag_, 
                                      length_,
                                      collationType_,
                                      regularNullability_,
                                      outHeap);
  else
    result = derivedNode;

  ((CompEncode *) result)->caseinsensitiveEncode_ = caseinsensitiveEncode_;
  ((CompEncode *) result)->encodedCollation_ = encodedCollation_;

  return BuiltinFunction::copyTopNode(result, outHeap);
}

Lng32  CompEncode::getEncodedLength(  const CharInfo::Collation collation,
				  const CollationInfo::CollationType ct,
				  const Lng32 srcLength,
				  const NABoolean nullable)
{
  CMPASSERT(CollationInfo::isSystemCollation(collation));
    	
  Int32 nPasses= CollationInfo::getCollationNPasses(collation);

  switch (ct)
  {
    case CollationInfo::Sort:
    {
      return nPasses *  (srcLength + 1 ) +  
	      (nullable? ExpTupleDesc::KEY_NULL_INDICATOR_LENGTH: 0 )  ;
    }
    case CollationInfo::Compare:
    {
	return nPasses * (srcLength + 1 ) ;
    }
    case CollationInfo::Search:
    {
      return nPasses * srcLength;
    }
    default:
    {
	    CMPASSERT(0);
	    return NULL;
    }
  }
}

// --------------------------------------------------------------
// member functions for CompDecode operator
// --------------------------------------------------------------

CompDecode::~CompDecode() {}

ItemExpr * CompDecode::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL)
    result = new (outHeap) CompDecode(NULL,
                                      unencodedType_->newCopy(outHeap),
                                      descFlag_,
				      length_,
                                      collationType_,
				      regularNullability_,
                                      outHeap);
  else
    result = derivedNode;

  return CompEncode::copyTopNode(result, outHeap);
}


// --------------------------------------------------------------
// member functions for LOBoper operator
// --------------------------------------------------------------
ItemExpr * LOBoper::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  LOBoper *result;

  if (derivedNode == NULL)
    result = new (outHeap) LOBoper(getOperatorType(), NULL, NULL, NULL,obj_);
  else
    result = (LOBoper*)derivedNode;

  result->lobNum() = lobNum();
  result->lobStorageType() = lobStorageType();
  result->lobStorageLocation() = lobStorageLocation();

  return BuiltinFunction::copyTopNode(result, outHeap);
}

ItemExpr * LOBinsert::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  LOBinsert *result;

  if (derivedNode == NULL)
    result = new (outHeap) LOBinsert(NULL, NULL, obj_, append_);
  else
    result = (LOBinsert*)derivedNode;

  result->insertedTableObjectUID() = insertedTableObjectUID();
  result->insertedTableSchemaName() = insertedTableSchemaName();
  //  result->lobNum() = lobNum();
  result->lobSize() = lobSize();
  result->lobFsType() = lobFsType();

  return LOBoper::copyTopNode(result, outHeap);
}

ItemExpr * LOBselect::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL)
    result = new (outHeap) LOBselect(NULL, NULL, obj_);
  else
    result = derivedNode;

  return LOBoper::copyTopNode(result, outHeap);
}

ItemExpr * LOBdelete::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL)
    result = new (outHeap) LOBdelete(NULL);
  else
    result = derivedNode;

  return LOBoper::copyTopNode(result, outHeap);
}

ItemExpr * LOBupdate::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  LOBupdate *result;

  if (derivedNode == NULL)
    result = new (outHeap) LOBupdate(NULL, NULL, NULL,obj_, append_);
  else
    result = (LOBupdate*)derivedNode;

  result->updatedTableObjectUID() = updatedTableObjectUID();
  result->updatedTableSchemaName() = updatedTableSchemaName();

  return LOBoper::copyTopNode(result, outHeap);
}
/*
Int32 LOBupdate::getArity() const
{
  if (obj_ == EMPTY_LOB_)
    return 0;
  else
    return getNumChildren();
}
*/
ItemExpr * LOBconvert::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL)
    result = new (outHeap) LOBconvert(NULL,obj_,tgtSize_);
  else
    result = derivedNode;

  return LOBoper::copyTopNode(result, outHeap);
}

ItemExpr * LOBconvertHandle::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL)
    result = new (outHeap) LOBconvertHandle(NULL, obj_);
  else
    result = derivedNode;

  return LOBoper::copyTopNode(result, outHeap);
}

ItemExpr * LOBextract::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL)
    result = new (outHeap) LOBextract(NULL, tgtSize_);
  else
    result = derivedNode;

  return LOBoper::copyTopNode(result, outHeap);
}


// --------------------------------------------------------------
// member functions for Concat operator
// --------------------------------------------------------------
ItemExpr * Concat::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL)
    result = new (outHeap) Concat(NULL, NULL);
  else
    result = derivedNode;

  return BuiltinFunction::copyTopNode(result, outHeap);
}

// --------------------------------------------------------------
// member functions for Format operator
// --------------------------------------------------------------

Format::~Format() {}

ItemExpr * Format::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  Format *result;

  if (derivedNode == NULL)
    result = new (outHeap) Format(NULL, formatStr_, formatCharToDate_);
  else
    result = (Format*)derivedNode;

  result->formatCharToDate_ = formatCharToDate_;
  result->formatType_ = formatType_;

  return BuiltinFunction::copyTopNode(result, outHeap);
}

// --------------------------------------------------------------
// member functions for Hash operator
// --------------------------------------------------------------

ItemExpr * Hash::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL)
    result = new (outHeap) Hash(NULL);
  else
    result = derivedNode;

  return BuiltinFunction::copyTopNode(result, outHeap);
}

// --------------------------------------------------------------
// member functions for HashComp operator
// --------------------------------------------------------------

HashComb::~HashComb() {}

ItemExpr * HashComb::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL)
    result = new (outHeap) HashComb(NULL,NULL);
  else
    result = derivedNode;

  return BuiltinFunction::copyTopNode(result, outHeap);
}

// --------------------------------------------------------------
// member functions for HashDistPartHash operator
// 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.
//--------------------------------------------------------------
HashDistPartHash::~HashDistPartHash() {}

ItemExpr *
HashDistPartHash::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL)
    result = new (outHeap) HashDistPartHash(NULL);
  else
    result = derivedNode;

  return BuiltinFunction::copyTopNode(result, outHeap);
}

// --------------------------------------------------------------
// member functions for HashDistPartHashComp operator
// 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.
// --------------------------------------------------------------

HashDistPartHashComb::~HashDistPartHashComb() {}

ItemExpr *
HashDistPartHashComb::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL)
    result = new (outHeap) HashDistPartHashComb(NULL,NULL);
  else
    result = derivedNode;

  return BuiltinFunction::copyTopNode(result, outHeap);
}

// --------------------------------------------------------------
// member functions for HiveFunc operator
// --------------------------------------------------------------
ItemExpr * HiveHash::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL)
    result = new (outHeap) HiveHash(NULL);
  else
    result = derivedNode;

  return BuiltinFunction::copyTopNode(result, outHeap);
}

// --------------------------------------------------------------
// member functions for HiveHashComb operator
// --------------------------------------------------------------
ItemExpr * HiveHashComb::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL)
    result = new (outHeap) HiveHashComb(NULL,NULL);
  else
    result = derivedNode;

  return BuiltinFunction::copyTopNode(result, outHeap);
}



// --------------------------------------------------------------
// member functions for MathFunc operator
// --------------------------------------------------------------
Int32 MathFunc::getArity() const
{
  if (child(0) == NULL)
    return 0;
  else if (child(1) == NULL)
    return 1;
  else
    return 2;
}

ItemExpr * MathFunc::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL)
    result = new (outHeap) MathFunc(getOperatorType(), NULL,NULL);
  else
    result = derivedNode;

  return BuiltinFunction::copyTopNode(result, outHeap);
}

const NAString MathFunc::getText() const
{
  switch (getOperatorType())
    {
    case ITM_ABS:          return "abs";
    case ITM_ACOS:         return "acos";
    case ITM_ASIN:         return "asin";
    case ITM_ATAN:         return "atan";
    case ITM_ATAN2:        return "atan2";
    case ITM_CEIL:         return "ceiling";
    case ITM_COS:          return "cos";
    case ITM_COSH:         return "cosh";
    case ITM_DEGREES:      return "degrees";
    case ITM_EXP:          return "exp";
    case ITM_EXPONENT:     return "'**'";
    case ITM_FLOOR:        return "floor";
    case ITM_LOG:          return "log";
    case ITM_LOG10:        return "log10";
    case ITM_LOG2:         return "log2";
    case ITM_PI:           return "pi";
    case ITM_POWER:        return "power";
    case ITM_RADIANS:      return "radians";
    case ITM_ROUND:        return "round";
    case ITM_SCALE_TRUNC:  return "truncate";
    case ITM_SIN:          return "sin";
    case ITM_SINH:         return "sinh";
    case ITM_SQRT:         return "sqrt";
    case ITM_TAN:          return "tan";
    case ITM_TANH:         return "tanh";

    default:
      return "unknown math func";
    } // switch
}

// --------------------------------------------------------------
// member functions for Modulus operator
// --------------------------------------------------------------

Modulus::~Modulus() {}

ItemExpr * Modulus::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL)
    result = new (outHeap) Modulus(NULL,NULL);
  else
    result = derivedNode;

  return BuiltinFunction::copyTopNode(result, outHeap);
}

// --------------------------------------------------------------
// member functions for Repeat operator
// --------------------------------------------------------------

ItemExpr * Repeat::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL)
    result = new (outHeap) Repeat(NULL, NULL);
  else
    result = derivedNode;
  
  ((Repeat *) result)->setMaxLength(getMaxLength());
  ((Repeat *) result)->maxLengthWasExplicitlySet_ = maxLengthWasExplicitlySet_;

  return BuiltinFunction::copyTopNode(result, outHeap);
}

// --------------------------------------------------------------
// member functions for Replace operator
// --------------------------------------------------------------

ItemExpr * Replace::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL)
    result = new (outHeap) Replace(NULL, NULL, NULL);
  else
    result = derivedNode;

  return BuiltinFunction::copyTopNode(result, outHeap);
}

// --------------------------------------------------------------
// member functions for ReplaceNull operator
// --------------------------------------------------------------

ItemExpr * ReplaceNull::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL)
    result = new (outHeap) ReplaceNull(NULL, NULL, NULL);
  else
    result = derivedNode;

  return BuiltinFunction::copyTopNode(result, outHeap);
}

// --------------------------------------------------------------
// member functions for HashDistrib operator
// --------------------------------------------------------------

HashDistrib::~HashDistrib() {}

ItemExpr * HashDistrib::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  CMPASSERT (derivedNode != NULL);

  return BuiltinFunction::copyTopNode(derivedNode, outHeap);
}

// --------------------------------------------------------------
// member functions for Hash2Distrib operator
// --------------------------------------------------------------

Hash2Distrib::~Hash2Distrib() {}

ItemExpr * Hash2Distrib::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL)
    result = new (outHeap) Hash2Distrib(NULL,NULL);
  else
    result = derivedNode;

  return HashDistrib::copyTopNode(result, outHeap);
}

// --------------------------------------------------------------
// member functions for ProgDistrib operator
// --------------------------------------------------------------

ProgDistrib::~ProgDistrib() {}

ItemExpr * ProgDistrib::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL)
    result = new (outHeap) ProgDistrib(NULL,NULL);
  else
    result = derivedNode;

  return HashDistrib::copyTopNode(result, outHeap);
}

// --------------------------------------------------------------
// member functions for ProgDistribKey operator
// --------------------------------------------------------------

ProgDistribKey::~ProgDistribKey() {}

ItemExpr *
ProgDistribKey::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL)
    result = new (outHeap) ProgDistribKey(NULL,NULL,NULL);
  else
    result = derivedNode;

  return BuiltinFunction::copyTopNode(result, outHeap);
}

// --------------------------------------------------------------
// member functions for PAGroup operator
// --------------------------------------------------------------

PAGroup::~PAGroup() {}

ItemExpr * PAGroup::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL)
    result = new (outHeap) PAGroup(NULL,NULL, NULL);
  else
    result = derivedNode;

  return BuiltinFunction::copyTopNode(result, outHeap);
}

// --------------------------------------------------------------
// member functions for InverseOrder operator
// --------------------------------------------------------------

ItemExpr * InverseOrder::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL)
    result = new (outHeap) InverseOrder(NULL);
  else
    result = derivedNode;

  return BuiltinFunction::copyTopNode(result, outHeap);
}

// --------------------------------------------------------------
// member functions for In operator
// --------------------------------------------------------------
ItemExpr * In::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL)
    result = new (outHeap) In(NULL, NULL);
  else
    result = derivedNode;

  return BuiltinFunction::copyTopNode(result, outHeap);
}
// --------------------------------------------------------------
// member functions for NATypeToItem operator
// --------------------------------------------------------------
Int32 NATypeToItem::getArity() const { return 0; }
const NAString NATypeToItem::getText() const
{  return natype_pointer->getTypeSQLname(TRUE); }

ItemExpr * NATypeToItem::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL)
    result = new (outHeap) NATypeToItem( natype_pointer );
  else
    result = derivedNode;

  return ItemExpr::copyTopNode(result, outHeap);
}

// --------------------------------------------------------------
// member functions for NamedTypeToItem operator
// --------------------------------------------------------------

ItemExpr* NamedTypeToItem::copyTopNode(ItemExpr *derivedNode, CollHeap *outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL)
    result = new (outHeap) NamedTypeToItem(name_.data(),
                                           natype_pointer,
                                           outHeap);
  else
    result = derivedNode;

  return NATypeToItem::copyTopNode(result, outHeap);
}

const NAString NamedTypeToItem::getText() const
{
  return name_;
}

// --------------------------------------------------------------
// member functions for NoOp operator
// --------------------------------------------------------------

NoOp::~NoOp() {}

ItemExpr * NoOp::copyTopNode(ItemExpr * derivedNode, CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL)
    result = new (outHeap) NoOp(NULL);
  else
    result = derivedNode;

  return BuiltinFunction::copyTopNode(result, outHeap);
}


// -----------------------------------------------------------------------
// member functions for class RandomNum
// -----------------------------------------------------------------------

RandomNum::~RandomNum() {}

ItemExpr * RandomNum::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL)
    result = new (outHeap) RandomNum(NULL, simpleRandom_);
  else
    result = derivedNode;

  return BuiltinFunction::copyTopNode(result, outHeap);

} // RandomNum::copyTopNode()

// MV, 
// -----------------------------------------------------------------------
// member functions for class GenericUpdateOutputFunction
// -----------------------------------------------------------------------
ItemExpr * GenericUpdateOutputFunction::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL)
    result = new (outHeap) GenericUpdateOutputFunction(getOperatorType());
  else
    result = derivedNode;

  return BuiltinFunction::copyTopNode(result, outHeap);

} // GenericUpdateOutputFunction::copyTopNode()

// Triggers - 
// -----------------------------------------------------------------------
// member functions for class InternalTimestamp
// -----------------------------------------------------------------------
InternalTimestamp::~InternalTimestamp() {}

ItemExpr * InternalTimestamp::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL)
    result = new (outHeap) InternalTimestamp();
  else
    result = derivedNode;

  return BuiltinFunction::copyTopNode(result, outHeap);

} // Timestamp::copyTopNode()
//++Triggers, 

// -----------------------------------------------------------------------
// member functions for class UniqueExecuteId
// -----------------------------------------------------------------------

UniqueExecuteId::~UniqueExecuteId() {}

ItemExpr * UniqueExecuteId::copyTopNode(ItemExpr *derivedNode,
					 CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL)
    result = new (outHeap) UniqueExecuteId();
  else
    result = derivedNode;

  return BuiltinFunction::copyTopNode(result,outHeap);

} // UniqueExecuteId::copyTopNode()


// -----------------------------------------------------------------------
// member functions for class GetTriggersStatus
// -----------------------------------------------------------------------
GetTriggersStatus::~GetTriggersStatus() {}

ItemExpr * GetTriggersStatus::copyTopNode(ItemExpr *derivedNode,
										  CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL)
    result = new (outHeap) GetTriggersStatus();
  else
    result = derivedNode;

  return BuiltinFunction::copyTopNode(result,outHeap);

} // GetTriggersStatus::copyTopNode()

// -----------------------------------------------------------------------
// member functions for GetBitValueAt
// -----------------------------------------------------------------------
GetBitValueAt::~GetBitValueAt() {}

ItemExpr * GetBitValueAt::copyTopNode(ItemExpr *derivedNode,
									  CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL)
  {
    result = new (outHeap) GetBitValueAt(child(0), child(1));
  }
  else
    result = derivedNode;

  return BuiltinFunction::copyTopNode(result, outHeap);

} // GetBitValueAt::copyTopNode()

//--Triggers, 

//++MV, 
// -----------------------------------------------------------------------
// member functions for IsBitwiseAndTrue
// -----------------------------------------------------------------------
IsBitwiseAndTrue::~IsBitwiseAndTrue() {}

ItemExpr * IsBitwiseAndTrue::copyTopNode(ItemExpr *derivedNode,
					 CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL)
  {
    result = new (outHeap) IsBitwiseAndTrue(child(0), child(1));
  }
  else
    result = derivedNode;

  return BuiltinFunction::copyTopNode(result, outHeap);

} // IsBitwiseAndTrue::copyTopNode()

//--MV, 


// -----------------------------------------------------------------------
// member functions for class Mask
// -----------------------------------------------------------------------

Mask::~Mask() {}

ItemExpr * Mask::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL)
    result = new (outHeap) Mask(ITM_MASK_SET, NULL, NULL);
  else
    result = derivedNode;

  return BuiltinFunction::copyTopNode(result, outHeap);

} // Mask::copyTopNode()

// -----------------------------------------------------------------------
// member functions for class Shift
// -----------------------------------------------------------------------

Shift::~Shift() {}

ItemExpr * Shift::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL)
    result = new (outHeap) Shift(ITM_SHIFT_RIGHT, NULL, NULL);
  else
    result = derivedNode;

  return BuiltinFunction::copyTopNode(result, outHeap);

} // Shift::copyTopNode()

// -----------------------------------------------------------------------
// member functions for class AnsiUSERFunction
// -----------------------------------------------------------------------
AnsiUSERFunction::~AnsiUSERFunction() {}

NABoolean AnsiUSERFunction::isAUserSuppliedInput() const	{ return TRUE; }

ItemExpr * AnsiUSERFunction::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL)
    result = new (outHeap) AnsiUSERFunction(getOperatorType());
  else
    result = derivedNode;

  return BuiltinFunction::copyTopNode(result, outHeap);

} // AnsiUSERFunction::copyTopNode()

// -----------------------------------------------------------------------
// member functions for class MonadicUSERFunction
// -----------------------------------------------------------------------
MonadicUSERFunction::~MonadicUSERFunction() {}

NABoolean MonadicUSERFunction::isAUserSuppliedInput() const	{ return TRUE; }

ItemExpr * MonadicUSERFunction::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL)
    result = new (outHeap) MonadicUSERFunction(child(0));
  else
    result = derivedNode;

  return BuiltinFunction::copyTopNode(result, outHeap);

} // MonadicUSERFunction::copyTopNode()

NABoolean MonadicUSERFunction::isCovered
                   (const ValueIdSet& newExternalInputs,
		    const GroupAttributes& coveringGA,
		    ValueIdSet& referencedInputs,
		    ValueIdSet& coveredSubExpr,
		    ValueIdSet& unCoveredExpr) const
{
  // If the argument of USER function is not a constant then it can be
  // evaluated anywhere in the tree. So check for its coverage
  ValueIdSet localSubExpr;
  for (Lng32 i = 0; i < (Lng32)getArity(); i++)
    {
      if ( coveringGA.covers(child(i)->getValueId(),
			     newExternalInputs,
			     referencedInputs,
			     &localSubExpr) )
	{
	  coveredSubExpr += child(i)->getValueId();
	}
    }

  // The USER function is not pushed down.

  return FALSE;

} // MonadicUSERFunction::isCovered

// -----------------------------------------------------------------------
// member functions for class MonadicUSERIDFunction
// -----------------------------------------------------------------------
MonadicUSERIDFunction::~MonadicUSERIDFunction() {}

ItemExpr * MonadicUSERIDFunction::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL)
    result = new (outHeap) MonadicUSERIDFunction(child(0));
  else
    result = derivedNode;

  return BuiltinFunction::copyTopNode(result, outHeap);

} // MonadicUSERIDFunction::copyTopNode()



// -----------------------------------------------------------------------
// member functions for class Translate
// -----------------------------------------------------------------------
Translate::Translate(ItemExpr *valPtr, NAString* map_table_name)
: CacheableBuiltinFunction(ITM_TRANSLATE, 1, valPtr)
{

  if ( _strcmpi(map_table_name->data(), "UNICODE_TO_SJIS") == 0 ||
       _strcmpi(map_table_name->data(), "UTOSJ") == 0
     )
    map_table_id_ = Translate::UNICODE_TO_SJIS;
  else
    if ( _strcmpi(map_table_name->data(), "UCS2TOSJIS") == 0)
      map_table_id_ = Translate::UCS2_TO_SJIS;
    else
      if ( _strcmpi(map_table_name->data(), "UCS2TOUTF8") == 0)
        map_table_id_ = Translate::UCS2_TO_UTF8;
      else
        if ( _strcmpi(map_table_name->data(), "UCS2TOISO88591") == 0 )
          map_table_id_ = Translate::UNICODE_TO_ISO88591;
        else
          if ( _strcmpi(map_table_name->data(), "SJIS_TO_UNICODE") == 0 ||
               _strcmpi(map_table_name->data(), "SJTOU") == 0
            )
            map_table_id_ = Translate::SJIS_TO_UNICODE;
          else
            if ( _strcmpi(map_table_name->data(), "SJISTOUCS2") == 0)
              map_table_id_ = Translate::SJIS_TO_UCS2;
            else
              if ( _strcmpi(map_table_name->data(), "UTF8TOUCS2") == 0 )
                map_table_id_ = Translate::UTF8_TO_UCS2;
              else
                if ( _strcmpi(map_table_name->data(), "ISO88591TOUCS2") == 0 )
                  map_table_id_ = Translate::ISO88591_TO_UNICODE;

  else if ( _strcmpi(map_table_name->data(), "ISO88591TOUTF8") == 0 )
    map_table_id_ = Translate::ISO88591_TO_UTF8;
  else if ( _strcmpi(map_table_name->data(), "UTF8TOISO88591") == 0 )
    map_table_id_ = Translate::UTF8_TO_ISO88591;
  else if ( _strcmpi(map_table_name->data(), "SJISTOUTF8") == 0 )
    map_table_id_ = Translate::SJIS_TO_UTF8;
  else if ( _strcmpi(map_table_name->data(), "UTF8TOSJIS") == 0 )
    map_table_id_ = Translate::UTF8_TO_SJIS;
  else if ( _strcmpi(map_table_name->data(), "GBKTOUTF8") == 0 )
    map_table_id_ = Translate::GBK_TO_UTF8;

                else
                  if ( _strcmpi(map_table_name->data(), "KANJITOISO88591") == 0 )
                    map_table_id_ = Translate::KANJI_MP_TO_ISO88591;
                  else
                    if ( _strcmpi(map_table_name->data(), "KSC5601TOISO88591") == 0 )
                      map_table_id_ = Translate::KSC5601_MP_TO_ISO88591;
                    else
                      map_table_id_ = UNKNOWN_TRANSLATION;

  allowsSQLnullArg() = FALSE;
}

Translate::Translate(ItemExpr *valPtr, Int32 map_table_id)
       : CacheableBuiltinFunction(ITM_TRANSLATE, 1, valPtr)
{
    map_table_id_ = map_table_id;
    allowsSQLnullArg() = FALSE;
}

ItemExpr * Translate::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL)
    result = new (outHeap) Translate(child(0), getTranslateMapTableId());
  else
    result = derivedNode;

  return BuiltinFunction::copyTopNode(result, outHeap);

} // Translate::copyTopNode()


// do not know why. But if this function is put inside Translate's
// class definition, cl.exe aborts with the following info:
// cl.exe ... sooutput.cpp
//../rogue\rw/locale.h(243) : fatal error C1001: INTERNAL COMPILER ERROR
//                (compiler file 'msc1.cpp', line 1188)
//    Please choose the Technical Support command on the Visual C++
//    Help menu, or open the Technical Support help file for more information
NABoolean Translate::isCharTypeMatchRulesRelaxable()
{
  return child(0)->isCharTypeMatchRulesRelaxable();
}

void Translate::unparse(NAString &result,
                        PhaseEnum phase,
                        UnparseFormatEnum form,
                        TableDesc* tabId) const
{
  if (CmpCommon::getDefault(MVQR_LOG_QUERY_DESCRIPTORS) != DF_DUMP_MV)
    return CacheableBuiltinFunction::unparse(result, phase, form, tabId);
  else
  {
    result += "translate(";
    child(0)->unparse(result, phase, form, tabId);
    result += " using ";
    NAString translation;
    switch (map_table_id_)
    {
      case UNICODE_TO_SJIS         : translation="UCS2_TO_SJIS";        break;
      case UNICODE_TO_ISO88591     : translation="UCS2TOISO88591";      break;
      case ISO88591_TO_UNICODE     : translation="ISO88591TOUCS2";      break;
      case SJIS_TO_UNICODE         : translation="SJIS_TO_UCS2";        break;
      case UCS2_TO_SJIS            : translation="UCS2TOSJIS";          break;
      case SJIS_TO_UCS2            : translation="SJISTOUCS2";          break;
      case UCS2_TO_UTF8            : translation="UCS2TOUTF8";          break;
      case UTF8_TO_UCS2            : translation="UTF8TOUCS2";          break;
      case UTF8_TO_SJIS            : translation="UTF8TOSJIS";          break;
      case SJIS_TO_UTF8            : translation="SJISTOUTF8";          break;
      case UTF8_TO_ISO88591        : translation="UTF8TOISO88591";      break;
      case ISO88591_TO_UTF8        : translation="ISO88591TOUTF8";      break;
      case KANJI_MP_TO_ISO88591    : translation="KANJITOISO88591";     break;
      case KSC5601_MP_TO_ISO88591  : translation="KSC5601TOISO88591";   break;
      case UNKNOWN_TRANSLATION     : translation="UNKNOWN_TRANSLATION"; break;                                                  
    }
    result += translation;
    result += ")";
  }                                               
}                                                 
                                                  
HbaseColumnLookup::~HbaseColumnLookup()
{
}

ItemExpr * HbaseColumnLookup::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL)
    result = new (outHeap) HbaseColumnLookup(child(0), hbaseCol_, naType_);
  else
    result = derivedNode;

  return BuiltinFunction::copyTopNode(result, outHeap);

} // HbaseColumnLookup::copyTopNode()
                                                  
HbaseColumnsDisplay::~HbaseColumnsDisplay()
{
}

ItemExpr * HbaseColumnsDisplay::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL)
    result = new (outHeap) HbaseColumnsDisplay(child(0), csl_, displayWidth_);
  else
    result = derivedNode;

  return BuiltinFunction::copyTopNode(result, outHeap);

} // HbaseColumnsDisplay::copyTopNode()

HbaseColumnCreate::~HbaseColumnCreate()
{
}

ItemExpr * HbaseColumnCreate::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  HbaseColumnCreate *result;

  if (derivedNode == NULL)
    result = new (outHeap) HbaseColumnCreate(hccol_);
  else
    result = (HbaseColumnCreate*)derivedNode;

  result->colNameMaxLen_ = colNameMaxLen_;
  result->colValMaxLen_ = colValMaxLen_;

  return BuiltinFunction::copyTopNode(result, outHeap);

} // HbaseColumnLookup::copyTopNode()
                                                  
SequenceValue::~SequenceValue()
{
}

ItemExpr * SequenceValue::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  SequenceValue *result;

  if (derivedNode == NULL)
    result = new (outHeap) SequenceValue(seqCorrName_, currVal_, nextVal_);
  else
    result = (SequenceValue*)derivedNode;

  result->naTable_ = naTable_;

  return BuiltinFunction::copyTopNode(result, outHeap);

} // SequenceValue::copyTopNode()
        
// HbaseTimestamp                                          
HbaseTimestamp::~HbaseTimestamp()
{
}

ItemExpr * HbaseTimestamp::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  HbaseTimestamp *result;

  if (derivedNode == NULL)
    result = new (outHeap) HbaseTimestamp(col_);
  else
    result = (HbaseTimestamp*)derivedNode;

  result->colIndex_ = colIndex_;
  result->colName_ = colName_;
  result->tsVals_ = tsVals_;

  return BuiltinFunction::copyTopNode(result, outHeap);
} // HbaseTimestamp::copyTopNode()
  
// HbaseTimestampRef                                          
HbaseTimestampRef::~HbaseTimestampRef()
{
}

ItemExpr * HbaseTimestampRef::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  HbaseTimestampRef *result;

  if (derivedNode == NULL)
    result = new (outHeap) HbaseTimestampRef(col_);
  else
    result = (HbaseTimestampRef*)derivedNode;

  return BuiltinFunction::copyTopNode(result, outHeap);
} // HbaseTimestamp::copyTopNode()
  
NABoolean HbaseTimestamp::isCovered
(const ValueIdSet& newExternalInputs,
 const GroupAttributes& coveringGA,
 ValueIdSet& referencedInputs,
 ValueIdSet& coveredSubExpr,
 ValueIdSet& unCoveredExpr) const
{
  //return TRUE;
  return FALSE;
}

// HbaseVersion                                          
HbaseVersion::~HbaseVersion()
{
}

ItemExpr * HbaseVersion::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  HbaseVersion *result;

  if (derivedNode == NULL)
    result = new (outHeap) HbaseVersion(col_);
  else
    result = (HbaseVersion*)derivedNode;

  result->colIndex_ = colIndex_;
  result->colName_ = colName_;
  result->tsVals_ = tsVals_;

  return BuiltinFunction::copyTopNode(result, outHeap);
} // HbaseVersion::copyTopNode()
  
// HbaseVersionRef                                          
HbaseVersionRef::~HbaseVersionRef()
{
}

ItemExpr * HbaseVersionRef::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  HbaseVersionRef *result;

  if (derivedNode == NULL)
    result = new (outHeap) HbaseVersionRef(col_);
  else
    result = (HbaseVersionRef*)derivedNode;

  return BuiltinFunction::copyTopNode(result, outHeap);
} // HbaseVersion::copyTopNode()
  
NABoolean HbaseVersion::isCovered
(const ValueIdSet& newExternalInputs,
 const GroupAttributes& coveringGA,
 ValueIdSet& referencedInputs,
 ValueIdSet& coveredSubExpr,
 ValueIdSet& unCoveredExpr) const
{
  //return TRUE;
  return FALSE;
}

// RowNumFunc                        
RowNumFunc::~RowNumFunc()
{
}

ItemExpr * RowNumFunc::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  RowNumFunc *result;

  if (derivedNode == NULL)
    result = new (outHeap) RowNumFunc();
  else
    result = (RowNumFunc*)derivedNode;

  return BuiltinFunction::copyTopNode(result, outHeap);

} // RowNumFunc::copyTopNode()
                                                  
NABoolean RowNumFunc::isCovered
                   (const ValueIdSet& newExternalInputs,
		    const GroupAttributes& coveringGA,
		    ValueIdSet& referencedInputs,
		    ValueIdSet& coveredSubExpr,
		    ValueIdSet& unCoveredExpr) const
{
  // The ROWNUM function is not pushed down.
  return FALSE;
} // RowNumFunc::isCovered
                                                  
// -----------------------------------------------------------------------
// Member functions for ItmSequenceFunction
//------------------------------------------------------------------------
// -----------------------------------------------------------------------
// Destructor
// -----------------------------------------------------------------------
ItmSequenceFunction::~ItmSequenceFunction() {}

NABoolean ItmSequenceFunction::isASequenceFunction() const   // virtual method
  { return TRUE; }

NABoolean ItmSequenceFunction::isCovered(const ValueIdSet& newExternalInputs,
                               const GroupAttributes& newRelExprAnchorGA,
                               ValueIdSet& referencedInputs,
                               ValueIdSet& coveredSubExpr,
                               ValueIdSet& unCoveredExpr) const
{
  // ---------------------------------------------------------------------
  // If the operand is covered, then return its ValueId in coveredSubExpr.
  // ---------------------------------------------------------------------
  ValueIdSet localSubExpr;
  for(Lng32 i = 0; i < (Lng32)getArity(); i++)
  {

     if (child(i)->getOperatorType() == ITM_ITEM_LIST)
      {
        // child is a multi-valued expression, test coverage on individuals
        // 
        ExprValueId treePtr = child(i);

        ItemExprTreeAsList values(&treePtr,
                                  ITM_ITEM_LIST,
                                  RIGHT_LINEAR_TREE);

        CollIndex nc = values.entries();
        for (CollIndex m = 0; m < nc; m++)
          {
            if(newRelExprAnchorGA.covers(values[m]->getValueId(),
                                         newExternalInputs,
                                         referencedInputs,
                                         &localSubExpr))
              {
                coveredSubExpr += values[m]->getValueId();
              }
            coveredSubExpr += localSubExpr;
          }
      }
    else 
      {

	if(newRelExprAnchorGA.covers(child(i)->getValueId(),
				     newExternalInputs,
				     referencedInputs,
				     &localSubExpr))
	{
	  coveredSubExpr += child(i)->getValueId();
	}
	coveredSubExpr += localSubExpr;
    }

  }
  // ---------------------------------------------------------------------
  // The ItmSequenceFunction function is coerced to fail the coverage test even
  // when its operands isCovered(). This is because only the RelSequence node
  // can evaluate the function. The function is associated with a RelSequence
  // node at the very beginning and we don't allow it to be pushed down
  // even if the function's operands are covered at the node's child.
  // ---------------------------------------------------------------------
  return FALSE;
}

void ItmSequenceFunction::getLeafValuesForCoverTest(ValueIdSet& leafValues, 
                                                    const GroupAttributes& coveringGA,
                                                    const ValueIdSet & newExternalInputs) const
{
  // ItmSequenceFunction is considered a leaf operator for cover test.
  leafValues += getValueId();
}


const NAString ItmSequenceFunction::getText() const
{
  switch (getOperatorType())
    {
    case ITM_DIFF1:
      return "diff1";
    case ITM_DIFF2:
      return "diff2";
    case ITM_LAST_NOT_NULL:
      return "lastnotnull";
    case ITM_MOVING_AVG:
      return "movingavg";
    case ITM_MOVING_COUNT:
      return "movingcount";
    case ITM_MOVING_MAX:
      return "movingmax";
    case ITM_MOVING_MIN:
      return "movingmin";
    case ITM_MOVING_RANK:
      return "movingrank";
    case ITM_MOVING_SDEV:
      return "movingsdev";
    case ITM_MOVING_SUM:
      return "movingsum";
    case ITM_MOVING_VARIANCE:
      return "movingvariance";
    case ITM_RUNNING_AVG:
      return "runningavg";
    case ITM_RUNNING_CHANGE:
      return "rows since changed";
    case ITM_RUNNING_COUNT:
      return "runningcount";
    case ITM_RUNNING_MAX:
      return "runningmax";
    case ITM_RUNNING_MIN:
      return "runningmin";
    case ITM_RUNNING_RANK:
      return "runningrank";
    case ITM_RUNNING_SDEV:
      return "runningsdev";
    case ITM_RUNNING_SUM:
      return "runningsum";
    case ITM_RUNNING_VARIANCE:
      return "runningvariance";
    case ITM_OFFSET:
      if (getArity() == 1 )// internally created offsets
      {
        char str[30]; 
        str_sprintf(str, "offset[%d]",((ItmSeqOffset *)this)->getOffsetConstantValue());
        return str;
      }
      else
      {
        return "offset";
      }
    case ITM_THIS:
      return "this";
    case ITM_NOT_THIS:
      return "not this";

    case ITM_OLAP_COUNT:
      return "olap count";
    case ITM_OLAP_MAX:
      return "olap max";
    case ITM_OLAP_MIN:
      return "olap min";
    case ITM_OLAP_RANK:
      return "olap rank";
    case ITM_OLAP_DRANK:
      return "olap dense rank";
    case ITM_OLAP_SDEV:
      return "olap sdev";
    case ITM_OLAP_SUM:
      return "olap sum";
    case ITM_OLAP_VARIANCE:
      return "olap variance";

    default:
      return "unknown sequence function";
    } // switch
}

ItemExpr * ItmSequenceFunction::copyTopNode(ItemExpr *derivedNode,
                                            CollHeap* outHeap)
{
  ItmSequenceFunction *result = NULL;

  if (derivedNode == NULL)
   ABORT(
   "copyTopNode() can only be called for a derived class of ItmSequenceFunction"
         );
  else
    result = (ItmSequenceFunction *)derivedNode;

  // Copy OLAP Window Function information.
  //
  result->isOLAP_ = isOLAP_;
  result->olapPartitionBy_ = olapPartitionBy_;
  result->olapOrderBy_ = olapOrderBy_;
  result->isTDFunction_ = isTDFunction_;

  return BuiltinFunction::copyTopNode(result, outHeap);
} // ItmSequenceFunction::copyTopNode()

ItemExpr * ItmSequenceFunction::transformTDFunction(BindWA * bindWA)
{
  if (getOperatorType() != ITM_RUNNING_RANK) // we are only doing td rank in this ohase
    return this;

  if (!isTDFunction())
    return this;

  if (!olapPartitionBy_)
    return this;

  ItmSequenceFunction *partClause = NULL;    

  partClause = new (bindWA->getCurrentScope()->collHeap())
                    ItmSeqRunningFunction(ITM_RUNNING_CHANGE,
                                          olapPartitionBy_->copyTree(bindWA->getCurrentScope()->collHeap()) );

  partClause->setIsTDFunction(TRUE);
  partClause->setOlapOrderBy(olapOrderBy_->copyTree(bindWA->getCurrentScope()->collHeap()));
  partClause->setOlapPartitionBy(olapPartitionBy_->copyTree(bindWA->getCurrentScope()->collHeap()));

  ItmSequenceFunction *seqFunc = new (bindWA->getCurrentScope()->collHeap())
                                      ItmSeqMovingFunction(ITM_MOVING_RANK, child(0), partClause);

  seqFunc->setIsTDFunction(TRUE);
  seqFunc->setOlapOrderBy(olapOrderBy_->copyTree(bindWA->getCurrentScope()->collHeap()));
  seqFunc->setOlapPartitionBy(olapPartitionBy_->copyTree(bindWA->getCurrentScope()->collHeap()));
                                    
  return seqFunc;
}

// -----------------------------------------------------------------------
// member functions for ItmSeqRunningFunction
// -----------------------------------------------------------------------
// Destructor
// -----------------------------------------------------------------------
ItmSeqRunningFunction::~ItmSeqRunningFunction() {}

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


ItmSeqOlapFunction::~ItmSeqOlapFunction() {}


ItemExpr * ItmSeqRunningFunction::copyTopNode(ItemExpr *derivedNode,
                                              CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL)
    {
     result = new (outHeap) ItmSeqRunningFunction(getOperatorType(),
                                                  child(0));
     ((ItmSeqRunningFunction *)result)->setIsOLAP(isOLAP());
    }
  else
    result = derivedNode;

  return ItmSequenceFunction::copyTopNode(result, outHeap);
} // ItmSeqRunningFunction::copyTopNode()


ItemExpr * ItmSeqOlapFunction::copyTopNode(ItemExpr *derivedNode,
                                              CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL)
    {
     result = new (outHeap) ItmSeqOlapFunction(getOperatorType(),
                                                  child(0));
    }
  else
    result = derivedNode;

  ((ItmSeqOlapFunction *)result)->frameStart_ = frameStart_;
  ((ItmSeqOlapFunction *)result)->frameEnd_ = frameEnd_;

  return ItmSequenceFunction::copyTopNode(result, outHeap);
} // ItmSeqOlapFunction::copyTopNode()


NABoolean
ItmSeqOlapFunction::inverseOLAPOrder(CollHeap *heap)
{
  //if (frameStart_ != -INT_MAX) {
  if (getOlapOrderBy())
    {
      ItemExprList orderList(getOlapOrderBy(),0);

      ItemExpr *newOrder = NULL;
      for (CollIndex i = 0; i < orderList.entries(); i++) {

        ItemExpr *itm = orderList[i];
        if (itm->getOperatorType() == ITM_INVERSE) {
          itm = itm->child(0);
        } else {
          itm = new (heap) InverseOrder(itm);
        }
        if(newOrder) {
          newOrder = new(heap) ItemList(newOrder, itm);
        } else {
          newOrder = itm;
        }
      }
      
      setOlapOrderBy(newOrder);
    }

  Lng32 olapRowsTemp = frameEnd_;
  frameEnd_ = -frameStart_;
  frameStart_ = -olapRowsTemp;
  return TRUE;
  //}
  //return FALSE;
}

NABoolean ItmSeqOlapFunction::hasEquivalentProperties(ItemExpr * other)
{
  if (other == NULL)
    return FALSE;
  if (getOperatorType() != other->getOperatorType() || 
        getArity() != other->getArity())
    return FALSE;

  ItmSeqOlapFunction * otherOSeq = (ItmSeqOlapFunction *) other;

  return 
      (this->frameStart_ == otherOSeq->frameStart_ &&
       this->frameEnd_ == otherOSeq->frameEnd_) ;
}

NABoolean ItmSequenceFunction::isEquivalentForBinding(const ItemExpr * other)
{
  
  
  if ( getOperatorType() != other->getOperatorType() || getArity() != other->getArity() )
  {
    return FALSE;
  }
  
  for (Lng32 i = 0; (i < getArity()); i++)
  {
    if (child(i)->isASequenceFunction())
    {
      ItmSequenceFunction * seqFunc = (ItmSequenceFunction * ) child(i).getValueId().getItemExpr();
      if (!seqFunc->isEquivalentForBinding(other->child(i)))
      {
	return FALSE;
      }
    }
    else 
    {
      if (!child(i)->hasBaseEquivalenceForCodeGeneration(other->child(i)))
    {
      return FALSE;
    }
    }
  }
  return TRUE;
 }
// -----------------------------------------------------------------------
// member functions for Offset
// -----------------------------------------------------------------------
// Destructor
// -----------------------------------------------------------------------
ItmSeqOffset::~ItmSeqOffset() {}

// -----------------------------------------------------------------------
Int32 ItmSeqOffset::getArity() const
{
  if (child(1))
  {
    if (child(2))
      return 3;
    else
      return 2;
  }
  else
    return 1;
}

ItemExpr * ItmSeqOffset::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL)
   {
    switch (getArity())
    {
      case 2:
         result = new (outHeap) ItmSeqOffset(child(0), child(1), NULL, 
                                             nullRowIsZero());
         break;

      case 3:
         result = new (outHeap) ItmSeqOffset(child(0), child(1), child(2),
                                             nullRowIsZero());
         break;

      default:
         result = new (outHeap) ItmSeqOffset( child(0),
                                             nullRowIsZero(),
                                              getOffsetConstantValue(),
                                              isLeading(),
                                              winSize());
         break;
    }
    ((ItmSeqOffset *)result)->setIsOLAP(isOLAP());
   }
  else
   {
    result = derivedNode;
   }

  return ItmSequenceFunction::copyTopNode(result, outHeap);

} // ItmSeqOffset::copyTopNode()

NABoolean ItmSeqOffset::hasEquivalentProperties(ItemExpr * other)
{
  if (other == NULL)
    return FALSE;
  if (getOperatorType() != other->getOperatorType() || 
        getArity() != other->getArity())
    return FALSE;

  ItmSeqOffset * otherOffset = (ItmSeqOffset *) other;

  return 
    (this->offsetConstantValue_ == otherOffset->offsetConstantValue_) &&
    (this->nullRowIsZero_ == otherOffset->nullRowIsZero_) &&
    (this->leading_ == otherOffset->leading_) &&
    (this->winSize_ == otherOffset->winSize_);
}

// -----------------------------------------------------------------------
// member functions for DIFF1
// -----------------------------------------------------------------------
// Destructor
// -----------------------------------------------------------------------
ItmSeqDiff1::~ItmSeqDiff1() {}

// -----------------------------------------------------------------------

ItemExpr * ItmSeqDiff1::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL)
   {
    if (getArity() == 1)
    {
     result = new (outHeap) ItmSeqDiff1(child(0));
    }
    else
    {
     result = new (outHeap) ItmSeqDiff1(child(0), child(1));
    }
   }
  else
   {
    result = derivedNode;
   }

  return ItmSequenceFunction::copyTopNode(result, outHeap);

} // ItmSeqDiff1::copyTopNode()

// -----------------------------------------------------------------------
// member functions for DIFF2
// -----------------------------------------------------------------------
// Destructor
// -----------------------------------------------------------------------
ItmSeqDiff2::~ItmSeqDiff2() {}

// -----------------------------------------------------------------------

ItemExpr * ItmSeqDiff2::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL)
   {
    if (getArity() == 1)
    {
     result = new (outHeap) ItmSeqDiff2(child(0));
    }
    else
    {
     result = new (outHeap) ItmSeqDiff2(child(0), child(1));
    }
   }
  else
   {
    result = derivedNode;
   }

  return ItmSequenceFunction::copyTopNode(result, outHeap);

} // ItmSeqDiff2::copyTopNode()

// -----------------------------------------------------------------------
// member functions for ItmSeqRowsSince
// -----------------------------------------------------------------------
// Destructor
// -----------------------------------------------------------------------
ItmSeqRowsSince :: ~ItmSeqRowsSince() {};

ItemExpr  *ItmSeqRowsSince :: copyTopNode(ItemExpr *derivedNode,
                                          CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL)
    {
     if (getArity() == 1)
     {
      result = new (outHeap) ItmSeqRowsSince(child(0), NULL, includeCurrentRow());
     }
     else
     {
      result = new (outHeap) ItmSeqRowsSince(child(0), child(1), includeCurrentRow());
     }
    }
  else
  {
   result = derivedNode;
  }

  return ItmSequenceFunction::copyTopNode(result, outHeap);
} // ItmSeqRowsSince::copyTopNode()

const NAString ItmSeqRowsSince :: getText() const
{
  if (includeCurrentRow())
   return "rows since inclusive";
  else
   return "rows since";
}  // ItmSeqRowsSince::getText()

// -----------------------------------------------------------------------
// member functions for ItmSeqMovingFunction
// -----------------------------------------------------------------------
// Destructor
// -----------------------------------------------------------------------
ItmSeqMovingFunction::~ItmSeqMovingFunction() {}

ItemExpr * ItmSeqMovingFunction::copyTopNode(ItemExpr *derivedNode,
                                             CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL) {
    result = new (outHeap) ItmSeqMovingFunction(getOperatorType(),
                                                child(0), child(1), child(2));
  ((ItmSeqMovingFunction *)result)->setIsOLAP(isOLAP());
  }
  else
    result = derivedNode;

  if (this->getSkipMovingMinMaxTransformation() == TRUE)
  {
   ((ItmSeqMovingFunction *)result)->setSkipMovingMinMaxTransformation();
  }

  return ItmSequenceFunction::copyTopNode(result, outHeap);
} // ItmSeqMovingFunction::copyTopNode()

NABoolean ItmSeqMovingFunction::hasEquivalentProperties(ItemExpr * other)
{
  if (other == NULL)
    return FALSE;
  if (getOperatorType() != other->getOperatorType() || 
        getArity() != other->getArity())
    return FALSE;

  ItmSeqMovingFunction * otherMSeq = (ItmSeqMovingFunction *) other;

  return 
      (this->skipMovingMinMaxTransformation_ == otherMSeq->skipMovingMinMaxTransformation_) ;
}
// -----------------------------------------------------------------------
// member functions for THIS function
// -----------------------------------------------------------------------
// Destructor
// -----------------------------------------------------------------------
ItmSeqThisFunction::~ItmSeqThisFunction() {}

ItemExpr * ItmSeqThisFunction::copyTopNode(ItemExpr *derivedNode,
                                           CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL)
   {
     result = new (outHeap) ItmSeqThisFunction (child(0));
   }
  else
   {
    result = derivedNode;
   }

  return ItmSequenceFunction::copyTopNode(result, outHeap);

} // ItmSeqThisFunction::copyTopNode()

// -----------------------------------------------------------------------
// member functions for NotTHIS function
// -----------------------------------------------------------------------
// Destructor
// -----------------------------------------------------------------------

ItmSeqNotTHISFunction::~ItmSeqNotTHISFunction(){}

ItemExpr *ItmSeqNotTHISFunction::copyTopNode(ItemExpr *derivedNode,
                                             CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL)
   {
     result = new (outHeap) ItmSeqNotTHISFunction (child(0));
   }
  else
   {
    result = derivedNode;
   }

  return ItmSequenceFunction::copyTopNode(result, outHeap);

} // ItmSeqNotTHISFunction::copyTopNode()

// -----------------------------------------------------------------------
// member functions for ItmScalarMinMax
// -----------------------------------------------------------------------
// Destructor
// -----------------------------------------------------------------------
ItmScalarMinMax::~ItmScalarMinMax() {};

ItemExpr *ItmScalarMinMax::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL)
   result = new (outHeap)ItmScalarMinMax(getOperatorType(), child(0), child(1));
  else
   result = derivedNode;

  return BuiltinFunction::copyTopNode(result, outHeap);
} // ItmScalarMinMax::copyTopNode

NABoolean ItemExpr::containsOneRowAggregate()
{

  if ( getOperatorType() == ITM_ONE_ROW )
     return TRUE;

  for (Int32 i=0; i < getArity(); i++)
  {
    if (child(i)->castToItemExpr()->containsOneRowAggregate())
      return TRUE;
  }
  return FALSE;
} // ItemExpr::containsOneRowAggregate()

NABoolean ItemExpr::containsOpType(OperatorTypeEnum opType) const
{

  if ( getOperator().match(opType) )
     return TRUE;

  for (Int32 i=0; i < getArity(); i++)
  {
    if (child(i)->castToItemExpr()->containsOpType(opType))
      return TRUE;
  }
  return FALSE;
} // ItemExpr::containsOpType()

// If I am untransformed, I tell my parent, which in turn will mark itself
// as untransformed, and tell its parent, ..., all the way up to the
// original place where this method was called.

NABoolean ItemExpr::markPathToUnTransformedNode()
{
  NABoolean retval = FALSE ;

  if ( !nodeIsTransformed() )
    retval = TRUE ;

  for (Int32 i=0; i < getArity(); i++)
  {
    if ( child(i)->castToItemExpr()->markPathToUnTransformedNode() )
      {
        markAsUnTransformed() ;
        retval = TRUE ;
        // NB: Since this function is marking nodes as untransformed, we
        // can't simply break after the first child which is found to
        // be untransformed.
      }
  }
  return retval;
} // ItemExpr::markPathToUnTransformedNode()


NABoolean ItemExpr::isEquivalentForCodeGeneration(const ItemExpr * other)
  {
  NABoolean rc = FALSE;// by default, return FALSE (suppress common subexpr elimination

  if (getArity() == 0)  // to limit needless recursion
    {
    if (hasBaseEquivalenceForCodeGeneration(other))
      {
      // we know other is non-null, has same operator type, same arity, and
      // that its children are equivalent

      OperatorTypeEnum myOp = getOperatorType();
      const ItemExpr & refOther = (const ItemExpr &) *other;

      // as it happens, with 0-arity operators, we know that operator==
      // should return false for all cases below (because of the way the
      // code in hasBaseEquivalenceForCodeGeneration() works; but I want
      // to see if virtual forms of operator== are selected)

      if (myOp == ITM_CONSTANT)
        {
        rc = (operator==(refOther));
        }
      else if (myOp == ITM_REFERENCE)
        {
        rc = (operator==(refOther));
        }
      else if (myOp == ITM_BASECOLUMN)
        {
        rc = (operator==(refOther));
        }
      else if (myOp == ITM_INDEXCOLUMN)
        {
        rc = (operator==(refOther));
        }
      }
    }
  return rc;
  }


NABoolean ItemExpr::hasBaseEquivalenceForCodeGeneration(const ItemExpr * other)
  {
  NABoolean rc = FALSE;    // assume not

  if (other)
    {
    const ItemExpr & refOther = (const ItemExpr &) *other;  // we know it exists

    if (operator==(refOther))  // $$$$ will this get virtual operator==????
      rc = TRUE;    // equal nodes are considered equivalent
    else
      {
      if (getOperatorType() == other->getOperatorType())
        {
        Lng32 arity = getArity();

        if (arity == other->getArity())
          {
          // make sure children are equivalent
          rc = TRUE;       // be optimistic now; assume equivalent
          for (Lng32 i = 0; (i < arity) && (rc); i++)
            {
            if (!(child(i)->isEquivalentForCodeGeneration(other->child(i))))
              rc = FALSE;   // oops -- found non-equivalent children
            }
          }  // end if arity's are equal
        }  // end if oper types are equal
      }  // end else nodes aren't equal
    }  // end if other is non-null

  return rc;
  }

  ItemExpr* ItemExpr::getParticularItemExprFromTree(NAList<Lng32>& childNum, 
                                          NAList<OperatorTypeEnum>& opType) const
  {
    ItemExpr * root = (ItemExpr *) this;
    for (CollIndex i = 0; i < childNum.entries(); i++)
    {
      if ((root->getArity() > childNum[i]) && 
          (root->child(childNum[i])) && 
          (root->child(childNum[i])->getOperatorType() == opType[i])) 
      {
          root = root->child(childNum[i]);
      }
      else
      {
        DCMPASSERT(FALSE);
        return NULL;
      }
    }
    return root;
  }

ItemExpr* ItemExpr::removeRangeSpecItems(NormWA* normWA)
{
  for (Lng32 i = 0; i < getArity(); i++)
  {
    child(i) = child(i)->removeRangeSpecItems(normWA);
  }
  return this;
};

// Raj P - 1/01
// Support for OUT parameters in Stored Procedures for Java
// Set Parameter Mode, Ordinal Position and Variable Index for a
// host variable or dynamic parameter
void
HostVar::setPMOrdPosAndIndex( ComColumnDirection paramMode,
			      Int32 ordinalPosition,
			      Int32 index )
{
    paramMode_ = paramMode;
    ordinalPosition_ = ordinalPosition;
    hvIndex_ = index;
}

NABoolean HostVar::isSystemGeneratedOutputHV() const
{  
  return (isSystemGenerated() &&
           getName() == "_sys_ignored_CC_convErrorFlag"); 
}

void
DynamicParam::setPMOrdPosAndIndex( ComColumnDirection paramMode,
				   Int32 ordinalPosition,
				   Int32 index )
{
    paramMode_ = paramMode;
    ordinalPosition_ = ordinalPosition;
    dpIndex_ = index;
}

ComColumnDirection ItemExpr::getParamMode () const
{
  CMPASSERT (0);
  return COM_UNKNOWN_DIRECTION;
};

Int32 ItemExpr::getOrdinalPosition () const
{
  CMPASSERT (0);
  return -1;
}

Int32 ItemExpr::getHVorDPIndex () const
{
  CMPASSERT (0);
  return -1;
}

NABoolean ItemExpr::isARangePredicate() const
{
  OperatorTypeEnum oper = getOperatorType();

  if ((oper == ITM_GREATER)    ||
      (oper == ITM_GREATER_EQ) ||
      (oper == ITM_LESS)       ||
      (oper == ITM_LESS_EQ))
  {
    return TRUE;
  }

  return FALSE;
}


QR::ExprElement Function::getQRExprElem() const
{
  return QR::QRFunctionElem;
}

// Flipping the tree in 1 pass top->bottom
//
//ITEM_LIST  (OLD TREE)
//    /   \
//   4    ITEM_LIST
//            /   \
//           3   ITEM_LIST
//                  /    \
//                 2      1
//
//ITEM_LIST   (NEW TREE)
//   /    \	
//   1     ITEM_LIST       
//          /     \               
//         2     ITEM_LIST
//                 /    \
//                 3     4

ItemExpr * ItemExpr::reverseTree() 
{
	ItemExpr *grammarTree = this;
	ItemExpr *topNode = NULL;


	// Special Case: 1, 2 & 3 columns. Base of tree
	// only 1 column.
	if (grammarTree->getOperatorType()!=ITM_ITEM_LIST) 
		return grammarTree;

	if (grammarTree->child(1)->getOperatorType()==ITM_ITEM_LIST ) {
		
		// more than 2 columns	
		topNode = grammarTree->child(1)->child(1);
		grammarTree->child(1)->child(1) = grammarTree->child(0);

		if (topNode->getOperatorType() != ITM_ITEM_LIST) { 
			// extactly 3 columns
			grammarTree->child(0) = topNode;		
			return grammarTree;
		}
		else {
			// more than 3 columns
			grammarTree->child(0) = topNode->child(0);
		}
	}
	else {
		// exactly 2 columns
		ItemExpr *temp = grammarTree->child(1);
		grammarTree->child(1) = grammarTree->child(0);
		grammarTree->child(0) = temp; 
		return grammarTree;
	}

	while (topNode) {

		if (topNode->child(1)->getOperatorType()==ITM_ITEM_LIST ) { 
		  // not bottom of tree
			ItemExpr *temp = topNode->child(1);
			topNode->child(1) = grammarTree;
			grammarTree = topNode;
			topNode = temp;
			grammarTree->child(0) = topNode->child(0);
		}
		else {  // bottom of the tree
			topNode->child(0) = topNode->child(1);
			topNode->child(1) = grammarTree;
			grammarTree = topNode;
			break;
		}
	}

	return grammarTree;

} // end of function

QR::ExprElement ItemExpr::getQRExprElem() const
{
  return QR::QRNoElem;
}

QR::ExprElement ConstantParameter::getQRExprElem() const
{
  return QR::QRScalarValueElem;
}

// Constructor for the wrapper class RangeSpecRef:
RangeSpecRef::RangeSpecRef(OperatorTypeEnum otype,
			   OptNormRangeSpec* range,
			   ItemExpr *colValueId,
			   ItemExpr *reConsIExpr)
  : ItemExpr(ITM_RANGE_SPEC_FUNC,colValueId,reConsIExpr),
    range_(range)
{}

/* Get the already generated ValueId */
DisjunctArray * RangeSpecRef::mdamTreeWalk()
{
  return new (CmpCommon::statementHeap()) DisjunctArray(new (CmpCommon::statementHeap()) ValueIdSet(getValueId()));
}

/* Need to get the access rightchild to print out the value , rightchild is reconstructed though */
/* This will affect explain "xx" output, this needs to be completed while we get a pointer to the right child
Item expression, then it will print something like <column> "Range in" Item expression corresponding to 
<subranges> */ 
const NAString RangeSpecRef::getText()  const
{   
  return "Range in";
}

short RangeSpecRef::mdamPredGen(Generator * generator,
                                MdamPred ** head,
                                MdamPred ** tail,
                                MdamCodeGenHelper & mdamHelper,
                                ItemExpr * parent)
{
  // return dummy;
  return 0;
}

Int32 RangeSpecRef::getArity() const 
{ 
  return 2; 
}

// delete this and the range_ object associated with this, if present */
RangeSpecRef::~RangeSpecRef()
{
  if(range_)
    delete range_;
}

ItemExpr * RangeSpecRef::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  RangeSpecRef *result;
  if (derivedNode == NULL)
    // Need a Deep copy of range_ object. - Change needs to be done after
    // Copy ctor is available.
    // Curently range_->clone(outHeap) gives Null value, while copying the tree
    // So again back to shallow copy
    result = new (outHeap) RangeSpecRef(getOperatorType(),range_, NULL,NULL);
  else
    result = (RangeSpecRef *) derivedNode;

  // copy the data members
  return ItemExpr::copyTopNode(result, outHeap);
}

short RangeSpecRef::codeGen(Generator* generator)
{
  child(1)->codeGen(generator);
  return 0;
}

void RangeSpecRef::unparse(NAString &result,
                           PhaseEnum phase,
                           UnparseFormatEnum form,
                           TableDesc * tabId) const
{
  // Don't include rangespec op if query format -- it won't parse.
  if (form == QUERY_FORMAT || form == COMPUTED_COLUMN_FORMAT)
    child(1)->unparse(result, phase, form, tabId);
  else
    ItemExpr::unparse(result, phase, form, tabId);
}

ItemExpr* RangeSpecRef::removeRangeSpecItems(NormWA* normWA)
{
  return getRangeObject()->getRangeItemExpr(normWA);
};

void RangeSpecRef::getValueIdSetForReconsItemExpr(ValueIdSet &outvs)
{
  ValueIdSet items;
  ItemExpr* ie;
  child(1)->convertToValueIdSet(items, NULL, ITM_ITEM_LIST);
  for (ValueId vid=items.init(); items.next(vid); items.advance(vid))
  {
    ie = vid.getItemExpr();
    if (!ie->isLike())
      ie->convertToValueIdSet(outvs, NULL, ITM_AND);
    else
      outvs.insert(vid);  // Add LIKE expansion without decomposing
  }
}

ItemExpr* revertBackToOldTree(CollHeap *heap, ItemExpr* newTree) 
{
  if(newTree->getOperatorType() != ITM_AND && 
     newTree->getOperatorType() != ITM_OR)
  {
    if (newTree->getOperatorType() == ITM_RANGE_SPEC_FUNC ) 
    {
      return(newTree->child(1));
    }
    else
    {
      return (newTree);	
    }
  }
  else
  {
    ItemExpr* newLeftNode = revertBackToOldTree(heap,newTree->child(0));
    ItemExpr* newRightNode = revertBackToOldTree(heap,newTree->child(1));
    assert(newLeftNode != NULL && newRightNode != NULL);
    newTree->setChild(0, newLeftNode);
    newTree->setChild(1, newRightNode);
    return newTree;
  }
}

// This method reverts back to Old Tree as valueIdSet from transformed Tree as valueIdSet.
void revertBackToOldTreeUsingValueIdSet(  ValueIdSet& inputSet /* IN */, ValueIdSet& outputSet /* OUT */) 
{
	ValueIdSet orSet,outorSet;
	ItemExpr * inputItemExprTree = NULL;
    for (ValueId predId = inputSet.init();
       inputSet.next(predId);
	   inputSet.advance(predId) ){
		if( predId.getItemExpr()->getOperatorType() == ITM_RANGE_SPEC_FUNC){
          outputSet += predId.getItemExpr()->child(1)->castToItemExpr()->getValueId();
		  if(inputItemExprTree != NULL)
		  {
            outputSet += inputItemExprTree->getValueId();
			inputItemExprTree = NULL;
			outorSet.clear();
		  }
		}
		else if( predId.getItemExpr()->getOperatorType() == ITM_OR){
        predId.getItemExpr()->convertToValueIdSet(orSet, NULL, ITM_OR, FALSE);
        for (ValueId predIdOr = orSet.init();
             orSet.next(predIdOr);
	         orSet.advance(predIdOr) ){
			 if(predIdOr.getItemExpr()->getOperatorType() == ITM_RANGE_SPEC_FUNC){
				 outorSet += predIdOr.getItemExpr()->child(1)->castToItemExpr()->getValueId();
			 }
			 else
			  outorSet += predIdOr;
			}
		  if(outorSet.entries())
		  inputItemExprTree = outorSet.rebuildExprTree(ITM_OR,FALSE,FALSE);
		}
		else
		{
         outputSet += predId;
		  if(inputItemExprTree != NULL)
		  {
            outputSet += inputItemExprTree->getValueId();
			inputItemExprTree = NULL;
			outorSet.clear();
		  }
		}
	}// for (1)
	if(inputItemExprTree != NULL)
	{
      outputSet += inputItemExprTree->getValueId();
	  inputItemExprTree = NULL;
	  outorSet.clear();
	}
}


NABoolean LOBoper::isCovered
(const ValueIdSet& newExternalInputs,
 const GroupAttributes& coveringGA,
 ValueIdSet& referencedInputs,
 ValueIdSet& coveredSubExpr,
 ValueIdSet& unCoveredExpr) const
{
  // If the argument is not a constant then it can be
  // evaluated anywhere in the tree. So check for its coverage
  ValueIdSet localSubExpr;
  for (Lng32 i = 0; i < (Lng32)getArity(); i++)
    {
      if ( coveringGA.covers(child(i)->getValueId(),
			     newExternalInputs,
			     referencedInputs,
			     &localSubExpr) )
	{
	  coveredSubExpr += child(i)->getValueId();
	}
    }

  // cannot be pushed down. Must be evaluated in master exe.
  return FALSE;
}

// Evalaute the exprssion at compile time. Assume all operands are constants.
// Return NULL if the computation fails and CmpCommon::diags() may be side-affected.
ConstValue* ItemExpr::evaluate(CollHeap* heap)
{
  ValueIdList exprs;
  exprs.insert(getValueId());

  const NAType& dataType = getValueId().getType();

  Lng32 decodedValueLen = dataType.getNominalSize() + dataType.getSQLnullHdrSize();

  char staticDecodeBuf[200];
  Lng32 staticDecodeBufLen = 200;

  char* decodeBuf = staticDecodeBuf;
  Lng32 decodeBufLen = staticDecodeBufLen;

  // For character types, multiplying by 6 to deal with conversions between
  // any two known character sets allowed. See CharInfo::maxBytesPerChar()
  // for a list of max bytes per char for each supported character set.  
  Lng32 factor = (DFS2REC::isAnyCharacter(dataType.getFSDatatype())) ? 6 : 1;

  if ( staticDecodeBufLen < decodedValueLen * factor) {
    decodeBufLen = decodedValueLen * factor;
    decodeBuf = new (STMTHEAP) char[decodeBufLen];
  }

  Lng32 resultLength = 0;
  Lng32 resultOffset = 0;

  // Produce the decoded key. Refer to 
  // ex_function_encode::decodeKeyValue() for the 
  // implementation of the decoding logic.
  ex_expr::exp_return_type rc = exprs.evalAtCompileTime
    (0, ExpTupleDesc::SQLARK_EXPLODED_FORMAT, decodeBuf, decodeBufLen,
     &resultLength, &resultOffset, CmpCommon::diags()
     );


  ConstValue* result = NULL;

  if ( rc == ex_expr::EXPR_OK ) {
    CMPASSERT(resultOffset == dataType.getPrefixSizeWithAlignment());
    // expect the decodeBuf to have this layout
    // | null ind. | varchar length ind. | alignment | result |
    // |<---getPrefixSizeWithAlignment-------------->|
    // |<----getPrefixSize-------------->|

    // The method getPrefixSizeWithAlignment(), the diagram above,
    // and this code block assumes that varchar length ind. is
    // 2 bytes if present. If it is 4 bytes we should fail the 
    // previous assert

    // Next we get rid of alignment bytes by prepending the prefix
    // (null ind. + varlen ind.) to the result. ConstValue constr.
    // will process prefix + result. The assert above ensures that 
    // there are no alignment fillers at the beginning of the 
    // buffer. Given the previous assumption about size
    // of varchar length indicator, alignment bytes will be used by
    // expression evaluator only if column is of nullable type.
    // For a description of how alignment is computed, please see
    // ExpTupleDesc::sqlarkExplodedOffsets() in exp/exp_tuple_desc.cpp

    if (dataType.getSQLnullHdrSize() > 0)
      memmove(&decodeBuf[resultOffset - dataType.getPrefixSize()], 
                        decodeBuf, dataType.getPrefixSize());
    result =
      new (heap) 
      ConstValue(&dataType,
                 (void *) &(decodeBuf[resultOffset - 
                                      dataType.getPrefixSize()]),
                 resultLength+dataType.getPrefixSize(),
                 NULL,
                 heap);
  }

  return result;
}

ItemExpr * ItmLagOlapFunction::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
    ItemExpr *result = NULL;

    if (derivedNode == NULL)
    {
        switch (getArity()) { 
           case 2:
               result = new (outHeap) ItmLagOlapFunction(child(0), child(1));
               break;
           case 3:
               result = new (outHeap) ItmLagOlapFunction(child(0), child(1), child(2));
               break;
           default:
               CMPASSERT(FALSE);
        }
    }
    else              
        result = derivedNode;                 

  return ItmSeqOlapFunction::copyTopNode(result, outHeap);
}

ItmLeadOlapFunction::~ItmLeadOlapFunction() {}

ItemExpr * 
ItmLeadOlapFunction::copyTopNode(ItemExpr *derivedNode, CollHeap* outHeap)
{
  ItemExpr *result;

  if (derivedNode == NULL)
    {
     switch (getArity()) { 
      case 2:
         result = new (outHeap) ItmLeadOlapFunction(child(0), child(1));
         break;
      
      case 1:
      default:
         result = new (outHeap) ItmLeadOlapFunction(child(0));
         break;
     }
    }
  else              
    result = derivedNode;                 

  ((ItmLeadOlapFunction*)result)->setOffset(getOffset());

  return ItmSeqOlapFunction::copyTopNode(result, outHeap);
}

NABoolean ItmLeadOlapFunction::hasEquivalentProperties(ItemExpr * other)
{
  if (other == NULL)
    return FALSE;

  if (getOperatorType() != other->getOperatorType() ||
        getArity() != other->getArity())
    return FALSE;

  //return getOffsetExpr()->hasEquivalentProperties(((ItmLeadOlapFunction*)other)->getOffsetExpr());
  return TRUE;
}

ItemExpr *ItmLeadOlapFunction::transformOlapFunction(CollHeap *heap)
{
   return this;
}

SplitPart::~SplitPart() {}

ItemExpr * SplitPart::copyTopNode(ItemExpr *derivedNode, CollHeap *outHeap)
{
      ItemExpr *result = NULL;
      if (derivedNode == NULL)
        result = new (outHeap) SplitPart(child(0), child(1), child(2));
      else
        result = derivedNode;

     return BuiltinFunction::copyTopNode(result, outHeap);
}

