/**********************************************************************
// @@@ 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:         BindItemExpr.C
* Description:  Item expressions (binder-related methods)
* Created:      09/31/94
* Language:     C++
*
*
* 	Canst thou bind the sweet influences of Pleiades,
* 	or loose the bands of Orion?
*		    -- Job 38:31
*
******************************************************************************
*/

#define  SQLPARSERGLOBALS_FLAGS	// must precede all #include's
#define  SQLPARSERGLOBALS_NADEFAULTS

#include "Platform.h"
#include "NAWinNT.h"
#include "nawstring.h"
#include "AllItemExpr.h"
#include "BindWA.h"
#include "ComOperators.h"
#include "GroupAttr.h"			// QSTUFF
#include "parser.h"
#include "ParNameLocList.h"
#include "Rel3GL.h"
#include "RelMisc.h"
#include "RelScan.h"
#include "RelUpdate.h"
#include "Sqlcomp.h"
#include "StmtDDLAddConstraintCheck.h"
#include "StmtDDLCreateTrigger.h"
#include "StmtDDLCreateView.h"
#include "StmtDDLCreateMV.h"
#include "ex_error.h"
#include "exp_like.h"
#include "ItemColRef.h"
#include "TriggerDB.h"
#include "UdrErrors.h"
#include "nchar_mp.h"
#include "CmpStatement.h"
#include "CmpCommon.h"
#include "Analyzer.h"
#include "ControlDB.h"
#include "OptimizerSimulator.h"
#include "RelSequence.h"
#include "ItemSample.h"
#include "SqlParserGlobals.h"
#include "RelSequence.h"
#include "ComSqlId.h"

#include "ItemFuncUDF.h"
#include "CmpSeabaseDDL.h"
#include "QCache.h"

#include "TrafDDLdesc.h"
#include "exp_datetime.h"

#include <stack>


// defined in SynthType.cpp
extern
void emitDyadicTypeSQLnameMsg(Lng32 sqlCode,
			      const NAType &op1,
			      const NAType &op2,
			      const char *str1 = NULL,
			      const char *str2 = NULL,
			      ComDiagsArea * diagsArea = NULL,
                              const Lng32 int1 = -999999);

// defined in parser/SqlParserAux.h
extern
ItemExpr *literalOfDate(NAString *strptr, NABoolean noDealloc = FALSE);

#define BINDITEMEXPR_STMTCHARSET CharInfo::UTF8

// -----------------------------------------------------------------------
// utility functions
// -----------------------------------------------------------------------

inline static ValueId createValueDesc(BindWA *bindWA,
				      ItemExpr *expr,
				      const NAType *type)
{
  // See CMPASSERT in RelRoot::bindNode --
  // put there, instead of here, for performance (assert only once per query).
  return ValueDesc::create(expr, type, bindWA->wHeap());
}

// Work for Genesis 10-971028-7413 (Ansi 7.1 SR 1, plus Ansi 8 "predicates").
//
// According to Ansi, the keyword NULL in a value expression (in DML)
// may appear *only* in:
//  - the VALUES row-val-ctor(s) of an INSERT
//  - a result of a CASE
//  - operand 1 of a CAST
// As extensions, since they're harmless and possibly useful,
// we also allow the NULL kwd to appear:
//  - as a select-list item, e.g. SELECT col1,NULL,col2 FROM tbl;
//  - in a IS [NOT] NULL predicate, e.g. WHERE NULL IS NULL;
//  - in any non-Ansi function, e.g. EXPLAIN
//  - in various (many) internal functions
//
// Here (throughout BindItemExpr), we explicitly disallow the NULL kwd in:
//  - comparison predicates (BiRelat), e.g. col>=NULL, col IN (x,NULL,y)
//  - quantified comparison predicates e.g. col>=ANY(subqry), NULL IN (subqry)
//  - IN predicates (e.g. see above two lines!)
//  - BETWEEN and LIKE predicates (see ItemFunc.h ctors, and Function::bindNode)
//  - all Ansi functions, including aggregates, e.g. UPPER(NULL), SUM(NULL)
//  - arithmetic operations, e.g. NULL*col, -NULL
//
// **Note** that when we support the MATCH and OVERLAPS predicates,
// they'll need to disallow the kwd too (emulate BETWEEN and LIKE,
// their ::allowsSQLnullArg, ::isAPredicate, and ::bindNode methods).
//
//
// The keyword DEFAULT is even more restricted in Ansi syntax, so the mechanism
// for disallowing it is different and simpler:
// it's by default disallowed everywhere except where explicitly enabled
// via binder context and Insert node context -- in an INSERT VALUES list only.
//
// According to Ansi,
//   INSERT INTO t(a,b,c) VALUES(DEFAULT,DEFAULT+1,SUBSTRING(DEFAULT FROM 2))
// is not legal (DEFAULT for column A is, but not in the other 2 expressions),
// but as a Tandem extension we allow arithmetic and functions.
// (Note that RelRoot will catch ..VALUES(..SUM(DEFAULT).. with err 4015.)
//
enum errSQLnullChild
       { FUNCTION_ = -4097, ARITH_ = -4098, PREDICATE_ = -4099,
         DEFAULT_SPEC_ = -4096,		  // see DefaultSpecification::bindNode
    	 DEFAULT_BOUND_AS_NULL_ = -4095,  // see ItemExpr::bindNode
	 CHILDREN_OK_ = 0
       };

static errSQLnullChild checkForSQLnullChild(const ItemExpr *ie,
					    NABoolean SQLnullIsLegal,
					    errSQLnullChild err)
{
  // Shallow (nonrecursive) testing of children,
  // except for ItemLists whose arity 2 really implements an n-ary list.
  Int32 arity = ie->getArity();
  for (Int32 i=0; i<arity; i++) {
    ItemExpr *ieChild = ie->child(i);
    if (!ieChild) break;		// could be optional children eg. STDDEV

    if (ieChild->getOperatorType() == ITM_CONSTANT) {
      if (!SQLnullIsLegal && ((ConstValue *)ieChild)->isNull()) {

	if (err == DEFAULT_BOUND_AS_NULL_ &&
	    ((ConstValue *)ieChild)->isNullWasDefaultSpec())
	  ((ConstValue *)ieChild)->setText("DEFAULT");
        return err;
      }
    }
    else if (ieChild->getOperatorType() == ITM_DEFAULT_SPECIFICATION) {
      if (err == PREDICATE_)		// Tandem extension (see comments)
	return DEFAULT_SPEC_;
    }
    else if (ieChild->getOperatorType() == ITM_ITEM_LIST) {
      errSQLnullChild ret = checkForSQLnullChild(ieChild, SQLnullIsLegal, err);
      if (ret) return ret;
    }
  }
  return CHILDREN_OK_;			// no naughty children
}
static NABoolean checkForSQLnullChild(BindWA *bindWA,
				      ItemExpr *ie,
				      NABoolean SQLnullIsLegal	= FALSE,
				      errSQLnullChild err 	= PREDICATE_,
				      NABoolean isUnaryNegate	= FALSE)
{
  // Some Function classes implement SQL predicates (BETWEEN, LIKE, MATCH, OVERLAPS).
  if (ie->isAPredicate()) err = PREDICATE_;

  err = checkForSQLnullChild(ie, SQLnullIsLegal, err);

  if (err) {
  NAString unparsed(bindWA->wHeap());

    if (isUnaryNegate)			// instead of "0 - NULL"
      unparsed = (err == DEFAULT_SPEC_) ? "(-DEFAULT)" : "(-NULL)";
    else if (ie->getOperatorType() == ITM_POSITION) unparsed = "POSITION or LOCATE";
    else if (ie->getOperatorType() == ITM_SUBSTR)   unparsed = "SUBSTRING";
    else if (ie->getOperatorType() == ITM_TRIM)     unparsed = "TRIM, LTRIM or RTRIM";
    else if (ie->getOperatorType() == ITM_LOWER)    unparsed = "LOWER or LCASE";
    else if (ie->getOperatorType() == ITM_UPPER)    unparsed = "UPPER or UCASE";
    else if (ie->getOperatorType() == ITM_NVL)    unparsed = "NVL";
    else if (ie->getOperatorType() == ITM_QUERYID_EXTRACT)    unparsed = "QUERYID_EXTRACT";
    else {
      ie->unparse(unparsed, DEFAULT_PHASE, USER_FORMAT_DELUXE);
      if (unparsed[(size_t)0] != '(') unparsed = "(" + unparsed + ")";
    }

    // 4095     A DEFAULT which resolves to NULL is not allowed in $0~String0.
    // 4096     A DEFAULT spec is allowed only in an INSERT's VALUES list.
    // 4097-99  A NULL operand cannot appear in func/oper/pred $0~String0.
    *CmpCommon::diags() << DgSqlCode(err) << DgString0(unparsed);
    bindWA->setErrStatus();
    return TRUE;
  }
  return FALSE;
}

// Flatten certain types to simplify (shorten) various if-tests.
static inline OperatorTypeEnum getOperatorTypeFlat(const ItemExpr *ie)
{
  const OperatorType &e = ie->getOperator();
  return e.match(ITM_ANY_CAST) ? ITM_CAST : OperatorTypeEnum(e);
}

// If target requires upshifting, and source is not already upshifted,
// then interpose a new upshift-function node and bind it.
// It is caller's duty to determine if the upshifting is required.
//
// See also Upper::bindNode(), which removes unneeded Upper's.
// ## Future enhancement is to NOT interpose an upshift in these cases:
// ## - source is a CAST from a TIME/TIMESTAMP *in format with no AM/PM marker*,
// ##	as the source then ends up being all digits and punctuation
// ##   so upshift is unnecessary.
// ##   SynthType.cpp should probably set the isUpshifted flag of the CharType..
//
static ItemExpr *applyUpperToSource(BindWA *bindWA, ItemExpr *ie, Int32 srcIndex)
{
  OperatorTypeEnum opSelf = getOperatorTypeFlat(ie);
  CMPASSERT(opSelf == ITM_ASSIGN || ie->getOperator().match(ITM_ANY_CAST));
  ItemExpr *src = ie->child(srcIndex);
  ItemExpr *upSrc;
  OperatorTypeEnum opSrc = getOperatorTypeFlat(src);

  const CharType &ct = (CharType &)src->getValueId().getType();
  if (ct.getTypeQualifier() == NA_CHARACTER_TYPE && !ct.isUpshifted()) {

    if (opSrc == ITM_CONSTANT && (upSrc = ((ConstValue *)src)->toUpper()))
      ie->setChild(srcIndex, upSrc->bindNode(bindWA));
    else {
      CMPASSERT(opSrc != ITM_UPPER);		// otherwise, bug in SynthType
      const NAColumn *nacolSrc =
	src->getValueId().getNAColumn(TRUE/*okIfNotColumn*/);

      if (NOT nacolSrc || NOT nacolSrc->isUpshiftReqd()) {
	if (opSelf == ITM_ASSIGN) {
	  // Genesis 10-980402-1556: uppercase (or NULL) constant is ok
	  Upper *upSrc = new (bindWA->wHeap()) Upper(src);
	  upSrc->allowsSQLnullArg() = TRUE;     // internal UPPER, it's ok
	  ie->setChild(srcIndex, upSrc->bindNode(bindWA));
	}
	else {
	  // Genesis 10-980611-7115:
	  //	CAST(expr AS CHAR(n) UPSHIFT)  =>  UPPER(CAST(expr AS CHAR(n)))
	  CharType &ctSelf = (CharType &)ie->getValueId().getType();
	  ctSelf.setUpshifted(FALSE);
	  Upper *upSrc = new (bindWA->wHeap()) Upper(ie);
	  ie = upSrc->bindNode(bindWA);
	}
      } // !isUpshiftReqd in src
    }
  }

  return ie;
}


// There are two metadata tables containing view-column-usage information,
// VW_COL_USAGE and VW_COL_TBL_COLS.
//
// VW_COL_USAGE is defined in page 472 of the ANSI SQL-92 standard
// as the Information Schema view VIEW_COLUMN_USAGE.
// VW_COL_USAGE contains information about all columns referenced in
// the view definition (excluding the columns in the view column list)
// so supporting it is pretty simple.
//
// VW_COL_TBL_COLS is for internal use by the catalog manager to support
// view column security; it is only used when the view is updatable.
// Supporting VW_COL_TBL_COLS is harder because we need to collect only
// certain (not all) referenced columns relating to each view column.
// Since we don't know whether the view is updatable or not until the
// normalization phase completes, we must blindly collect information for it..
// Once we find out that the view is not updatable, we can throw this
// extra information away.  It's still not clear what information
// needs to be collected and what not.  So the code might still have
// problems, but hopefully it'll be more stable soon.  In certain
// cases the binder can find out if the view is not updatable; for
// example, a view is not updatable if its query expression a natural
// join operation; the binder can stop collecting information for
// the VW_COL_TBL_COLS right away.
//
void
BindUtil_CollectColUsageForCommonCol(BindWA *const bindWA,
                                     const NAString &commonColName,
                                     const RelExpr  *const tableRelExpr,
                                     const ItemExpr *const columnItemExpr)
{
  if (bindWA->getNameLocListPtr() == NULL) return;
  ExprNode *pUsageParseNode = bindWA->getUsageParseNodePtr();
  if (pUsageParseNode == NULL) return;

  QualifiedName tblQualName;

  if (tableRelExpr->getOperatorType() == REL_RENAME_TABLE AND
      ((RenameTable *)tableRelExpr)->isView()) // view
  {
    RenameTable *pRenameTab = (RenameTable *)tableRelExpr;
    tblQualName = pRenameTab->getTableName().getQualifiedNameObj();
  }
  else if (tableRelExpr->getOperatorType() == REL_SCAN)    // table
  {
    Scan *pScan = (Scan*)tableRelExpr;
    tblQualName = pScan->getTableName().getQualifiedNameObj();
    if (NOT tblQualName.fullyExpanded())  // is a renamed table
      return;
  }
  else return;  // does nothing

  ColRefName colRefName(commonColName, tblQualName);

  if (pUsageParseNode->getOperatorType()
      == DDL_ALTER_TABLE_ADD_CONSTRAINT_CHECK)
  {
    StmtDDLAddConstraintCheck &pn = *pUsageParseNode->castToElemDDLNode()->castToStmtDDLAddConstraintCheck();
    ParCheckConstraintColUsageList &cul = pn.getColumnUsageList();
    cul.insert(colRefName,
               bindWA->getCurrentScope()->context()->inSelectList());
  }
  else if (pUsageParseNode->getOperatorType() == DDL_CREATE_VIEW)
  {
    StmtDDLCreateView &cvpn = *pUsageParseNode->castToElemDDLNode()->castToStmtDDLCreateView();
    ParViewTableColsUsageList &vcul = cvpn.getViewUsages().
                                      getViewTableColsUsageList();
    vcul.insert(colRefName);

    // The view is not updatable because it has common columns.
    // This is one of a few cases that the binder knows whether the
    // view is not updatable.  See comments for method
    // ParViewUsages::isViewSurelyNotUpdatable() for more information.
    cvpn.getViewUsages().setViewIsSurelyNotUpdatableFlag();
  }
  return;

} // BindUtil_CollectColUsageForCommonCol()

//
// Returns FALSE if colRefName does not contain adequate information.
// Returns TRUE  if colRefName contains enough information to be added
//                             to a column-usage list.
//
static NABoolean
BindUtil_IsColUsgInfoOk(const ColRefName &colRefName)
{
  if (colRefName.isFabricated())
  {
    //
    // column-usage information for common columns (e.g., in
    // a natural join operation) has already been collected by
    // routine BindUtil_CollectColUsageForCommonCol().
    //
    return FALSE;
  }

  const QualifiedName &qualName = colRefName.getCorrNameObj().
                                  getQualifiedNameObj();

  if (colRefName.getColName().isNull() OR
      qualName.getObjectName().isNull())
  {
    //
    // col name in GroupBy node created by parser
    // for Select Distinct; for example:
    //
    //   create view v as select distinct * from t;
    //
    return FALSE;
  }

  if (qualName.getCatalogName().isNull() OR
      qualName.getSchemaName().isNull())
  {
    //
    // ( query_expr ) corr_name
    //
    // For example:
    //
    //   create view v as select * from (select c from t) x(d);
    //
    return FALSE;
  }

  return TRUE;
}

static NABoolean BindUtil_CollectColumnUsageInfo(BindWA *bindWA,
                                                 const ColRefName &colRefName,
                                                 const ValueId vid,
                                                 RelExpr * parent)
{
  ExprNode *pUsageParseNode = bindWA->getUsageParseNodePtr();
  if (pUsageParseNode == NULL)
  {
    return FALSE;  // no, do not continue to collect usage information
  }

  if (pUsageParseNode->getOperatorType()
      == DDL_ALTER_TABLE_ADD_CONSTRAINT_CHECK)
  {
    StmtDDLAddConstraintCheck &pn = *pUsageParseNode
      ->castToElemDDLNode()->castToStmtDDLAddConstraintCheck();
    ParCheckConstraintColUsageList &cul = pn.getColumnUsageList();
    if (BindUtil_IsColUsgInfoOk(colRefName))
    {
      cul.insert(colRefName,
                 bindWA->getCurrentScope()->context()->inSelectList());
    }
    return TRUE;
  }
  else if (pUsageParseNode->getOperatorType() == DDL_CREATE_VIEW)
  {
    StmtDDLCreateView &cvpn = *bindWA->getCreateViewParseNode();
    ParViewTableColsUsageList &vcul = cvpn.getViewUsages().
                                      getViewTableColsUsageList();

    if (BindUtil_IsColUsgInfoOk(colRefName))
    {
      vcul.insert(colRefName);
    }

    if (cvpn.isProcessingViewColList())
    {
      ParViewColTableColsUsageList &vctcul = cvpn.getViewUsages().
                                             getViewColTableColsUsageList();

      if (NOT colRefName.isFabricated() AND  // com col info already collected
          NOT cvpn.getViewUsages().isViewSurelyNotUpdatable())
      {
        const QualifiedName &qualName = colRefName.getCorrNameObj().
                                        getQualifiedNameObj();

        if (BindUtil_IsColUsgInfoOk(colRefName))
        {
          vctcul.insert(cvpn.getCurViewColNum(), colRefName);
        }
        else if (qualName.getObjectName().isNull() AND
                 NOT colRefName.getCorrNameObj().getCorrNameAsString().isNull()
                 AND NOT colRefName.getColName().isNull() AND
                 cvpn.isItmColRefInColInRowVals() AND
                 parent == cvpn.getQueryExpression())
        {
          // renamed_table.column case
          // for example: x.d in the following statement
          // create view v as select * from (select c from t) x(d);
          // needs to map to t.c (a persistent object)

          // traverses down the parse tree, skipping the RenameTable
          // parse nodes, until reaching a RenameTable parse node for
          // a referenced view or (hopefully) a base table.

          // QSTUFF
          // at this time we know that the view is updatable
          // previously an updatable view ended up to be a RelRoot
          // followed by a sequence of (Rename,RelRoot) pairs.
          // At the bottom of the view we either find a Scan
          // or a "RenameTable" inserted by view expansion.
          // When allowing emdedded generic updates we may see
          // the following combination at the bottom of a
          // view (RenameTable,RelRoot,GenericUpdate). If we
          // encounter this combination we need to skip the
          // GenericUpdate to get to the base table scan or
          // RenameTable inserted by view expansion below
          // the GenericUpdate.
          // RelExpr *result = parent->child(0);  // table in FROM clause

          NABoolean isTopLevelUpdateInView =
             (parent->getGroupAttr()->isEmbeddedUpdate() && (NOT bindWA->inViewExpansion()));

          // in case of a top level update within a view definition we really
          // want the RETDesc of the generic update as it contains both, the
          // valueids of the scan table and the valueids of the update base table.
          RelExpr *result = parent->getViewScanNode(isTopLevelUpdateInView);

          if (result)
          {
            const ValueIdList & updateValueIds =
                              bindWA->getUpdateToScanValueIds().getTopValues();
            const ValueIdList & scanValueIds =
                              bindWA->getUpdateToScanValueIds().getBottomValues();
            ValueId mappedVid = vid;

            for (CollIndex i = 0; i < updateValueIds.entries(); i++){
              if (vid == updateValueIds[i]){
                mappedVid = scanValueIds[i];
                break;
              }
            }

            // gets the fully-qualified column name (of the referenced
            // view or base table) if it exists.
            ColumnNameMap *cnm = result->getRETDesc()->findColumn(mappedVid);
            // QSTUFF

            if (cnm AND
                NOT cnm->getColumnDesc()->getColRefNameObj().isFabricated())
            {
              vctcul.insert(cvpn.getCurViewColNum(),
                            cnm->getColumnDesc()->getColRefNameObj());
            }
          } // if (result)
        } // else if (rename-table.column-name AND ...)
      } // if (column-name is not fabricated AND ...)

      if (cvpn.isItmColRefInColInRowVals() AND
          parent == cvpn.getQueryExpression())
      {
        // only increment the counter if the column in the bindRowValues()
        // is a column reference or a star column references; for example,
        //   create view v as select a, t1.*, b+2 from t1,t2;
        // in the above example, when we process a (or t1.*) here, we
        // need to increment the counter here. When we process b (in the
        // expression b+2), we do not increment the counter (the counter will
        // be incremented later in routine ItemExpr::convertToValueIdList().
        cvpn.incrCurViewColNum();
      }
    }
    return TRUE;
  }
  return FALSE;
} // BindUtil_CollectColumnUsageInfo()

static void BindUtil_UpdateNameLocForColRef(BindWA *bindWA,
                                            ColRefName &colRefName,
                                            ColumnNameMap *colNameMap,
                                            RelExpr *parent)
{
  ParNameLocList *pNameLocList = bindWA->getNameLocListPtr();
  if (pNameLocList == NULL) return;
  CMPASSERT(NOT colRefName.isStar());
  CMPASSERT(colNameMap);

  // note that the name of a common column (e.g., in a natural
  // join operation) may not be qualified so qualName and
  // qualNameExpanded may be empty.
  const ColRefName &colRefNameExpanded =
    colNameMap->getColumnDesc()->getColRefNameObj();
  const QualifiedName &qualNameExpanded =
    colRefNameExpanded.getCorrNameObj().getQualifiedNameObj();

  CorrName &corrName = colRefName.getCorrNameObj();
  QualifiedName &qualName = corrName.getQualifiedNameObj();

  ParNameLoc *pNameLoc = pNameLocList->getNameLocPtr(
			     colRefName.getNamePosition());
  // -- Triggers
  //CMPASSERT(pNameLoc);
  if (pNameLoc == NULL)
	  return;

  // Note that qualName can be empty when column is a common
  // column (e.g. in a natural join operation).  Common columns
  // is handled in routine joinCommonColumns().
  //
  if (qualName.fullyExpanded())
  {
    pNameLoc->setExpandedName(colRefName.getColRefAsAnsiString());
  }
  else if (qualNameExpanded.fullyExpanded())
  {
    // Expand colRefName's qualified name, without modifying any overlying
    // correlation name; and if no overlying corr name, also expand the
    // name loc to four-part col ref ("c.s.t.col").
    //
    qualName.setObjectName(qualNameExpanded.getObjectName());
    if (NOT qualName.getObjectName().isNull())
      qualName.applyDefaults(qualNameExpanded);
    if (corrName.getCorrNameAsString().isNull())
    {
      corrName.setCorrName(colRefNameExpanded.getCorrNameObj().getCorrNameAsString());
      pNameLoc->setExpandedName(colRefNameExpanded.getColRefAsAnsiString());
    }
  }
  else if (!colRefNameExpanded.getCorrNameObj().getCorrNameAsString().isNull())
  {
    pNameLoc->setExpandedName(colRefNameExpanded.getColRefAsAnsiString());
  }

  // Note that colRefNameExpanded might not be fully qualified in
  // certain cases (for example, the column is a derived column,
  // not a catalog object).  These should not be put into the usage
  // list.  The routine BindUtil_CollectColumnUsageInfo will take
  // care of these cases.
  //
  // Example:  The following query generates a derived column:
  // create view v as select a from (select x + y from t1) as t(a)

  BindUtil_CollectColumnUsageInfo(bindWA, colRefNameExpanded,
                                  colNameMap->getValueId(), parent);

} // BindUtil_UpdateNameLocForColRef()

static void BindUtil_UpdateNameLocForStarExpansion
				      (BindWA *bindWA,
				       const ColumnDescList &colDescList,
				       const StringPos starPos,
                                       RelExpr *parent)
{
  ParNameLocList *pNameLocList = bindWA->getNameLocListPtr();
  if (pNameLocList == NULL) return;
  if (starPos)
  {
    ParNameLoc *pNameLoc = pNameLocList->getNameLocPtr(starPos);
    CMPASSERT(pNameLoc);
    // tries to handle the following case
    // create view v as select * from (select * from (values (1), (2)) x
    NABoolean isStarWithoutColNames = FALSE;
    for (CollIndex i = 0; i < colDescList.entries(); i++)
    {
      if (colDescList[i]->getColRefNameObj().getColName().isNull())
      {
        isStarWithoutColNames = TRUE;
        break;
      }
    }
    if (isStarWithoutColNames)
      pNameLoc->setExpandedName("*");
    else
      pNameLoc->setExpandedName(colDescList.getColumnDescListAsString());
  }

  for (CollIndex i = 0; i < colDescList.entries(); i++)
    if (NOT BindUtil_CollectColumnUsageInfo(bindWA,
    					    colDescList[i]->getColRefNameObj(),
                                            colDescList[i]->getValueId(),
                                            parent))
      break;

} // BindUtil_UpdateNameLocForStarExpansion()

// -----------------------------------------------------------------------
// member functions for class ItemExpr
// -----------------------------------------------------------------------
void ItemExpr::bindChildren(BindWA *bindWA)
{
  Int32 savedCurrChildNo = currChildNo();
  for (Int32 i = 0; i < getArity(); i++, currChildNo()++) {
   
    ItemExpr *boundExpr = child(i)->bindNode(bindWA);
    if (bindWA->errStatus()) return;
    child(i) = boundExpr;
      
      
  }
  currChildNo() = savedCurrChildNo;
}

// Within the loop here, currChildNo() is an index or position.
// After the loop (it does not get reset), it is an index one past the max,
// i.e. it is the degree of this ItemExpr -- which will equal arity for all(?)
// items except ItemList (arity 2, arbitrary degree).
// If this ItemExpr returns a node different than 'this' in its bindNode,
// its bindNode must explicitly save this currChildNo degree if needed.
//
void ItemExpr::bindSelf(BindWA *bindWA)
{
  if (nodeIsBound()) return;

  // defaultSpecBoundAsSQLnull is needed only for our Tandem extension
  // of allowing DEFAULT to appear in item expressions
  // *except* when the DEFAULT value is NULL:
  //   INSERT INTO t(a,b) VALUES(DEFAULT,DEFAULT+1)
  //   -- DEFAULT for A is ok always, even if A is DEFAULT NULL,
  //   -- DEFAULT+1 for B is ok, *unless* B is DEFAULT NULL.
  // Couldn't catch the disallowed NULL+1 earlier in checkForSQLnullChild
  // because didn't know DEFAULT was NULL then, but no big deal, since
  // DEFAULT+1 and its ilk are allowed only as a Tandem extension anyway.
  //
  NABoolean defaultSpecBoundAsSQLnull = FALSE;

  for (Int32 i = 0; i < getArity(); i++, currChildNo()++) {
   
    ItemExpr *boundExpr = child(i)->bindNode(bindWA);
    if (bindWA->errStatus()) 
      return;
    if (! boundExpr)
      {
        bindWA->setErrStatus();
        return;
      }

    if (boundExpr->getOperatorType() == ITM_CONSTANT &&
        ((ConstValue *)boundExpr)->isNullWasDefaultSpec())
      defaultSpecBoundAsSQLnull = TRUE;

    child(i) = boundExpr;
      
  }

  //##? Should   getOperatorType() != ITM_CAST		?##
  //##? be	!getOperator().match(ITM_ANY_CAST)	?##
  if (defaultSpecBoundAsSQLnull)
    if (getOperatorType() != ITM_ASSIGN		 &&
        getOperatorType() != ITM_CAST		 &&
        getOperatorType() != ITM_EXPLODE_VARCHAR &&  // Genesis 10-980402-1556
        getOperatorType() != ITM_ITEM_LIST)
      checkForSQLnullChild(bindWA, this, FALSE, DEFAULT_BOUND_AS_NULL_);

  markAsBound();
} // ItemExpr::bindSelf()


  // Relaxation on an item expression is necessary if some of its
  // character-typed children are associated with character set values such
  // that the ANSI character type matching rule is violated for the expression.
  //
  // Relaxation can be done for an item expression, if it is either
  // 1) a character hostvar with UCS2 charset, or
  // 2) a SQL string function that returns an UCS2 result, and all
  //    character-typed operands of the function are relaxable.
  //
  // To perform the relaxation for a non-Translate relexable expression, add
  // a translate node (UCS2->ISO88591) on top of it. For a translate node,
  // simply remove the expression.
  //
  // Assume hostvar a, b and c are defined as
  //   char CHARACTER SET IS UCS2 a[10]
  //   char CHARACTER SET IS UCS2 b[1]
  //   char CHARACTER SET IS ISO88591 c[1]
  //
  // Examples of relexable item expressions:
  //    :a        // :a is an UCS2 hostvar
  //    :b        // :b is an UCS2 hostvar
  //    trim(:a)  // trim(:a) produces an UCS2 resulta, :a is relaxable.
  //    upper(:a) // upper(:a) produces an UCS2 result, :a is relaxable.
  //    repeat(:b, 10) // repeat(:b, 10) produces an UCS2 result,
  //                   // :b (the only character operand of the function)
  //                   // is relaxable.
  //
  // Examples of non-relexable item expressions:
  //    :c                        // :c is not an UCS2 host variable.
  //    concat(:a, 'b')           // 'b' is not a relaxable child of concat().
  //    replace(:a, _ucs2'b', _ucs2'z') // both _ucs2'b' and _ucs2'z'are not
  //                                    // relaxable.
  //

// A generic routine to relax ANSIcharacter-type matching rule for Static Inputs
//
// Always return this.
ItemExpr* ItemExpr::tryToRelaxCharTypeMatchRules(BindWA *bindWA)
{

  Int32 ucs2s = 0;
  CharInfo::CharSet cs = CharInfo::UnknownCharSet;

  // determine whether the ANSI character type matching rule is violated
  for (Int32 i = 0; i < getArity(); i++) {

    const NAType& type = child(i)->getValueId().getType();

    if ( type.getTypeQualifier() == NA_CHARACTER_TYPE )
    {
       switch (((const CharType&)type).getCharSet())
       {
        case CharInfo::UNICODE :
          ucs2s++;
          break;

        case CharInfo::KANJI_MP:
        case CharInfo::KSC5601_MP:
                 // can not perform relaxation on non-ISO88591 charsets.
          return this;

        case CharInfo::ISO88591:
        default:
          if (cs == CharInfo::UnknownCharSet)
             cs = ((CharType&)type).getCharSet();
          break;
       }
    }
  }

  if ( cs != CharInfo::UnknownCharSet && ucs2s > 0 )
   // ANSI rule is violated, try to perform relaxation
    return performRelaxation(cs, bindWA);
  else
   // relaxation not needed
    return this;
}

// Always return this.
ItemExpr* ItemExpr::performRelaxation(CharInfo::CharSet cs, BindWA *bindWA)
{
  // perofrm relaxation on any relaxable child
  for (Int32 i = 0; i < (Int32) currChildNo(); i++) {
     if ( ((ItemExpr*)child(i)) -> isCharTypeMatchRulesRelaxable() )
     {
        // for R2 FCS, the target is fixed at 88591. With Phase II work, it is
        // possible to set the target charset in Translator cstr.

	ItemExpr * newTranslateChild =
           new (bindWA->wHeap()) Translate(child(i), Translate::UNICODE_TO_ISO88591);

        newTranslateChild = newTranslateChild->bindNode(bindWA);
	if (bindWA->errStatus())
            return this;

	setChild(i, newTranslateChild);
     }
  }
  return this;
}


Int32 find_translate_type( CharInfo::CharSet src_cs,   // Source charset 
                           CharInfo::CharSet dest_cs ) // Destination charset 
{
     Int32 tran_type  = Translate::UNKNOWN_TRANSLATION;

     switch( dest_cs )
     {
        case CharInfo::ISO88591:
             switch( src_cs )
             {
                case CharInfo::UCS2:
                     tran_type = Translate::UNICODE_TO_ISO88591;
                     break;
                case CharInfo::UTF8:
                     tran_type = Translate::UTF8_TO_ISO88591;
                     break;
                case CharInfo::SJIS:
                     // tran_type = Translate::SJIS_TO_ISO88591;
                     break;
             }
             break;
        case CharInfo::UCS2:
             switch( src_cs )
             {
                case CharInfo::UTF8:
                     tran_type = Translate::UTF8_TO_UCS2;
                     break;
                case CharInfo::ISO88591:
                     tran_type = Translate::ISO88591_TO_UNICODE;
                     break;
                case CharInfo::SJIS:
                     tran_type = Translate::SJIS_TO_UCS2;
                     break;
             }
             break;
        case CharInfo::UTF8:
             switch( src_cs )
             {
                case CharInfo::UCS2:
                     tran_type = Translate::UCS2_TO_UTF8;
                     break;
                case CharInfo::ISO88591:
                     tran_type = Translate::ISO88591_TO_UTF8;
                     break;
                case CharInfo::SJIS:
                     tran_type = Translate::SJIS_TO_UTF8;
                     break;
             }
             break;
        case CharInfo::SJIS:
             switch( src_cs )
             {
                case CharInfo::UCS2:
                     tran_type = Translate::UCS2_TO_SJIS;
                     break;
                case CharInfo::ISO88591:
                     // tran_type = Translate::ISO88591_TO_SJIS;
                     break;
                case CharInfo::UTF8:
                     tran_type = Translate::UTF8_TO_SJIS;
                     break;
             }
             break;
     }
     return tran_type;
}

//
// For each character child node (of node pointed to by 'this') that has
// a different character set than the 'cs' argument, we must do something
// to convert the child to the 'cs' character set.  
//
// For children that are character string constants, we can do the actual
// translation here in the Compiler (UTF8->UCS2 or UCS2->UTF8).  If we
// later want to do something similar for the SJIS or ISO88591 configurations,
// we might have to restrict this and do the translation here in the compiler
// ONLY IF the string is all ASCII characters or something like that.
// For Seaquest platform (using the True ISO88591 configuration), the
// translation is between ISO88591 and UCS2, and we issue error messages
// when the translation fails.
//
// For children that are Translate nodes, we may be able to *delete* the
// Translate node in order to get the correct character set.
//
// For some child nodes that are functions, we may be able to push the
// translation operation down to the children of those functions.  We 
// expecially want to do this if the children of those functions are
// string constant nodes.
//
// For all other cases, we insert a Translate node between the 'this'
// node and the child node.
//
// Always return this.
//
ItemExpr* ItemExpr::performImplicitCasting(CharInfo::CharSet cs, BindWA *bindWA)
{
  if ( getOperatorType() == ITM_INSTANTIATE_NULL ||
       getOperatorType() == ITM_BITMUX )           // Don't want translate node
     return this;                                  // below one of these.


  ItemExpr *result = this;

  // If we are dealing with an expression that already has been assigned a ValueId,
  // it may be shared with other ItemExpr trees, therefore we need to make a copy
  // and can't modify it or its children.
  // Note that when we call this method from tryToDoImplicitCasting(), "this"
  // is an expression that does not yet have a value id. In this case, the
  // method will return "this", but maybe with modified children.
  if (getValueId() != NULL_VALUE_ID)
     result = copyTopNode();

  for (Int32 i = 0; i < getArity(); i++)
  {
     // initialize the result's child, assuming for now that it won't change
     if (result != this)
        result->setChild(i, getChild(i));

     const NAType& type = child(i)->getValueId().getType();
     if ( type.getTypeQualifier() != NA_CHARACTER_TYPE )
        continue; // Skip non-char types

     CharInfo::CharSet child_cs = ((const CharType&)type).getCharSet() ;
     if ( child_cs != CharInfo::ISO88591 && child_cs != CharInfo::UNICODE &&
          child_cs != CharInfo::UTF8     && child_cs != CharInfo::SJIS )
        continue;

     // If child is already in desired charset, then skip it.
     if ( child_cs == cs )
        continue;

     CharInfo::CharSet  desired_cs    = cs;

     enum cnv_charset eCnvCS = convertCharsetEnum(desired_cs);
     enum cnv_charset eCnvChild_cs = convertCharsetEnum(child_cs);

     Int32 tran_type = find_translate_type( child_cs, desired_cs );

     if ( tran_type == Translate::UNKNOWN_TRANSLATION )
        continue;

     // Remove a Translate node when appropriate (insteading of adding
     // another one to undo the existing one.)
     //
     OperatorTypeEnum chld_opertyp = child(i)->getOperatorType();
     if ( chld_opertyp == ITM_TRANSLATE )
     {
        Translate * Trans_node = (Translate *) ( child(i)->castToItemExpr() );
        ItemExpr * grandchild = Trans_node->child(0);

        const NAType& gr_type = grandchild->getValueId().getType();
        CharInfo::CharSet gr_child_cs = ((const CharType&)gr_type).getCharSet() ;

        if ( gr_child_cs == cs ) // If true, delete Translate node!
        {
           // Make the copy become this Translate Node's child
           result->setChild(i, grandchild);
           continue; //Go on to deal with next child
        }

     }  // end: if child(i) is an ITM_TRANSLATE

     else if ( chld_opertyp == ITM_CONSTANT )
     {
        NABoolean    cv_is_NULL ;
        Lng32         cv_StorageSize ;
        const char * cv_ConstValue;
        ValueId      cv_ValueId ;

        ConstValue * new_cv ;
          
        ConstValue * cv ;
        cv = (ConstValue*)(child(i)->castToItemExpr());
        cv_is_NULL = cv->isNull();
        cv_StorageSize = cv->getStorageSize() - cv->getType()->getVarLenHdrSize();
        cv_ConstValue  = (const char *)(cv->getConstValue());
        cv_ValueId     = cv->getValueId();

        if ( cv_is_NULL )
        {
           new_cv = new (bindWA->wHeap()) ConstValue() ;
        }
        else
        {
           // First find length of constant string in characters.
           // Also find length of result string in bytes.
           //
           Int32 byte_offset = 0;
           Int32 cv_len_in_chars = 0;
           Int32 rslt_len_in_bytes = 0;
           while ( byte_offset < cv_StorageSize )
           {
              Int32 firstCharLenInBuf;
              UInt32 UCS4value;
              firstCharLenInBuf = LocaleCharToUCS4(&cv_ConstValue[byte_offset],
                                                   cv_StorageSize - byte_offset,
                                                   &UCS4value,
                                                   eCnvChild_cs);
              if(firstCharLenInBuf < 0)
                {
                  *CmpCommon::diags() << DgSqlCode(-2109)
                                      << DgString0(CharInfo::getCharSetName(child_cs))
                                      << DgString1("UCS4") 
                                      << DgInt0(cv_len_in_chars)
                                      << DgInt1((Int32)(byte_offset));
                   bindWA->setErrStatus();
                   break;
              }
              byte_offset += firstCharLenInBuf;
              cv_len_in_chars++;

              Int16 tmpBuf[4];
              Int32 len_in_bytes = UCS4ToLocaleChar(&UCS4value,
                                                    (char *)tmpBuf, 8,
                                                    eCnvCS);
              if (len_in_bytes < 0)
                {
                  *CmpCommon::diags() << DgSqlCode(-2109)
                                      << DgString0(CharInfo::getCharSetName(child_cs))
                                      << DgString1(CharInfo::getCharSetName(desired_cs))
                                      << DgInt0(cv_len_in_chars)
                                      << DgInt1((Int32)(byte_offset));
                  bindWA->setErrStatus();
                   break;
              }
              rslt_len_in_bytes += len_in_bytes;
           }
           //
           // Now we know the exact length of the output buffer and
           // the length of the string (in chars!)
           //
           Int32 out_length = rslt_len_in_bytes +
                              ( (desired_cs == CharInfo::UNICODE) ?  2 : 1 );
           char * tmpbufr = new(bindWA->wHeap()) char[out_length];

           Int32 rslt_len = 0;

           byte_offset = 0;
           while ( byte_offset < cv_StorageSize )
           {
              Int32 firstCharLenInBuf;
              UInt32 UCS4value;
              firstCharLenInBuf = LocaleCharToUCS4(&cv_ConstValue[byte_offset],
                                                   cv_StorageSize - byte_offset,
                                                   &UCS4value,
                                                   eCnvChild_cs);
              if(firstCharLenInBuf < 0)
                   break; // Error would have already been reported above

              byte_offset += firstCharLenInBuf;
              Int32 len_in_bytes = UCS4ToLocaleChar(&UCS4value,
                                                    tmpbufr + rslt_len,
                                                    8, eCnvCS);
              if (len_in_bytes < 0)
                   break; // Error would have already been reported above

              rslt_len += len_in_bytes;
           }

           if ( desired_cs == CharInfo::UCS2 )
           {
             NAWString tmpStr;
             // Instead of using
             //         NAWString tmpStr = (NAWchar *)tmpbufr;
             // use NAWString::append() method in case tmpbufr contains
             // many consecultive embedded binary zero bytes that
             // look like the NAWchar NULL terminator(s).
             tmpStr.append((NAWchar *)tmpbufr, (size_t)cv_len_in_chars);
             NADELETEBASIC(tmpbufr, bindWA->wHeap()); tmpbufr = NULL;
             new_cv = new (bindWA->wHeap()) ConstValue( tmpStr,
                    CharInfo::UNICODE, CharInfo::DefaultCollation, CharInfo::COERCIBLE );
           }
           else
           {
              *(tmpbufr + rslt_len) = 0; // Add a trailing Null
              NAString tmpStr = tmpbufr;
              NADELETEBASIC(tmpbufr, bindWA->wHeap()); tmpbufr = NULL;
              new_cv = new (bindWA->wHeap()) ConstValue( tmpStr,
                    desired_cs, CharInfo::DefaultCollation, CharInfo::COERCIBLE);
           }
        }

        ItemExpr   * new_chld_ie = new_cv->bindNode(bindWA);
        if ( cv_is_NULL )
        {
           CharType myCharType = (const CharType&)type;
           Int32 bytesPerCh = myCharType.getBytesPerChar();
           NAType * newType = new (HEAP) SQLChar(HEAP, 
                           ( cv_ValueId == NULL_VALUE_ID )
                           ? 0 : type.getNominalSize()/bytesPerCh,
                             TRUE, FALSE, FALSE, FALSE,
                             cs,                         // The target charset
                             CharInfo::DefaultCollation,
                             CharInfo::COERCIBLE );
           ValueId theId = new_cv->getValueId();
           theId.coerceType(*newType);
           new_cv->changeType(newType);
        }

        ConstValue* new_chld_cv = dynamic_cast<ConstValue*>(new_chld_ie);

        CURRENTQCACHE->getHQC()
             ->collectBinderRetConstVal4HQC
                 ((ConstValue*)(child(i)->castToItemExpr()), new_chld_cv);
        
        result->setChild(i, new_chld_ie);

        continue; //Go on to deal with next child

     }    // end:  ITM_CONSTANT

     else if ( child(i)->getArity() > 0 ) // If it has child nodes
     {
        if ( child(i)->shouldPushTranslateDown(cs) >= 0 )
        {
           result->setChild(i, child(i)->performImplicitCasting(cs, bindWA));
           continue; //Go on to deal with next child

        }  // end: if ( child(i)->shouldPushTranslateDown(cs) >= 0 )
     }     // end: if ( child(i)->getArity() > 0 )

     ItemExpr * newTranslateChild =
        new (bindWA->wHeap()) Translate(child(i), tran_type );

     newTranslateChild = newTranslateChild->bindNode(bindWA);
     if (bindWA->errStatus())
        return this;
     result->setChild(i, newTranslateChild);

  }  //end of for loop (for each child node)

  if ( result->getOperatorType() == ITM_CAST )
  {
     // Must fix up the Cast's target type field
     const NAType *targetType = ((Cast *)result)->getType();
     NAType * newCastType = targetType->newCopy(bindWA->wHeap());
     CharType * newChCastType = (CharType *) newCastType;
     newChCastType->setCharSet(cs) ;
     newChCastType->setBytesPerChar(CharInfo::maxBytesPerChar(cs)) ;
     ((Cast *)result)->changeType(newCastType);
  }

  if (result != this && nodeIsBound() && getValueId() != NULL_VALUE_ID)
  {
     // if this node is already bound (not just marked as bound, but completely
     // bound with a value id assigned), then bind the new result as well
     result->bindNode(bindWA);
  }

  return result;
}

//
// This method tries to determine whether or not it is a good idea
// to push the Translate operation down to the children of the 'this'
// node.  Returns:
//        + num   if this is a good idea
//        0       if this is not a good idea
//        - num   if this is a bad idea (or not even possible)
//
Int32 ItemExpr::shouldPushTranslateDown(CharInfo::CharSet chrset) const
{
   Int32 Goodness = 1; // Good if number of Translate Nodes would not increase
   NABoolean sawChildWithDiffCS = FALSE;

   // Exclude all ItemExprs with arity > 1 that possibly produce character
   // output, have children with possibly a character type, and have at least
   // one of the following:
   //
   //  a) A fixed output charset, so pushing the translate down would
   //     have no effect. Examples: CAST, ENCODE.
   //  b) The semantics of the operator may depend on the character set.
   //     Examples: MIN, MAX, LIKE.
   //  c) the operator isn't well-enough understood to push the translate
   //     down below it. Example: ITM_USER_DEF_FUNCTION.
   //  d) Other reasons.

   // For any ItemExpr do not push a CAST node down the ItemExpr tree
   // if the ItemExpr itself is the output of a groupby. This is needed
   // because the components of a grouped expression are likely not available
   // above the groupby. Pushing the CAST down a group expression forces
   // the generator to look for parts of the group exptresion in nodes where
   // they are typically not available.
   if (isGroupByExpr())
     return -1 ;

   switch (getOperatorType())
     {
     case ITM_BITMUX:                // d) mixes separate item expressions together
     case ITM_MAX:                   // b) ordering, also may eliminate data
     case ITM_MIN:                   // b) ordering, also may eliminate data
     case ITM_MAX_ORDERED:           // b) ordering, also may eliminate data
     case ITM_MIN_ORDERED:           // b) ordering, also may eliminate data
     case ITM_USER_DEF_FUNCTION:     // c) may or may not depend on charset
     case ITM_COMP_ENCODE:           // a), b) output is binary disguised as ISO
     case ITM_COMP_DECODE:           // a), b) output is binary disguised as ISO
     case ITM_MOVING_MAX:            // b) possibly different orderings
     case ITM_MOVING_MIN:            // b) possibly different orderings
     case ITM_SCALAR_MIN:            // b) ordering, also may eliminate data
     case ITM_SCALAR_MAX:            // b) ordering, also may eliminate data
     case ITM_OLAP_MAX:              // b) ordering, also may eliminate data
     case ITM_OLAP_MIN:              // b) ordering, also may eliminate data
     case ITM_CONVERTTOHEX:          // b) operator depends on encoding
     case ITM_CONVERTFROMHEX:        // b) produces a specific encoding
     case ITM_TOKENSTR:              // b) implementation assumes all same 
     case ITM_SUBSTR_DOUBLEBYTE:     // b) operator specific to UCS2
     case ITM_LIKE_DOUBLEBYTE:       // b) operator specific to UCS2
     case ITM_UPPER_UNICODE:         // b) operator specific to UCS2
     case ITM_LOWER_UNICODE:         // b) operator specific to UCS2
     case ITM_REPLACE_UNICODE:       // b) operator specific to UCS2
     case ITM_INSTANTIATE_NULL:      // d) caused test failures
     case ITM_QUERYID_EXTRACT:       // a) output is always ISO88591
     case ITM_NARROW:                // b) NARROW may want to catch conversion errors
     case ITM_CONVERT:               // a) internal node, too late to do ICAT
     case ITM_CAST:                  // a) output is of a specific charset
     case ITM_CAST_CONVERT:          // a) internal node, too late to do ICAT
     case ITM_CAST_TYPE:
     case ITM_DATEFORMAT:
     case ITM_REVERSE:
       return -1;

     case ITM_LEFT:                  // b) counts characters
     case ITM_RIGHT:                 // b) counts characters
     case ITM_LIKE:                  // b) counts characters
     case ITM_REGEXP:                  // b) counts characters
     case ITM_SUBSTR:                // b) counts characters
     case ITM_REPLACE:               // b) counts characters
     case ITM_INSERT_STR:            // b) counts characters
       {
         // Some operators produce subtle differences when used on UTF-16 surrogate
         // pairs instead of 4-byte UTF-8 characters. Don't open that can of worms.
         const NAType&     myType    = getValueId().getType();
         CharInfo::CharSet myCharset = CharInfo::UnknownCharSet;

         if (myType.getTypeQualifier() == NA_CHARACTER_TYPE)
           myCharset = ((const CharType &) myType).getCharSet();

         if ((chrset    == CharInfo::UCS2 &&
              myCharset == CharInfo::UTF8)
             ||
             (myCharset == CharInfo::UCS2 &&
              chrset    == CharInfo::UTF8))
           return -1;
       }

     default:
       ; // go on, it's ok to push the translate operator down
     }

   for (Int32 ii = 0 ; ii < getArity(); ii++ )
   {
      const NAType& type = child(ii)->getValueId().getType();
      if ( type.getTypeQualifier() != NA_CHARACTER_TYPE )
         continue; // Skip non-char types

      if ( ((const CharType&)type).getCharSet() == chrset )
         continue; // Skip children with desired character set

      sawChildWithDiffCS = TRUE;

      switch ( child(ii)->getOperatorType() )
      {
         case ITM_CONSTANT: // Node should be changed to new character set.
            Goodness++ ;    // and may allow optimizer to eval at Compile time
            continue;
         case ITM_TRANSLATE:
            Goodness++ ; // Good since node would be removed if we did push down.
            continue;

         case ITM_BASECOLUMN:
         case ITM_VALUEIDUNION:
         case ITM_ROW_SUBQUERY:
         case ITM_IN_SUBQUERY:
            Goodness-- ; // Bad since we would add a Translate node for this.
            continue;

         default:
         Int32 chld_goodness = child(ii)->shouldPushTranslateDown(chrset) ;
         if ( chld_goodness < 0 )
            Goodness = 0; // Cannot push down any lower (at least for now)
         else if ( chld_goodness > 1 )
            Goodness++ ;
         continue;
      }
   }
   if (sawChildWithDiffCS == FALSE )
      Goodness = -1;     //Pushing Translate down is not possible
   return ( Goodness );
}

// A special routine to relax ANSI character-type matching rule for binary comparison
// operators for Static Inputs, due to special internal representation for such
// operators.
//
// Aleays return this.
ItemExpr* BiRelat::tryToRelaxCharTypeMatchRules(BindWA *bindWA)
{
   ItemExpr *x = (ItemExpr*)child(0);
   ItemExpr *xy= (ItemExpr*)child(1);

   // if both children are not list type, just relax both
   if (x-> getOperatorType() != ITM_ITEM_LIST &&
        xy-> getOperatorType() != ITM_ITEM_LIST
      )
     return ItemExpr::tryToRelaxCharTypeMatchRules(bindWA);

   // handle the comparison bwt two lists
   if ( x-> getOperatorType() == ITM_ITEM_LIST &&
        xy-> getOperatorType() == ITM_ITEM_LIST )
   {
      NAMemory *heap = CmpCommon::statementHeap();

      // collect the leaves from the two trees into two lists
      ExprValueIdList* leafList1 =
          ((ItemList*)(x)) -> collectLeaves(heap);
      ExprValueIdList* leafList2 =
          ((ItemList*)(xy)) -> collectLeaves(heap);

      // can not relax if both lists are not of same length
      if ( leafList1 -> entries() != leafList2 -> entries() )
         return this;

      // relax by pairs
      for ( Int32 i=0; i<leafList1 -> entries(); i++ ) {
         if ( performRelaxation((*leafList1)[i], (*leafList2)[i], bindWA) == FALSE )
           return this; // If one pair can not be made to be type-compatible, return
                        // right away. The type synthesise code will flag the
                        // type mismatch error.
      }
   }
   return this;
}

// This routine is a helper function to BiRelat::tryToRelaxCharTypeMatchRules().
// It linearizes the item expression tree by collecting the address of leave
// nodes into a list. The list is returned.
ExprValueIdList*
ItemList::collectLeaves(CollHeap* heap, ExprValueIdList* list)
{
   if ( list == NULL )
      list = new (heap) ExprValueIdList(heap);

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

     ItemExpr* c = this->child(i);
     if ( c )  {

       if ( ((ItemExpr*)child(i)) -> getOperatorType() != ITM_ITEM_LIST )
          list->insert(&child(i));
       else 
          return ((ItemList*)((ItemExpr*)child(i))) -> collectLeaves(heap, list);
     
     }
   }

   return list;
}

void ItemList::setResolveIncompleteTypeStatus(NABoolean x)
{
   for ( Int32 i=0; i<getArity(); i++ ) {
       ItemExpr* child = this->child(i);
       if ( child )
         child -> setResolveIncompleteTypeStatus(x);
   }
}

// This routine is a helper function to BiRelat::tryToRelaxCharTypeMatchRules().
// It performs the relaxation.
NABoolean
ItemExpr::performRelaxation(ExprValueId* ie1, ExprValueId* ie2, BindWA *bindWA)
{
   const NAType *operand1 = &(ie1->getValueId()).getType();
   const NAType *operand2 = &(ie2->getValueId()).getType();

   if ( operand1 -> getTypeQualifier() != NA_CHARACTER_TYPE ||
        operand2 -> getTypeQualifier() != NA_CHARACTER_TYPE
      )
     return TRUE;

   const CharType *charOp1 = (CharType*)operand1;
   const CharType *charOp2 = (CharType*)operand2;

   // pointer to the node to be translated (relaxed)
   ExprValueId* nodeToTranslatePtr = NULL;

   if (  (ie1->getPtr()) -> isCharTypeMatchRulesRelaxable() &&
         charOp2->getCharSet() == CharInfo::ISO88591
      )
   {
      nodeToTranslatePtr = ie1; // the left node should be translated
   } else
   if ( (ie2->getPtr()) -> isCharTypeMatchRulesRelaxable() &&
        charOp1->getCharSet() == CharInfo::ISO88591
      )
   {
      nodeToTranslatePtr = ie2; // the right node should be translated
   }

   if ( nodeToTranslatePtr != NULL )
   {
      ItemExpr * newTranslateChild =
         new (CmpCommon::statementHeap()) Translate(
                 nodeToTranslatePtr->getPtr(),
                 Translate::UNICODE_TO_ISO88591
                                           );

      newTranslateChild = newTranslateChild->bindNode(bindWA);
      if (bindWA->errStatus())
         return FALSE;

      *nodeToTranslatePtr = newTranslateChild;

      return TRUE;
   }

   return FALSE;
}

// special relax code because we want to handle Code_Value(:ucs_hv)
ItemExpr* CodeVal::tryToRelaxCharTypeMatchRules(BindWA *bindWA)
{
   if ( (getOperatorType() == ITM_ASCII || getOperatorType() == ITM_CODE_VALUE)
       && ((ItemExpr*)child(0)) -> isCharTypeMatchRulesRelaxable()
      )
   {
     return performRelaxation(CharInfo::ISO88591, bindWA);
   }
   return this;
}

// special relax code because we want to handle
// Translate(:ucs_hv using ISO88591TOUCS2)
ItemExpr* Translate::tryToRelaxCharTypeMatchRules(BindWA *bindWA)
{
   if ( getTranslateMapTableId() == Translate::ISO88591_TO_UNICODE &&
        ((ItemExpr*)child(0)) -> isCharTypeMatchRulesRelaxable()
      )
   {
     // just return the child(0) because this translate is not
     // necessary and we want to avoid double 1-to-1 translation
     return (ItemExpr*)child(0);
   }
   return this;
}

// special "relaxable" test for assign. Return true if the target is
// an UCS2 hostvar and the source is ISO88591.
NABoolean Assign::isRelaxCharTypeMatchRulesPossible()
{
   if ( getTarget().getType().getTypeQualifier() == NA_CHARACTER_TYPE &&
        getSource().getType().getTypeQualifier() == NA_CHARACTER_TYPE &&
        getSource().getItemExpr() -> isCharTypeMatchRulesRelaxable()
       )
   {
      const CharType& sourceCT = (const CharType&)getSource().getType();
      const CharType& targetCT = (const CharType&)getTarget().getType();

      if ( sourceCT.getCharSet() == CharInfo::UNICODE &&
           targetCT.getCharSet() == CharInfo::ISO88591
         )
        return TRUE;
   }
   return FALSE;
}

ItemExpr* Assign::tryToRelaxCharTypeMatchRules(BindWA *bindWA)
{
   return performRelaxation(CharInfo::ISO88591, bindWA);
}

// A generic routine to attempt Implicit Casting/Translation of
// child nodes to the character set required by the context.
//
// Always return this.
//
ItemExpr* ItemExpr::tryToDoImplicitCasting(BindWA *bindWA)
{
  ItemExpr *result = this;
  enum {iUCS2 = 0, iISO = 1, iUTF8 = 2, iSJIS = 3, iGBK = 4, iUNK = 5};
  Int32 Literals_involved[6] = { 0, 0, 0, 0, 0, 0};
  Int32 nonLiterals_involved[6] = { 0, 0, 0, 0, 0, 0 };
  Int32 charsets_involved[6] = { 0, 0, 0, 0, 0, 0 };
  Int32 charsetsCount = 0;
  CharInfo::CharSet cs          = CharInfo::UnknownCharSet;
  CharInfo::CharSet curr_chld_cs= CharInfo::UnknownCharSet;
  CharInfo::CharSet chld0_cs    = CharInfo::UnknownCharSet;
  OperatorTypeEnum  chld0_opType     = ITM_FIRST_ITEM_OP;
  OperatorTypeEnum  curr_chld_opType = ITM_FIRST_ITEM_OP;

  Int32 arity = getArity();
  if (arity <= 0)       // This method works only if there are children
     return this;
  //
  // First we must determine the best target character set to use
  // given the context.
  //
  // Step 1: Determine if we have children with different character set attributes
  //
  for (Int32 i = 0; i < arity; i++) {
    
    const NAType& type = child(i)->getValueId().getType();
    if ( type.getTypeQualifier() == NA_CHARACTER_TYPE )
      {
        curr_chld_cs = ((const CharType&)type).getCharSet();
        if ( i==0 ) chld0_cs = curr_chld_cs;  // Remember this one

        Int16 cur_chld_cs_ndx = iUNK;

        switch ( curr_chld_cs )
          {
          case CharInfo::UNICODE :
            cur_chld_cs_ndx = iUCS2;
            break;

          case CharInfo::ISO88591:
            cur_chld_cs_ndx = iISO;
            break;

          case CharInfo::UTF8:
            cur_chld_cs_ndx = iUTF8;
            break;

          case CharInfo::SJIS:
            cur_chld_cs_ndx = iSJIS;
            break;

          case CharInfo::GBK:
            cur_chld_cs_ndx = iGBK;
            break;

            //case CharInfo::KANJI_MP:
            //case CharInfo::KSC5601_MP:
          default:
            break; // Can not translate these currently.
          }
        charsets_involved[cur_chld_cs_ndx]++;

        OperatorTypeEnum curr_chld_opType = child(i)->getOperatorType();
        if (i == 0 ) chld0_opType = curr_chld_opType;  // Remember this one

        if ( curr_chld_opType == ITM_CONSTANT )
          Literals_involved[cur_chld_cs_ndx] += 1 ;
        else
          nonLiterals_involved[cur_chld_cs_ndx] += 1 ;
      }
      
  }

  for (Int32 j = 0; j < iUNK; j++)
  {
    if (charsets_involved[j] > 0)
      charsetsCount++;
  }

  if (charsetsCount > 1)
  {
    // Now choose the best character set for the translations

    cs = CharInfo::ISO88591;

    if ( ! CanChild0BeImplicitlyCast() )
    {
       // Looks like an Assign operation, so use child 0's cs
       cs = chld0_cs;
    }
    else 
    {
       if ( nonLiterals_involved[iUCS2] > 0 )
          cs = CharInfo::UCS2;
       else if ( nonLiterals_involved[iUTF8] > 0 )
          cs = CharInfo::UTF8;
       else if ( nonLiterals_involved[iSJIS] > 0 )
          cs = CharInfo::SJIS;
       else if ( Literals_involved[iUCS2] > 0 )
          cs = CharInfo::UCS2;
       else if ( Literals_involved[iUTF8] > 0 )
          cs = CharInfo::UTF8;
       else if ( Literals_involved[iSJIS] > 0 )
          cs = CharInfo::SJIS;
       else if ( Literals_involved[iGBK] > 0 )
          cs = CharInfo::GBK;

       //
       // Now, we may be able to optimize by translating the 1st child
       // rather than the 2nd.  For now, we consider only the case
       // when there are exactly 2 children (e.g. WHERE predicate)
       //
       if ( ( cs == chld0_cs ) &&  ( arity == 2 ) &&
               ( curr_chld_opType != ITM_TRANSLATE ) &&
               ( charsetsCount == (charsets_involved[iUCS2] + charsets_involved[iUTF8] + charsets_involved[iGBK]) ) )
       {
          if ( chld0_opType == ITM_TRANSLATE )
             cs = curr_chld_cs;  //...because we will eliminate a translate op
          else
          if ( CanChild0BeImplicitlyCast()      &&
             ( chld0_opType != ITM_BASECOLUMN ) )
          {
             if ( child(0)->shouldPushTranslateDown( curr_chld_cs ) >
                  child(1)->shouldPushTranslateDown( cs ) )
             {  // If translating to curr_chld_cs is more beneficial
                cs = curr_chld_cs;
             }
          }
       }
    }

    result = performImplicitCasting(cs, bindWA);
  }
  else if ( getOperatorType() == ITM_CAST )
  {
     const NAType& chldType = child(0)->getValueId().getType();
     if ( chldType.getTypeQualifier() == NA_CHARACTER_TYPE )
     {
        CharInfo::CharSet chld_cs = ((const CharType&)chldType).getCharSet();

        const NAType *desiredType = ((Cast *)this)->getType();
        if ( desiredType->getTypeQualifier() == NA_CHARACTER_TYPE )
        {
           CharInfo::CharSet Desired_cs = ((const CharType*)desiredType)->getCharSet();
           /*
           * this is a special handling for jira 1720, only used in a bulkload scenario
           * that is, when user set the HIVE_FILE_CHARSET to 'gbk', it means the data saved in hive
           * table is encoded as GBK. Trafodion default all Hive data charset as 'UTF8', so 
           * this will allow the auto charset converting to happen during bulk load
           * the reason is:
           * hive scan will mark the source column as GBK when HIVE_FILE_CHARSET is set to GBK
           * which is the only value it can be 
           * So the bind will invoke this implicit casting method to check if an auto charset 
           * converting is needed. 
           * In the hive scan, it does not set the tgtCharSetSpecified field, so in order to 
           * force it to perform a translate, add a checking here
           */
           if( (chld_cs != Desired_cs) && CmpCommon::getDefaultString(HIVE_FILE_CHARSET) == "GBK" )
              result = performImplicitCasting( Desired_cs, bindWA );
           else if ( (chld_cs != Desired_cs) && ( ! ((Cast *)this)->tgtCharSetSpecified() ) )
           {
              //
              // Looks like user said CAST( ... as [var]char(NNN) ) 
              // without specifying charset.
              // Leave the child's charset alone and change desired type to match it.
              NAType * newType = desiredType->newCopy(bindWA->wHeap());
              CharType * newCType = (CharType *) newType;
              Int32 child_bpc = CharInfo::maxBytesPerChar(chld_cs);
              Int32 child_charLimit = ((const CharType&)chldType).getStrCharLimit();
              Int32 Desired_charLimit = ((const CharType*)desiredType)->getStrCharLimit();
  
              newCType->setCharSet(chld_cs) ;
              newCType->setBytesPerChar(child_bpc) ;
              newCType->setEncodingCharSet( ((const CharType&)chldType).getEncodingCharSet() );
              if ( chld_cs == CharInfo::UNICODE )
                  newCType->setDataStorageSize( Desired_charLimit * child_bpc );
              if ( (Desired_cs == CharInfo::ISO88591) &&
                   (chld_cs    == CharInfo::UTF8)
                 )
              {
                  // Assume user meant [var]char(nnn CHARS)
                  newCType->setDataStorageSize( Desired_charLimit * child_bpc );
              }
              ((Cast *)this)->changeType(newType); // Change the Cast's target type!

              if (getValueId() != NULL_VALUE_ID)
                  getValueId().changeType(newType);
              return this;
           }
           else if ( chld_cs != Desired_cs )  // New CharSet specified
           {
              result = performImplicitCasting( Desired_cs, bindWA );
           }
        }
     }
  }
  else if ( getOperatorType() == ITM_TRANSLATE )
  {
     CharInfo::CharSet Required_cs = CharInfo::UnknownCharSet;
     Translate *parent_tran = (Translate *) this;
     switch( parent_tran->getTranslateMapTableId() )
     {
        case Translate::ISO88591_TO_UNICODE:
        case Translate::ISO88591_TO_UTF8:
        // case Translate::ISO88591_TO_SJIS:
             Required_cs = CharInfo::ISO88591;
             break;
        case Translate::SJIS_TO_UNICODE:
        case Translate::SJIS_TO_UCS2:
        case Translate::SJIS_TO_UTF8:
        // case Translate::SJIS_TO_ISO88591:
             Required_cs = CharInfo::SJIS;
             break;
        case Translate::UTF8_TO_UCS2:
        case Translate::UTF8_TO_SJIS:
        case Translate::UTF8_TO_ISO88591:
             Required_cs = CharInfo::UTF8;
             break;
        case Translate::UNICODE_TO_ISO88591:
        case Translate::UNICODE_TO_SJIS:
        case Translate::UCS2_TO_SJIS:
        case Translate::UCS2_TO_UTF8:
             Required_cs = CharInfo::UNICODE;
             break;
	case Translate::GBK_TO_UTF8:
	     Required_cs = CharInfo::GBK;
             break;
        default:
             break;
     }
     if ( Required_cs == CharInfo::UnknownCharSet )
        return this; // Cannot do anything for this situation

     if ( child(0)->getOperatorType() == ITM_TRANSLATE ) // 1st child ?
     {
        const NAType& type = child(0)->child(0)->getValueId().getType();
        CharInfo::CharSet gr_chld_cs = ((const CharType&)type).getCharSet();
        if ( gr_chld_cs == Required_cs )
        {
           // We have an undesired TRANSLATE node, so we will remove it.

           ItemExpr *grnd_child = child(0)->child(0)->castToItemExpr();

           result->setChild(0, grnd_child);
        }
     }
     else if ( child(0)->getOperatorType() != ITM_BASECOLUMN )
     {
        const NAType& type = child(0)->getValueId().getType();
        if ( type.getTypeQualifier() == NA_CHARACTER_TYPE )
        {
           CharInfo::CharSet chld_cs = ((const CharType&)type).getCharSet();
           //
           // If the child is NOT of the required character set we need to
           // do Implicit Casting UNLESS the child is ISO88591 and the
           // Required_cs is a superset of ISO88591
           //
           if ( ( chld_cs != Required_cs ) &&
              ! ( ( chld_cs == CharInfo::ISO88591 ) && ( Required_cs == CharInfo::UTF8 ) )
              )
           {
              result = performImplicitCasting(Required_cs, bindWA); 
           }
        }
     }
     // else it is an ITM_BASECOLUMN.  We choose to give user an error,
     // so here we just return.

  }  // end of:  if ( getOperatorType() == ITM_TRANSLATE )

  // assumption is that we call this method before assigning a value id, and that
  // performImplicitCasting returns the object it has been called on
  CMPASSERT(result == this && getValueId() == NULL_VALUE_ID);

  return result; // No automatic translations to do.
}

ItemExpr *ItemExpr::bindNode(BindWA *bindWA)
{
  if (nodeIsBound()) return this;
  bindSelf(bindWA);
  if (bindWA->errStatus()) return this;

  ItemExpr* exp = this;

  // A quick way to determine whether we should worry about relaxation.
  // Only comparison and assign operators, SQL string functions are the
  // candidates.
  if ( isRelaxCharTypeMatchRulesPossible() )
  {
     // may return this or an modified expression. In either case, need to
     // perform the type synthesization.
     exp=tryToRelaxCharTypeMatchRules(bindWA);
     CMPASSERT(exp);
  }

  if ( getArity() > 0 || getOperatorType() == ITM_VALUEIDUNION)
  {
     // Might be possible to do some automatic translation of character sets
     //
     if (getOperatorType() != ITM_ITEM_LIST) // Ignore LISTs - no context yet!
     {
        if ( CmpCommon::getDefault(ALLOW_IMPLICIT_CHAR_CASTING) == DF_ON )
        {
           //User wants this (despite being rather non-ANSI standard)
           //so we will try to do so.

          exp = tryToDoImplicitCasting(bindWA);
          CMPASSERT(exp);
        }
     }
  }

  const NAType *type = exp->synthTypeWithCollateClause(bindWA);
  if (!type) return exp;
  setValueId(createValueDesc(bindWA, exp, type));
  return exp;
} // ItemExpr::bindNode()

//////////////////////////////////////////////////
// This function binds an item expression tree.
// After bindNode() returns, the completeness of
// the type of the expression is checked. Pushing
// down desired complete type may take place.
//////////////////////////////////////////////////

ItemExpr *ItemExpr::bindNodeRoot(BindWA *bindWA)
{
  ItemExpr* exp = bindNode(bindWA);

  if ( getResolveIncompleteTypeStatus() == FALSE )
      return exp;

// if the valudId is invalid or we are not bind the true root, 
// forget the pushdown type business
  if ( exp ==0 || exp->getValueId() == NULL_VALUE_ID ||
       bindWA->isBindTrueRoot() == FALSE
     )
     return exp;

  const NAType* type = &(exp->getValueId()).getType();

  if ( type->getTypeQualifier() == NA_CHARACTER_TYPE &&
       ((CharType*)type)->getCharSet() == CharInfo::UnknownCharSet
     )
  {

   // deal with cases where the item expression tree can not determine
   // the charset attribute by itself.
   // Example: select upper('abcd') from t;
   // Solution: we force ISO88591 throughout the tree here.
     const NAType* desired = CharType::desiredCharType(CharInfo::ISO88591);

     (exp->getValueId()).coerceType(*desired, NA_CHARACTER_TYPE);
     type = &(exp->getValueId()).getType();

// We only give one shot here.
     if ( type->getTypeQualifier() == NA_CHARACTER_TYPE &&
          ((CharType*)type)->getCharSet() == CharInfo::UnknownCharSet
        )
     {
        return 0;
     }
  }

  return exp;

} // ItemExpr::bindNodeRoot()

ItemExpr* ItemExpr::_bindNodeRoot(BindWA *bindWA)
{
  return 0;
}

ItemExpr * ItemExpr::foldConstants(BindWA *bindWA)
{
  // a shortcut to constant folding for use in the binder
  ItemExpr *result = foldConstants(CmpCommon::diags(), TRUE);
  if (CmpCommon::diags()->mainSQLCODE() < 0)
    bindWA->setErrStatus();
  return result;
}

ItemExpr * ItemExpr::bindUDFsOrSubqueries(BindWA *bindWA)
{

  // Method to bind only a UDF or Subquery node in an expr Tree. This
  // is used for assign expression in update to make sure we know the
  // the degree of the UDF/Subquery before we create assignment lists.
  
  switch (getOperatorType())
  {
    case ITM_ROW_SUBQUERY:
    {
      DefaultToken allowMultiDegreeTok =
                    CmpCommon::getDefault(ALLOW_MULTIDEGREE_SUBQ_IN_SELECTLIST);

      if (allowMultiDegreeTok == DF_ON ||
          allowMultiDegreeTok == DF_SYSTEM)
        return bindNode(bindWA); 
      else
        return this; // don't do anything.
      break;
    }
            
    case ITM_USER_DEF_FUNCTION:
      return bindNode(bindWA); 
      break;
            
    default:
      // Walk the rest of the tree.
      for (Int32 chld=0; chld < getArity(); chld++)
      {
        child(chld) = child(chld)->bindUDFsOrSubqueries(bindWA); 
      }
  }
  return this;
}

ItemExpr *AnsiUSERFunction::bindNode(BindWA *bindWA)
{
  if (bindWA->inDDL() && (bindWA->inCheckConstraintDefinition()))
  {
    StmtDDLAddConstraintCheck *pCkC = bindWA->getUsageParseNodePtr()
                                    ->castToElemDDLNode()
                                    ->castToStmtDDLAddConstraintCheck();
    *CmpCommon::diags() << DgSqlCode(-4132);
    bindWA->setErrStatus();
    return this;
  }

  if (nodeIsBound())
    return getValueId().getItemExpr();
  const NAType *type = synthTypeWithCollateClause(bindWA);
  if (!type) return this;

  // Multiple references to the USER function should return the same
  // user ID in one query, no matter which process it is being evaluated
  // (sqlci/esp/dp2).
  // So all occurrences of CURRENT USER functions are treated as input
  // values and are given the same value id.  Similarly, all occurrences
  // of SESSION USER function are given the same value id (but different
  // from that of the CURRENT USER).
  //
  ItemExpr * ie = ItemExpr::bindUserInput(bindWA,type,getText());
  if (bindWA->errStatus())
    return this;

  // add this value id to BindWA's input function list.
  bindWA->inputFunction().insert(getValueId());

  return ie;
}

ItemExpr *MonadicUSERFunction::bindNode(BindWA *bindWA)
{
  if (nodeIsBound())
    return getValueId().getItemExpr();

  // For now user(x) is allowed only in the top most select list
  // check that first, or else give an error

  BindScope * currScope = bindWA->getCurrentScope();
  BindContext *context = currScope->context();

  if (!(context->inSelectList()))
  {
    *CmpCommon::diags() << DgSqlCode(-4310)
			<< DgString0("USER(x)");
    bindWA->setErrStatus();
    return NULL;
  }

  // Check for case like select (select user(1) ...).
  // or select * from t1, (select user(x) from t1) t3 etc.
  // Here the user function is in the select list of a
  // sub-query and in join, hence is not allowed.
  // Also it is not allowed at any other place example orderBy
  BindScope *prevScope   = NULL;

  while (currScope)
  {
    BindContext *currContext = currScope->context();
    if (currContext->inSubquery() ||
      currContext->inOrderBy() ||
      currContext->inExistsPredicate() ||
      currContext->inGroupByClause() ||
      currContext->inWhereClause() ||
      currContext->inHavingClause() ||
      currContext->inUnion() ||
      currContext->inJoin()       )
    {
 	*CmpCommon::diags() << DgSqlCode(-4310)
			    << DgString0("USER(x)");
	bindWA->setErrStatus();
	return NULL;
    }
    prevScope = currScope;
    currScope = bindWA->getPreviousScope(prevScope);
  }

  bindSelf(bindWA);
  if (bindWA->errStatus()) return this;

  unBind();

  return ItemExpr::bindNode(bindWA);
} // MonadicUSERFunction::bindNode


// -----------------------------------------------------------------------
// BiRelat & Function classes set context flags, then call ItemExpr::bindNode
// (they are directly derived subclasses of ItemExpr; safe to invoke this)
// -----------------------------------------------------------------------

ItemExpr *BiRelat::bindNode(BindWA *bindWA)
{
  if (checkForSQLnullChild(bindWA, this, getSpecialNulls())) return this;
  ItemExpr *save = bindWA->getCurrentScope()->context()->inMultaryPred();
  bindWA->getCurrentScope()->context()->inMultaryPred() = this;

  //changes for HistIntRed

  //save the current state of inRangePred_ in the binder
  //context so that we can set it back after binding this
  //node in case we reset it the if statement below
  NABoolean inRangePredSave = bindWA->getCurrentScope()->context()->inRangePred();

  //get the operator
  OperatorTypeEnum oper = getOperatorType();

  //check if the operator implies a range predicate
  //this would be if the operator is <, >, <=, >=
  if((oper == ITM_LESS)||
     (oper == ITM_LESS_EQ)||
     (oper == ITM_GREATER)||
     (oper == ITM_GREATER_EQ))
    {
      bindWA->getCurrentScope()->context()->inRangePred() = TRUE;
    };
  bindWA->getCurrentScope()->context()->inPredicate() = TRUE;

  // this will bind/type-propagate all children.
  //bindChildren(bindWA);
  ItemExpr *boundExpr = ItemExpr::bindNode(bindWA);

  //set inRangePred_ in the context to original value
  bindWA->getCurrentScope()->context()->inRangePred() = inRangePredSave;
  bindWA->getCurrentScope()->context()->inMultaryPred() = save;

  bindWA->getCurrentScope()->context()->inPredicate() = FALSE;

  if (bindWA->errStatus()) 
    return this;

  if (!handleIncompatibleComparison(bindWA))
    return NULL;

  // ------
  // for dynamic histogram compression:
  // ----------------------------------
  // if the node relates two basecolumns mark the columns
  // as having a join predicate
  // The hasJoinPred flag is used by dynamic histogram compression
  // to pick the correct version of compressed histograms
  if((child(0)->getOperatorType()==ITM_BASECOLUMN) &&
     (child(1)->getOperatorType()==ITM_BASECOLUMN))
  {
    // get the table descriptor for each column
    TableDesc * tabdesc1 = ((BaseColumn *) getChild(0))->getTableDesc();
    TableDesc * tabdesc2 = ((BaseColumn *) getChild(1))->getTableDesc();

    // if table descriptors don't match these columns are from different
    // tables i.e. join predicate
    // This avoids a scenario like select * from t1 where t1.a = t1.b
    if(tabdesc1 != tabdesc2)
    {
      ((BaseColumn *) getChild(0))->getNAColumn()->setHasJoinPred();
      ((BaseColumn *) getChild(1))->getNAColumn()->setHasJoinPred();
    }
  }

  if ((child(0)->getOperatorType() == ITM_BASECOLUMN) ||
      (child(1)->getOperatorType() == ITM_BASECOLUMN))
    {
      const NAType &type1 = 
	child(0)->castToItemExpr()->getValueId().getType();
      const NAType &type2 = 
	child(1)->castToItemExpr()->getValueId().getType();

      if ((type1.getTypeQualifier() == NA_CHARACTER_TYPE) &&
	  (type2.getTypeQualifier() == NA_CHARACTER_TYPE))
	{
	  const CharType &cType1 = (CharType&)type1;
	  const CharType &cType2 = (CharType&)type2;
	  
	  if (cType1.isCaseinsensitive() != cType2.isCaseinsensitive())
	    {
	      if ((child(0)->getOperatorType() == ITM_BASECOLUMN) &&
		  (cType1.isCaseinsensitive()))
		{
		  ItemExpr * newChild = 
		    new (bindWA->wHeap()) Convert(child(0));
		  newChild->bindNode(bindWA);
		  setChild(0, newChild);
		}

	      if ((child(1)->getOperatorType() == ITM_BASECOLUMN) &&
		  (cType2.isCaseinsensitive()))
		{
		  ItemExpr * newChild = 
		    new (bindWA->wHeap()) Convert(child(1));
		  newChild->bindNode(bindWA);
		  setChild(1, newChild);
		}
	    }
	}

      if ( child(0)->getOperatorType() == ITM_CONSTANT ||
           child(1)->getOperatorType() == ITM_CONSTANT )
      {
        NABoolean checkRebind = FALSE;
        Int32 cvExprIndex;
        if ( child(1)->getOperatorType() == ITM_CONSTANT AND
             oper == ITM_EQUAL )
        {
            checkRebind = TRUE;
            cvExprIndex = 1;
        } else {
           if ( child(0)->getOperatorType() == ITM_CONSTANT AND
                oper == ITM_EQUAL )
           {
             checkRebind = TRUE;
             cvExprIndex = 0;
           }
        }
  
        if ( checkRebind == TRUE ) {
            ConstValue* cvExpr = (ConstValue*)(getChild(cvExprIndex));
            if ( cvExpr->getValueId().getType().getTypeQualifier() == NA_CHARACTER_TYPE
                 AND
                 cvExpr-> isRebindNeeded() == TRUE ) {
               cvExpr -> unBind();
               cvExpr->bindNode(bindWA); // rebind to populate the cache or
                                         // share the valueId of an identical
                                         // string literal
               setChild(cvExprIndex, cvExpr);
               cvExpr->setRebindNeeded(FALSE);
            }
        }
      }
    }

  // 
  return boundExpr;
} // BiRelat::bindNode()

void BiRelat::synthTypeAndValueId(NABoolean redriveTypeSynthesisFlag, 
				  NABoolean redriveChildTypeSynthesis)
{
  ItemExpr::synthTypeAndValueId(redriveTypeSynthesisFlag,
				redriveChildTypeSynthesis);

  if ((child(0)->getOperatorType() == ITM_BASECOLUMN) ||
      (child(1)->getOperatorType() == ITM_BASECOLUMN))
    {
      const NAType &type1 = 
	child(0)->castToItemExpr()->getValueId().getType();
      const NAType &type2 = 
	child(1)->castToItemExpr()->getValueId().getType();

      if ((type1.getTypeQualifier() == NA_CHARACTER_TYPE) &&
	  (type2.getTypeQualifier() == NA_CHARACTER_TYPE))
	{
	  const CharType &cType1 = (CharType&)type1;
	  const CharType &cType2 = (CharType&)type2;
	  
	  if (cType1.isCaseinsensitive() != cType2.isCaseinsensitive())
	    {
	      if ((child(0)->getOperatorType() == ITM_BASECOLUMN) &&
		  (cType1.isCaseinsensitive()))
		{
		  ItemExpr * newChild = new HEAP Convert(child(0));
		  newChild->synthTypeAndValueId(redriveTypeSynthesisFlag,
						redriveChildTypeSynthesis);
		  setChild(0, newChild);
		}

	      if ((child(1)->getOperatorType() == ITM_BASECOLUMN) &&
		  (cType2.isCaseinsensitive()))
		{
		  ItemExpr * newChild = new HEAP Convert(child(1));
		  newChild->synthTypeAndValueId(redriveTypeSynthesisFlag,
						redriveChildTypeSynthesis);
		  setChild(1, newChild);
		}
	    }
	}
    }
  
}

static ItemExpr * ItemExpr_handleIncompatibleComparison(
     BindWA *bindWA,
     ItemExpr * thisPtr,
     ItemExpr * op1, ItemExpr * op2,
     ItemExpr * &newOp1, ItemExpr * &newOp2)
{
  const NAType &type1 = op1->castToItemExpr()->getValueId().getType();
  const NAType &type2 = op2->castToItemExpr()->getValueId().getType();

  // lob cannot be in a predicate
  if (type1.isLob() || type2.isLob())
  {
    *CmpCommon::diags() << DgSqlCode(-4322);
    bindWA->setErrStatus();
    return NULL;  // error
  }

  // Check if we are to allow certain incompatible comparisons
  if (CmpCommon::getDefault(ALLOW_INCOMPATIBLE_OPERATIONS) == DF_ON)
  {
    // if left and right operands are incompatible, convert
    // one of them to the other type.
    // The check for the conditions under which this is allowed
    // has already been done in BiRelat::synthesizeType.

    Int32 srcOpIndex = -1;  //index of src child
    Int32 tgtOpIndex = -1;  //index of tgt child
    Int32 conversion = 0; //0 = no conversion
                        //1 = cast char to numeric
                        //2 = cast char to date
                        //3 = cast date to numeric
                        //4 = cast numeric to interval
                        //5 = cast numeric to date

    //check if:
    //1. Comparing numeric to a character type
    //2. Comparing date column to a character string literal
    //3. Comparing date to numeric
    //4. Comparing interval to numeric
    //6. Comparing date to char of form: DD-MON-YYYY

    //check for numeric to character comparison
    if ((type1.getTypeQualifier() == NA_CHARACTER_TYPE) &&
	(type2.getTypeQualifier() == NA_NUMERIC_TYPE))
    {
      // convert op1(char) to numeric type
      srcOpIndex = 0;
      tgtOpIndex = 1;
      conversion = 1;
    }
    else
    if ((type1.getTypeQualifier() == NA_NUMERIC_TYPE) &&
        (type2.getTypeQualifier() == NA_CHARACTER_TYPE))
    {
      // convert op2(character) to numeric type
      srcOpIndex = 1;
      tgtOpIndex = 0;
      conversion = 1;
    }

    //check for date to character literal comparison
    if (((type1.getTypeQualifier() == NA_CHARACTER_TYPE) &&
	 (op1->getOperatorType() == ITM_CONSTANT) &&
	 (type2.getTypeQualifier() == NA_DATETIME_TYPE)) ||
	((type1.getTypeQualifier() == NA_DATETIME_TYPE) &&
	 (type2.getTypeQualifier() == NA_CHARACTER_TYPE) &&
	 (op2->getOperatorType() == ITM_CONSTANT)))
    {
      NABoolean op1IsChar = 
	(type1.getTypeQualifier() == NA_CHARACTER_TYPE);

      // only a specific char const pattern is being supported right now.
      // Pattern is:   DD-MON-YYYY.
      // Check for that.
      ConstValue * cv = 
	(op1IsChar ? (ConstValue*)op1->castToItemExpr()
	 : (ConstValue*)op2->castToItemExpr());

      if (cv->getStorageSize() == strlen("DD-MON-YYYY"))
	{
	  char * str = (char*)cv->getRawText()->data();
	  if ((str[2] == '-') && (str[6] == '-'))
	    {
	      if (op1IsChar)
		{
		  //convert op1(char literal) to date
		  srcOpIndex = 0;
		  tgtOpIndex = 1;
		}
	      else
		{
		  //convert op2(char literal) to date
		  srcOpIndex = 1;
		  tgtOpIndex = 0;
		}

	      if (op1IsChar)
		{
		  if (type2.getPrecision() == SQLDTCODE_DATE)
		    conversion = 6;
		  else if (type2.getPrecision() == SQLDTCODE_TIMESTAMP)
		    conversion = 7;
		}
	      else
		{
		  if (type1.getPrecision() == SQLDTCODE_DATE)
		    conversion = 6;
		  else if (type1.getPrecision() == SQLDTCODE_TIMESTAMP)
		    conversion = 7;
		}
	    }
	}
    }

    // check for date to character comparison that was not covered by
    // the previous condition.
    if (conversion == 0)
      {
	if ((type1.getTypeQualifier() == NA_CHARACTER_TYPE) &&
	    (type2.getTypeQualifier() == NA_DATETIME_TYPE))
	  {
	    //convert op1(char literal) to date
	    srcOpIndex = 0;
	    tgtOpIndex = 1;
	    conversion = 2;
	  }
	else
	  if ((type1.getTypeQualifier() == NA_DATETIME_TYPE) &&
	      (type2.getTypeQualifier() == NA_CHARACTER_TYPE))
	    {
	      //convert op2(char literal) to date
	      srcOpIndex = 1;
	      tgtOpIndex = 0;
	      conversion = 2;
	    }
      }

    // check for date to numeric comparison.
    // if one child is a column and the other child is not, then
    // convert the non-column child to the type of the column child.
    // This would result in a CAST node not being added on top of the
    // column which could then be used as a key predicate.
    // If both children are columns or both are non-columns, then convert 
    // datetime to numeric.
    if ((type1.getTypeQualifier() == NA_DATETIME_TYPE) &&
	(type2.getTypeQualifier() == NA_NUMERIC_TYPE))
      {
	if (((op1->getOperatorType() == ITM_REFERENCE) ||
	     (op1->getOperatorType() == ITM_BASECOLUMN)) &&
	    (NOT ((op2->getOperatorType() == ITM_REFERENCE) ||
		  (op2->getOperatorType() == ITM_BASECOLUMN))))
	  {
	    // op1 is column, op2 is not.
	    // convert op2(numeric) to the type of op1 (datetime)
	    srcOpIndex = 1;
	    tgtOpIndex = 0;
	    conversion = 5;
	  }
	else
	  {
	    // op2 is column and op1 is not,
	    // or both children are columns, or both children are non-columns.
	    // Convert op1(datetime) to numeric type
	    srcOpIndex = 0;
	    tgtOpIndex = 1;
	    conversion = 3;
	  }
      }
    else if ((type1.getTypeQualifier() == NA_NUMERIC_TYPE) &&
	     (type2.getTypeQualifier() == NA_DATETIME_TYPE))
      {
	if (((op2->getOperatorType() == ITM_REFERENCE) ||
	     (op2->getOperatorType() == ITM_BASECOLUMN)) &&
	    (NOT ((op1->getOperatorType() == ITM_REFERENCE) ||
		  (op1->getOperatorType() == ITM_BASECOLUMN))))
	  {
	    // op2 is column, op1 is not.
	    // convert op1(numeric) to the type of op2 (datetime)
	    srcOpIndex = 0;
	    tgtOpIndex = 1;
	    conversion = 5;
	  }
	else
	  {
	    // op1 is column and op2 is not,
	    // or both children are columns, or both children are non-columns.
	    // Convert op2(datetime) to numeric type(op1)
	    srcOpIndex = 1;
	    tgtOpIndex = 0;
	    conversion = 3;
	  }
    }

    //check for interval to numeric comparison
    if ((type1.getTypeQualifier() == NA_INTERVAL_TYPE) &&
	(type2.getTypeQualifier() == NA_NUMERIC_TYPE))
    {
      // convert op2 to interval type
      srcOpIndex = 1;
      tgtOpIndex = 0;
      conversion = 4;
    }
    else
    if ((type1.getTypeQualifier() == NA_NUMERIC_TYPE) &&
        (type2.getTypeQualifier() == NA_INTERVAL_TYPE))
    {
      // convert op1 to interval type
      srcOpIndex = 0;
      tgtOpIndex = 1;
      conversion = 4;
    }
    else
    if ((type1.getTypeQualifier() == NA_DATETIME_TYPE) &&
	(type2.getTypeQualifier() == NA_DATETIME_TYPE) &&
        (type1.getPrecision() != type2.getPrecision()))
    {
      conversion = 8;
      if (type1.getPrecision() == SQLDTCODE_TIMESTAMP)
        {
          // convert op2 to timestamp
          srcOpIndex = 1;
          tgtOpIndex = 0;
        }
      else
        {
          // convert op1 to timestamp
          srcOpIndex = 0;
          tgtOpIndex = 1;
        }
    }

    ItemExpr * newOp = NULL;

    switch (conversion)
    {
      case 1:
        //doing a char to numeric conversion
        // convert to double precision. This will handle all precision,
	// scale and type specified in the char value.
	newOp =
	  new (bindWA->wHeap())
	  Cast((srcOpIndex == 0 ? op1 : op2),
	    new (bindWA->wHeap())
	    SQLDoublePrecision(bindWA->wHeap(), (srcOpIndex == 0 ? op1 : op2)->castToItemExpr()->getValueId().getType().supportsSQLnull()));
    	newOp = newOp->bindNode(bindWA);
        break;

      case 2:
        //doing a char to date conversion
        newOp =
	  new (bindWA->wHeap())
	  Cast((srcOpIndex == 0 ? op1 : op2),
	       (tgtOpIndex == 0 ? op1 : op2)->castToItemExpr()->getValueId().getType().newCopy(bindWA->wHeap()));
    	newOp = newOp->bindNode(bindWA);
        break;

      case 3:
	{
	  //doing a date to numeric conversion
	  newOp =
	    new (bindWA->wHeap())
	    Cast((srcOpIndex == 0 ? op1 : op2),
		 new (bindWA->wHeap())
		 SQLLargeInt(bindWA->wHeap(), TRUE,
			     (srcOpIndex == 0 ? op1 : op2)->castToItemExpr()->
			     getValueId().getType().supportsSQLnull()));
	  newOp = newOp->bindNode(bindWA);
	}
        break;

      case 4:
	{
	  //doing a numeric to interval conversion
	  const NumericType&  numeric  = 
	    (NumericType&)(srcOpIndex == 0 ? op1 : op2)->castToItemExpr()->getValueId().getType();
	  const IntervalType& interval = 
	    (IntervalType&)(tgtOpIndex == 0 ? op1 : op2)->castToItemExpr()->getValueId().getType();
	  Lng32 maxDigits = (numeric.getMagnitude() + 9) / 10;
	  maxDigits = MINOF(maxDigits, 
			    SQLInterval::MAX_LEADING_PRECISION);
	  
	  SQLInterval * newInterval =  
	    new(bindWA->wHeap()) SQLInterval(
                 bindWA->wHeap(),
		 numeric.supportsSQLnull(),
		 interval.getEndField(),
		 maxDigits,
		 interval.getEndField(),
		 0);
	  
	  newOp =
	    new (bindWA->wHeap())
	    Cast((srcOpIndex == 0 ? op1 : op2), newInterval);
	  newOp = newOp->bindNode(bindWA);
	}
        break;

      case 5:
        //doing a numeric to date conversion
        newOp =
	  new (bindWA->wHeap())
	  Cast((srcOpIndex == 0 ? op1 : op2),
	       (tgtOpIndex == 0 ? op1 : op2)->castToItemExpr()->getValueId().getType().newCopy(bindWA->wHeap()));
    	newOp = newOp->bindNode(bindWA);
        break;

    case 6:
    case 7:
      // doing char to date formatting.
      newOp =
	new (bindWA->wHeap())
	Format((srcOpIndex == 0 ? op1 : op2), "DD-MON-YYYY", TRUE);
      newOp = newOp->bindNode(bindWA);

      if (conversion == 7)
	{
	  newOp =
	    new (bindWA->wHeap())
	    Cast(newOp,
		 (tgtOpIndex == 0 ? op1 : op2)->castToItemExpr()->getValueId().getType().newCopy(bindWA->wHeap()));
	  newOp = newOp->bindNode(bindWA);
	}
      break;
      
    case 8:
      newOp =
	new (bindWA->wHeap())
	Cast((srcOpIndex == 0 ? op1 : op2),
	     (tgtOpIndex == 0 ? op1 : op2)->castToItemExpr()->getValueId().getType().newCopy(bindWA->wHeap()));
      newOp = newOp->bindNode(bindWA);
      break;
     
      default:
        break;
    }

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

    newOp1 = NULL;
    newOp2 = NULL;
    if (newOp)
      {
	if (srcOpIndex == 0)
	  newOp1 = newOp;
	else
	  newOp2 = newOp;
      }
  }

  return thisPtr;
}


// if we are allowing certain incompatible comparisons handle them.
// currently the following incompatible comparisons are supported:
// 1. Numeric and Character
// 2. Date and Character literal
BiRelat * BiRelat::handleIncompatibleComparison(BindWA *bindWA)
{
  ItemExpr * newChild0 = NULL;
  ItemExpr * newChild1 = NULL;
  ItemExpr * result = 
    ItemExpr_handleIncompatibleComparison(
	 bindWA,
	 this,
	 child(0)->castToItemExpr(), child(1)->castToItemExpr(),
	 newChild0, newChild1);
  if (! result)
    return NULL;

  if(bindWA->errStatus()) 
    return NULL;
  
  if (newChild0)
    setChild(0, newChild0);
  if (newChild1)
    setChild(1, newChild1);

  return this;
}

ItemExpr *KeyRangeCompare::bindNode(BindWA *bindWA)
{
  if (nodeIsBound()) return this;

  CollIndex i = 0;


  // In the case of CLUSTERING KEY option (child(0) == NULL),
  // see if the objectName exists in the RetDesc. This is done to support
  // queries of the form - "select * from t_4a1 as X where
  //           Key_Range_Compare (CLUSTERING KEY >= (1,2) on table X);".
  // The X within the KeyRangeCompare resolves to t_4a1.
  //
  // In the case of PARTITIONING KEY option use the object name that
  // the user provides.
  // This is to support the requirements from Online Populate Index, where
  // KEY_RANGE_COMAPRE is done to see which partition a row belongs
  // to in the index. The key values are obtained from the Audit Image of the
  // table. Example:
  // select case
  // when KEY_RANGE_COMPARE(PARTITIONING KEY(X.C2, X.C3) < ('l',1000)
  //					ON INDEX_TABLE t_indx)
  //	THEN 0
  //    ELSE -1
  //	END
  // from (SELECT c2,c3 from table(INTERPRET_AS_ROW(:tableAuditImage,....))
  //  AS X(C2,C3)).
  //

  if (child(0) == NULL)
    {
      TableNameMap *exposedTableName = NULL;
      LIST(TableNameMap*) xtnmList(bindWA->wHeap());
      bindWA->getTablesInScope(xtnmList, NULL);

      if ((getObjectName().isEmpty()) && (xtnmList.entries() == 1))
      { // if no table was specified and there is only one table in scope
	// then use that table.
	exposedTableName = xtnmList[0];
      }
      else
      {
	RETDesc * retDesc = bindWA->getCurrentScope()->getRETDesc();
	exposedTableName = retDesc->getXTNM().get(&objectName_);

	if (!exposedTableName)
	{
	  // Table specified for KeyRangeCompare is not in scope.
	  retDesc->getTableList(xtnmList, NULL);
	  NAString fmtdList(bindWA->wHeap());
	  RETDesc::formatTableList(xtnmList, &fmtdList, TRUE);  // include partition names, if present

	  NAString objectNameAsString;
	  if (objectName_.hasPartnClause())
	    objectNameAsString = objectName_.getExposedNameAsStringWithPartitionNames();
	  else
	    objectNameAsString = objectName_.getExposedNameAsString();

	  *CmpCommon::diags() << DgSqlCode(-4332)
			      << DgTableName(objectNameAsString)
			      << DgString0(fmtdList);
	  bindWA->setErrStatus();
	  return this;
	}
      } // table name was specified or we have more than one table in scope.

      setObjectName(exposedTableName->getTableName());
    }

  // Obtain the NATable for the objectName.
  NATable *naTable = bindWA->getNATable(objectName_);
  if (bindWA->errStatus())
    return this;
  naTable->decrReferenceCount(); // refcount need not be incremented for this use of natable

  // Key_Range_Compare disallowed on views.
  if (naTable->getViewText() != NULL)
    {
      *CmpCommon::diags() << DgSqlCode(-4334);
     bindWA->setErrStatus();
     return this;
    }

  // The constructor sets the specialNulls_ flag to TRUE
  // Initialize the direction vector here. Set it up
  // later in the procedure.
  IntegerList *directionVector = new(bindWA->wHeap()) IntegerList();

  // Setup the LHS of the comparision predicate
  // Currently, we require the users to specify the LHS for
  // partition keys, but not for clustering keys.
  // child0 will be NULL only for the clustering key comparision.
   if (child(0) == NULL)
    {
      // Get the Clustering Key Columns.
      const NAColumnArray & clustKeyColumns =
	naTable->getClusteringIndex()->getIndexKeyColumns();

      CorrName qualifiedName(objectName_, bindWA->wHeap());
      // since these CKs colReferences are created in the Binder
      // don't fix the name in LocList.
      qualifiedName.setNamePosition(0);

      // Create an item list and set it as the LHS.
      ItemExpr *clustKeyColList = new (bindWA->wHeap())
	ColReference(new(bindWA->wHeap()) ColRefName
		     (clustKeyColumns[0]->getColName(),
		      qualifiedName,
		      bindWA->wHeap()));

      for (i = 1; i < clustKeyColumns.entries(); i++)
	clustKeyColList = new (bindWA->wHeap())
	  ItemList(clustKeyColList, (ItemExpr *) new (bindWA->wHeap())
		   ColReference(new(bindWA->wHeap()) ColRefName
				(clustKeyColumns[i]->getColName(),
				 qualifiedName,
				 bindWA->wHeap())));

      // Set that as child(0)
      child(0) = clustKeyColList;

      // Setup the direction vector.
      for (i=0; i < clustKeyColumns.entries(); i++)
      {
	if (clustKeyColumns.isAscending(i))
	  directionVector->insert(1);
	else
	  directionVector->insert(-1);
      }
    }
  else
    {
      const PartitioningFunction *partFunc =
	naTable->getClusteringIndex()->getPartitioningFunction();

      if (partFunc->isATableHashPartitioningFunction())
	{
	  // Table is Hash or Hash2 partitioned. Partitioning Keys
	  // comparison is not allowed on hash partitioned tables.
	  *CmpCommon::diags() << DgSqlCode(-4331)
			      << DgTableName(objectName_.getExposedNameAsAnsiString());
	  bindWA->setErrStatus();
	  return this;
	}

      // Partition Key is being specified.
      const NAColumnArray &partKeyCols =
	naTable->getClusteringIndex()->getPartitioningKeyColumns();

      if(!verifyPartitioningKeys(bindWA,
				 child(0),
				  partKeyCols,
				  bindWA->wHeap()))
	{
	  bindWA->setErrStatus();
	  return this;
	}

      for (CollIndex i2=0; i2 < partKeyCols.entries(); i2++)
	{
	  if (partKeyCols.isAscending(i2))
	    directionVector->insert(1);
	  else
	    directionVector->insert(-1);
	}
    }

  setDirectionVector(directionVector);

  // KeyRangeCompare inherits from BiRelat
  return BiRelat::bindNode(bindWA);
}

NABoolean KeyRangeCompare::verifyPartitioningKeys(BindWA *bindWA,
						  ItemExpr *tree,
						   const NAColumnArray &partKeyCols,
						  CollHeap *heap)
{
  ExprValueIdList *list = new (heap) ExprValueIdList(heap);

  if (tree->getOperatorType() != ITM_ITEM_LIST)
    {
      ExprValueId exprTree(tree);
      // There is only one element.
      list->insert(&exprTree);
    }
  else
    {
      list = ((ItemList *)tree)->collectLeaves(heap, list);
    }

  const ULng32 num = list->entries();

  if (partKeyCols.entries() != num) {
    // 4042 The operands of a comparison predicate must be of equal degree.
    *CmpCommon::diags() << DgSqlCode(-4335)
			<< DgInt0((Lng32) num)
			<< DgInt1((Lng32) partKeyCols.entries())
			<< DgTableName(objectName_.getExposedNameAsAnsiString());
    return FALSE;
  }


  // Make sure that the types of items in tree match the partKeyCols types.
  // We do this by temporarily creating a cast node and binding it.
  for (ULng32 i = 0; i < num; i++)
    {
      ItemExpr *cast = new (bindWA->wHeap()) Cast((*list)[i]->getPtr(),
						  partKeyCols[i]->getType(),
						  ITM_CAST);
      cast = cast->bindNode(bindWA);
      if (bindWA->errStatus())
	return FALSE;

      delete cast;

    }
  return TRUE;
}

ItemExpr *Function::bindNode(BindWA *bindWA)
{
  if (checkForSQLnullChild(bindWA, this, allowsSQLnullArg(), FUNCTION_))
    return this;

  ItemExpr *save = bindWA->getCurrentScope()->context()->inMultaryPred();
  bindWA->getCurrentScope()->context()->inMultaryPred() = this;
  ItemExpr *boundExpr = ItemExpr::bindNode(bindWA);
  bindWA->getCurrentScope()->context()->inMultaryPred() = save;
  return boundExpr;
} // Function::bindNode()

ItemExpr *Between::bindNode(BindWA *bindWA)
{
  //changes for HistIntRed

  //save the current state of inRangePred_ in the binder
  //context so that we can set it back after binding this
  //node in case we reset it the if statement below
  NABoolean inRangePredSave = bindWA->getCurrentScope()->context()->inRangePred();
  bindWA->getCurrentScope()->context()->inRangePred() = TRUE;

  ItemExpr * boundExpr = BuiltinFunction::bindNode(bindWA);

  if((boundExpr) &&
     (!bindWA->errStatus()) &&
     (!handleIncompatibleComparison(bindWA)))
    return NULL;

  //set inRangePred_ in the context to original value
  bindWA->getCurrentScope()->context()->inRangePred() = inRangePredSave;

  // Apply the substr transformation, if possible
  if (child(0)->getOperatorType() == ITM_SUBSTR AND
      child(1)->getOperatorType() == ITM_CONSTANT AND
      child(2)->getOperatorType() == ITM_CONSTANT AND
      CmpCommon::getDefault(SUBSTRING_TRANSFORMATION) == DF_ON)
  {
     ItemExpr * bt = checkAndApplySubstrTransformation();
     if ( bt ) {
       boundExpr = bt->bindNode(bindWA);
     }
  }

  return boundExpr;
}

// Check out the possibilty of SUBSTR optimization, which
// convert the predicate
//
//   substr(PK_column_fix_char, 1, n) between literal1 and literal2
//
// into the following
//
//   PK_column_fix_char between c1 and c2 
//
//   where c1 = literal1 paded with character 0x00
//                     and
//         c2 = literal2 paded with character 0xff
//
// The transformation is applied when the following is true
//
// 1. PK_column_fix_char is leading key fixed ISO88591 char column;
// 2. strlen(literal1) = strlen(literal2) = length of substr();
// 3. 1 <= n <= column length of PK_column_fix_char
//
// The method returns the transformed between expr if the transformation
// can be done. Otherwise, a NULL is returned.
//
ItemExpr* Between::checkAndApplySubstrTransformation()
{
   ItemExpr* substr = child(0)->castToItemExpr();
   ItemExpr* literal1 = child(1)->castToItemExpr();
   ItemExpr* literal2 = child(2)->castToItemExpr();

   NAMemory *heap = CmpCommon::statementHeap();

   Int32 column_len = 0; 
   NABoolean col_support_null = FALSE;
   Lng32  substr_len = 0;

   // check substr() first
   ItemExpr* c = substr->child(0)->castToItemExpr();
   BaseColumn* baseCol = NULL;

   // skip the CAST operator, if any 
   if ( c->getOperatorType()==ITM_CAST )
      baseCol = (BaseColumn*)(c->child(0)->castToItemExpr());
   else
      baseCol = (BaseColumn*)c;

   // c in SUBSTR(c, a, b) must be a basecolumn
   if ( baseCol->getOperatorType()==ITM_BASECOLUMN )
   {
     const NAType &coltype = (baseCol->getValueId()).getType();

     // c should be a leading key base column with fixed ISO88591 char data type
     if ( coltype.getTypeQualifier() != NA_CHARACTER_TYPE ||
          ((const CharType&)(coltype)).getCharSet() != CharInfo::ISO88591 ||
          !DFS2REC::isSQLFixedChar(((const CharType&)(coltype)).getFSDatatype())
      )
       return NULL;

     // c must be a key column
     const NAColumn* naCol = baseCol->getNAColumn();
     if (naCol==NULL || !(naCol->isPrimaryKey())) return NULL;


     const NATable* naTable = naCol->getNATable();
     const NAColumnArray & clustKeyColumns =
                   naTable->getClusteringIndex()->getIndexKeyColumns();

     // c must be a leading key column
     if ( clustKeyColumns.entries() < 1 ||
          clustKeyColumns[0]->getPosition() != baseCol->getColNumber() )
       return NULL;

/*
     const ValueIdList keyCols = 
        baseCol->getTableDesc()->getClusteringIndex()->getClusteringKeyCols();

     if ( keyCols.entries() == 0 || 
          keyCols[0].getItemExpr()->getOperatorType() != ITM_INDEXCOLUMN )
       return NULL;

     IndexColumn* indexCol = (IndexColumn*)(keyCols[0].getItemExpr());
     if ( indexCol->getIndexColNumber() != baseCol->getColNumber() )
       return NULL;
*/

     column_len = ((const CharType&)(coltype)).getStrCharLimit();

     // Get the number of characters returned by the SUBSTR 
     substr_len = 
       ((const CharType&)((substr->getValueId()).getType())).getStrCharLimit();

     // Column length must be at least substr_len long
     if ( column_len < substr_len )
       return NULL;

     col_support_null = coltype.supportsSQLnullLogical();
   } else
       return NULL;

   // The 2nd argument of substr should be 1
   if ( substr->child(1)->getOperatorType()==ITM_CONSTANT ) {

      const ConstValue* cv1 = 
         (const ConstValue*)(substr->child(1)->castToItemExpr());

      if ( cv1->canGetExactNumericValue() AND
           cv1->getExactNumericValue() != 1 ) 
         return NULL;
   } else
      return NULL;

   // The 3rd argument of substr should be >= 1.
   if ( substr->child(1)->getOperatorType()==ITM_CONSTANT ) {

      const ConstValue* cv2 =
         (const ConstValue*)(substr->child(2)->castToItemExpr());

      if ( cv2->canGetExactNumericValue() AND
           cv2->getExactNumericValue() < 1 )
         return NULL;
   } else
      return NULL;

   // literal1 must be of character type and its length must be
   // equal to that of the synthesized SUBSTR().
   const NAType &literal1_type = 
        literal1->castToItemExpr()->getValueId().getType();

   if ( literal1_type.getTypeQualifier() != NA_CHARACTER_TYPE ||
        substr_len != ((const CharType&)literal1_type).getStrCharLimit() 
      )
      return NULL;

   // literal2 must be of character type and its length must be
   // equal to that of the synthesized SUBSTR().
   const NAType &literal2_type = 
        literal2->castToItemExpr()->getValueId().getType();

   if ( literal2_type.getTypeQualifier() != NA_CHARACTER_TYPE ||
        substr_len != ((const CharType&)literal2_type).getStrCharLimit() 
      )
     return NULL;


   // Now modify the between tree
   // ----------------------------

   // Figure out the number of character 0x00 or 0xff to pad
   Int32 chars_to_pad = column_len - substr_len;

   // modify the Construct the new constant 
   ConstValue* cv = (ConstValue*)literal1;
   NAString cstr1(*(cv->getRawText()));
   cstr1.append((const char)0x00, chars_to_pad);
   ConstValue *c1 = new (heap) ConstValue(cstr1, heap);

   cv = (ConstValue*)literal2;
   NAString cstr2(*(cv->getRawText()));
   cstr2.append((const char)0xff, chars_to_pad);

   ConstValue *c2 = new (heap) ConstValue(cstr2, heap);

   child(0)= baseCol;
   child(1)= c1;
   child(2)= c2;

   // make sure this gets bound again
   unBind();

   return this;
}

// -----------------------------------------------------------------------
// member functions for class BitOperFunc
// -----------------------------------------------------------------------
ItemExpr *BitOperFunc::bindNode(BindWA *bindWA)
{
  if (nodeIsBound())
    return getValueId().getItemExpr();

  return BuiltinFunction::bindNode(bindWA);
} // BitOperFunc::bindNode()

Between * Between::handleIncompatibleComparison(BindWA * bindWA)
{
  ItemExpr * newChild0 = NULL;
  ItemExpr * newChild1 = NULL;
  ItemExpr * newChild2 = NULL;
  ItemExpr * result = 
    ItemExpr_handleIncompatibleComparison(
	 bindWA,
	 this,
	 child(0)->castToItemExpr(), child(1)->castToItemExpr(),
	 newChild0, newChild1);
  if (! result)
    return NULL;

  if(bindWA->errStatus()) 
    return NULL;
  
  result = 
    ItemExpr_handleIncompatibleComparison(
	 bindWA,
	 this,
	 child(0)->castToItemExpr(), child(2)->castToItemExpr(),
	 newChild0, newChild2);
  if (! result)
    return NULL;

  if(bindWA->errStatus()) 
    return NULL;
  
  if (newChild0)
    setChild(0, newChild0);
  if (newChild1)
    setChild(1, newChild1);
  if (newChild2)
    setChild(2, newChild2);
  
  return this;
}

ItemExpr *BuiltinFunction::bindNode(BindWA *bindWA)
{
  if (nodeIsBound())
    {
      // 10-100719-1893
      // Look for the replacementExpr if the builtinFunction is already
      // bound. Solves the issue where we forget that we have transformed
      // the function. For example NVL() -> CASE().

      ItemExpr * retExpr = getValueId().getItemExpr()->getReplacementExpr();
      if (retExpr != NULL) 
        return retExpr;
      else
        return getValueId().getItemExpr();
    }

  //////////////////////////////////////////////////////////////////////
  // Due to the many problems with rand() implementations we decided to
  // disable this method for R2.0. The last known problem with rand()
  // caused data corruption.
  // We will re-enable rand() after it get fixed.
  // Also we provide special CQD to allow R1.8 users who may already used
  // rand() and have scripts depending on it to use it in R2.0.
  // We need also to make sure we are only disabling user rands (binder
  // phase rands) and not  system generated rands.
  ///////////////////////////////////////////////////////////////////////
  if ( getOperatorType() == ITM_RANDOMNUM )
    {
      // if this builtinfunction is a RandomNum(), then it is safe to cast
      // the this pointer to (Random *). 
      if (CmpCommon::getDefault(ALLOW_RAND_FUNCTION) != DF_ON AND
	  QueryAnalysis::Instance() AND
	  QueryAnalysis::Instance()->getCompilerPhase() == QueryAnalysis::BINDER)
	{
	  *CmpCommon::diags() << DgSqlCode(-4313);
	  bindWA->setErrStatus();
	  return NULL; // error
	}
    }

  // this will bind/type-propagate all children.
  bindChildren(bindWA);
  if (bindWA->errStatus()) 
    return this;

  if ( getOperatorType() != ITM_BETWEEN )
    {
      // Reverify inputs
      // This is to deal with cases where a builtin function requires one 
      // input, but the input given is a subquery with degree greater than 1 or
      // a MultiValuedFunction(MVF). In this case the parser would not flag it,
      // since we don't know the degree of those until after bind time.
      // Here we check again..
      
      // We don't need to do this for between because comparison expandsions
      // will detect it.
      
      // XXX If there are builtin functions that requires two inputs and we 
      // want to allow specifying just an mvf or subquery of degree 2, we need
      // to change the parser...
      
      Int32 childDegree = 0;
      Subquery * subq = NULL;
      UDFunction * udf = NULL;
      Int32 origArity = getArity();
      
      for (Int32 chld=0; chld < origArity; chld++)
        {
       
          switch (child(chld)->getOperatorType())
            {
            case ITM_ROW_SUBQUERY:
              subq = (Subquery *) child(chld)->castToItemExpr();
              childDegree += subq->getSubquery()->getDegree();
              break;
            
            case ITM_USER_DEF_FUNCTION:
              udf = (UDFunction *) child(chld)->castToItemExpr();
              childDegree += udf->getRoutineDesc()->getOutputColumnList().entries();
              break;
            
            default:
              childDegree += 1;
              break;
            }
          
        }
      
      if (childDegree > origArity) 
      {
        NAString upperFunc(getText(), bindWA->wHeap());
        
        upperFunc.toUpper();
        *CmpCommon::diags() << DgSqlCode(-4479) << DgString0(upperFunc) 
                            << DgInt1(origArity) << DgInt2(childDegree);
        
        bindWA->setErrStatus();
        return NULL;
      }
    } // if ITM_BETWEEN

  ItemExpr * retExpr = NULL;
  NABoolean useCase = FALSE;
  ItemExpr * ie = NULL;
  switch (getOperatorType())
    {

    case ITM_ISIPV4:
    case ITM_ISIPV6:
    case ITM_MD5:
    case ITM_CRC32:
    case ITM_SHA1:
    case ITM_SOUNDEX:
    case ITM_SHA2_224:
    case ITM_SHA2_256:
    case ITM_SHA2_384:
    case ITM_SHA2_512:
      {
         break;
      }
    case ITM_NULLIFZERO:
      {
	// binder has already verified that child is numeric
	const NumericType &type_op1 = (NumericType&)
	  (child(0)->castToItemExpr()->getValueId().getType());

	if ((type_op1.isComplexType()) ||
	    (NOT (type_op1.isExact())) ||
	    (type_op1.isDecimal()))
	  {
	    Parser parser(bindWA->currentCmpContext());

	    retExpr =
	      parser.getItemExprTree(
		   "CASE WHEN @A1 <> 0 then @A1 ELSE NULL END;",
		   0, BINDITEMEXPR_STMTCHARSET, 1, child(0));
	  }
	break;
      }

    case ITM_NVL:
      {
	// if my children's attributes EXCEPT for nullability are not the
	// same as mine, use a CASE stmt.
	const NAType &typ1 =
	  child(0)->castToItemExpr()->getValueId().getType();
	const NAType &typ2 =
	  child(1)->castToItemExpr()->getValueId().getType();

	NABoolean useCase = FALSE;
	if (NOT typ1.isCompatible(typ2))
	  useCase = TRUE;
	else if ((child(0)->castToItemExpr()->isASubquery()) ||
	    (child(1)->castToItemExpr()->isASubquery()))
	  {
	    useCase = TRUE;
	  }
	else if (typ1.getTypeQualifier() == NA_CHARACTER_TYPE)
	  {
	    //
	    // For character types, if the collation is not the same for
	    // the two arguments to NVL, then revert to a CASE stmt.
	    //
	    const CharType &cTyp1 = (CharType&)typ1;
	    if ( cTyp1.getCollation() != ((CharType&)typ2).getCollation() )
	      useCase = TRUE;
	  }
	if ( ( NOT useCase) && (NOT typ1.supportsSQLnull()) )
	  {
	    retExpr = child(0)->castToItemExpr();
	    break;    // That's all that this NVL needs.
	  }
	if ( NOT useCase )
	  {
	    if (typ2.supportsSQLnull())
	      useCase = TRUE;
            // convert NVL to CASE for all CHAR types, including fixed CHARs.
            // This is necessary because query caching does limited type
            // synthesization when replacing a fixed char literal with a varchar
            // typed parameter. In fact, if NVL appears inside
            //       "select nvl(t.c1, 'a') from t"
            // the type of nvl() is assumed to be that of t.c1 if no conversion
            // is done. If t.c1 is fixed char, then type will mismatch when
            // the execution of the cached plan delivers a varchar value. The
            // length value will appear as 1st two bytes of the output value!
            //
	    else if ((DFS2REC::isAnyCharacter(typ1.getFSDatatype())) ||
		     (DFS2REC::isAnyCharacter(typ2.getFSDatatype())))
	      useCase = TRUE;
	    else
	      {
		// typ1 is nullable and typ2 is non-nullable.
		// create a new typ1 with the same null attr as typ2
		// and the same coercibilit as typ2.
		NAType * newTyp1 = typ1.newCopy(bindWA->wHeap());
		newTyp1->resetSQLnullFlag();
		if (newTyp1->getTypeQualifier() == NA_CHARACTER_TYPE)
		  ((CharType*)newTyp1)->setCoercibility(((CharType&)typ2).getCoercibility());
		if (NOT(*newTyp1 == typ2))
		  {
		    ie = Function::bindNode(bindWA);
		    if (bindWA->errStatus()) 
		      return NULL;

		    if (*newTyp1 == getValueId().getType())
		      {
			// Left child is the same type as result.
			// Insert a cast node to convert right child to
			// result type.
			child(1) = new (bindWA->wHeap())
			  Cast(child(1), &getValueId().getType());
			child(1)->bindNode(bindWA);
		      }
		    else
		      useCase = TRUE;
		  }
		delete newTyp1;
	      }

	  }

	if (useCase)
	  {
	    Parser parser(bindWA->currentCmpContext());

	    retExpr =
	      parser.getItemExprTree(
		   "CASE WHEN @A1 is null then @A2 ELSE @A1 END;",
		   0, BINDITEMEXPR_STMTCHARSET, 2, child(0), child(1));
	  }

	break;
      }
    case ITM_JSONOBJECTFIELDTEXT:
    {
        break;
    }
    case ITM_QUERYID_EXTRACT:
      {
        // type cast any params
	ValueId vid1 = child(0)->getValueId();
	SQLChar c1(NULL, ComSqlId::MAX_QUERY_ID_LEN);
	vid1.coerceType(c1, NA_CHARACTER_TYPE);
        
        ValueId vid2 = child(1)->getValueId();
	SQLChar c2(NULL, 40, FALSE);
	vid2.coerceType(c2, NA_CHARACTER_TYPE);

	const CharType &typ1 = (CharType&)child(0)->getValueId().getType();
	const CharType &typ2 = (CharType&)child(1)->getValueId().getType();
	
        if (typ1.getTypeQualifier() != NA_CHARACTER_TYPE || typ2.getTypeQualifier() != NA_CHARACTER_TYPE)
        {
          // 4043 The operand of a $0~String0 function must be character.
          *CmpCommon::diags() << DgSqlCode(-4043) << DgString0(getTextUpper());
          bindWA->setErrStatus();
          return NULL;
        }
        CharInfo::CharSet chld_cs = ((const CharType&)typ1).getCharSet();
        if ( chld_cs == CharInfo::UNICODE )
        {
           child(0) =
             new (bindWA->wHeap()) Translate(child(0), Translate::UNICODE_TO_ISO88591);
           child(0) = child(0)->bindNode(bindWA);
        }
        chld_cs = ((const CharType&)typ2).getCharSet();
        if ( chld_cs == CharInfo::UNICODE )
        {
           child(1) =
             new (bindWA->wHeap()) Translate(child(1), Translate::UNICODE_TO_ISO88591);
           child(1) = child(1)->bindNode(bindWA);
        }
        if (bindWA->errStatus())
          return NULL;
        // Right child is the string containing the query id attribute that
	// needs to be extracted. 
	// Upshift it so it could be compared at runtime.
	child(1) = new (bindWA->wHeap()) Upper(child(1));
	child(1) = child(1)->bindNode(bindWA);
        if (bindWA->errStatus())
          return NULL;
      }
    break;

    case ITM_ASCII:
      {
         // Since the ASCII(<str_expr>) function requires an ISO88591 string arg,
         // but we want to allow unprefixed string literals (which may be UCS2
         // when running on a system that is using the Unicode Config),
         // we need the following code.
      }
    break;

    case ITM_AES_ENCRYPT:
    case ITM_AES_DECRYPT:
      break;
    default:
      {
      }
      break;
    } // switch

  if (retExpr)
    {
      // Make sure the original expression is bound
      ie = Function::bindNode(bindWA);
      if (bindWA->errStatus()) 
        return NULL;


      // then bind the replacement expression
      ie = retExpr->bindNode(bindWA);
      if (bindWA->errStatus())
	return NULL;
    }
  else
    {
      if (getOperatorType() == ITM_EXTRACT || 
          getOperatorType() == ITM_EXTRACT_ODBC)
        {
          if (isAUserSuppliedInput())
            {
              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();

              const NAType *type = synthTypeWithCollateClause(bindWA);
              if (!type) return this;

              char xFld[2]; str_itoa(((Extract*) this)->getExtractField(),xFld);
              char xVid[7]; str_itoa(extractChild->getValueId(),xVid);
              NAString functionText = getText() + xFld + "-" + xVid;
              ie = ItemExpr::bindUserInput(bindWA,type,functionText);
              if (bindWA->errStatus())
                return this;

              // add this value id to BindWA's input function list.
              bindWA->inputFunction().insert(getValueId());
              return ie;
            }
        } // !extract

      ie = Function::bindNode(bindWA);
      if (bindWA->errStatus()) 
        return NULL;
    } // !retExpr

  //////////////////////////////////////////////////////////////////////
  // Put a special Cast node on top of each child node that is a column.
  // Do not do this if this function is a Cast function.
  // This special Cast function casts the child to its existing
  // data attributes. Later, if the child is replaced by a VEG and
  // resolved to a type with different attribute in preCodeGen,
  // this cast will convert it to its original data attributes.
  // If the child was not resolved to a different type, then precodegen
  // ignores this cast and replaces it with the original child.
  ///////////////////////////////////////////////////////////////////////
  NABoolean doCastFix = TRUE;
  if ((doCastFix) && (protectFromVEGs()))
    {
      for (Int32 i = 0; i < ie->getArity(); i++)
	{
	  if ((child(i)) &&
	      ((child(i)->getOperatorType() == ITM_REFERENCE) ||
	       (child(i)->getOperatorType() == ITM_BASECOLUMN)))
	    {
	      ItemExpr * newChild =
		new (bindWA->wHeap()) Cast(ie->child(i),
					   &ie->child(i)->getValueId().getType());

	      // mark this cast so we do not generate code for it if its attrs
	      // are the same as its child's.
	      ((Cast*)newChild)->setMatchChildType(TRUE);

	      newChild = newChild->bindNode(bindWA);
	      if (bindWA->errStatus()) return NULL;
	      ie->setChild(i, newChild);
	    }
	}
    }

  // 10-100719-1893
  // set the replacementExpr so that we remember any substitution done
  // for example a NVL() expression gets translated to a CASE expression
  // and we want to remember this so that any references to the same NVL()
  // gets replaced correctly. AVG(NVL()) is a good example as the AVG() itself
  // gets translated to SUM(NVL())/COUNT(NVL()). If we don't remember the
  // CASE translation of the NVL(), then only the SUM() reference to the NVL()
  // expression getting translated correctly. 

  setReplacementExpr(ie);

  return ie;
}


ItemExpr *Upper::bindNode(BindWA *bindWA)
{
  // solution 10-040212-3234: the upshift transformation is happening
  // in code generator. This is too late. Suppose a relational operator
  // is outputting the Upper ItemExpression node. Now suddenly, it has
  // to output the child. This presents a few problems. Perhaps, the
  // transformatin can't happen no later than the normalization when the
  // outputs are decided.

  if (nodeIsBound())
    return getValueId().getItemExpr();

  // Upper inherits from BuiltinFunction .. Function .. ItemExpr.
  ItemExpr *boundExpr = BuiltinFunction::bindNode(bindWA);
  if (bindWA->errStatus()) return this;

  // If our child is already upshifted, we can remove this Upper from the tree.
  // BuiltinFunction::bindNode might have added a Cast node underneath Upper
  // with the MATCH_CHILD_TYPE flag set. We need to remove it too
  // else we can get into trouble with unmapped ValueIds at code generation
  // time. (e.g. If a hash join equi-join predicate refers to the Cast, the
  // Cast expression will be in the join child's characteristic outputs but
  // when we generate the join predicate we skip the Cast looking for the
  // underlying column. That might not be in the join child's characteristic
  // outputs.)
  if (boundExpr == this) {
    CMPASSERT(getArity() == 1);
    ValueId opVid = child(0)->getValueId();
    ItemExpr * child0ie = opVid.getItemExpr();
    if (child0ie->getOperatorType() == ITM_CAST)
      {
        Cast * child0ieCast = (Cast *)child0ie;
        if (child0ieCast->matchChildType()) 
          // we need to remove the Cast too
          opVid = child0ieCast->child(0)->getValueId();
      }
    const CharType &ct = (const CharType &)opVid.getType();
    CMPASSERT(ct.getTypeQualifier() == NA_CHARACTER_TYPE);
    if (ct.isUpshifted()) setValueId(opVid);
  }
  return getValueId().getItemExpr();
}

ItemExpr *Abs::bindNode(BindWA *bindWA)
{
  // solution 1438 in Bugzilla: If my child is unsigned 
  // then no Abs function is necessary. It seems safer to 
  // remove the Abs from the query tree as early as possible.
  // Runtime eval method expects child of Abs to be signed,
  // so if this transformation is not made we get a runtime
  // internal error.

  if (nodeIsBound())
    return getValueId().getItemExpr();

  // Abs inherits from MathFunc .. BuiltinFunction .. Function .. ItemExpr.
  ItemExpr *boundExpr = MathFunc::bindNode(bindWA);
  if (bindWA->errStatus()) return this;

  // If our child is unsigned, we can remove this Abs from the tree.
  if (boundExpr == this) {
    CMPASSERT(getArity() == 1);
    ValueId opVid = child(0)->getValueId();
    const NumericType &nt = (const NumericType &)opVid.getType();
    CMPASSERT(nt.getTypeQualifier() == NA_NUMERIC_TYPE);
    if (nt.isUnsigned()) setValueId(opVid);
  }
  return getValueId().getItemExpr();
}

ItemExpr *CharFunc::bindNode(BindWA *bindWA)
{
  switch ( charSet_ )
  {
    case CharInfo::UNICODE:
      setOperatorType(ITM_UNICODE_CHAR);
      break;

    case CharInfo::KANJI_MP:
    case CharInfo::KSC5601_MP:
      setOperatorType(ITM_NCHAR_MP_CHAR);
      break;

    default:
      break;
  }

  if (!CharInfo::isCharSetSupported(charSet_)) {
    // 3010 Character set $0~string0 is not yet supported.
    // 4062 The preceding error actually occurred in function $0~String0.
    *CmpCommon::diags() << DgSqlCode(-3010)
      << DgString0(CharInfo::getCharSetName(charSet_));
  NAString unparsed(bindWA->wHeap());
    unparse(unparsed, DEFAULT_PHASE, USER_FORMAT_DELUXE);
    *CmpCommon::diags() << DgSqlCode(-4062) << DgString0(unparsed);
    bindWA->setErrStatus();
    return NULL;
  }

  // CharFunc inherits from BuiltinFunction .. Function .. ItemExpr.
  return BuiltinFunction::bindNode(bindWA);
}

ItemExpr *Concat::bindNode(BindWA *bindWA)
{
  if (nodeIsBound())
    return getValueId().getItemExpr();

  // this will bind/type-propagate all children.
  bindChildren(bindWA);
  if (bindWA->errStatus()) 
    return this;

  if (CmpCommon::getDefault(ALLOW_INCOMPATIBLE_OPERATIONS) == DF_ON)
  {
    const NAType &type1 = 
      child(0)->castToItemExpr()->getValueId().getType();
    const NAType &type2 = 
      child(1)->castToItemExpr()->getValueId().getType();
    
    // allow DATE || CHAR (in mode_special_1)
    // allow NUMERIC || CHAR for all
    Int32 srcChildIndex = -1;
    Int32 convType = -1;
    if ((type1.getTypeQualifier() == NA_CHARACTER_TYPE) &&
        (type2.getTypeQualifier() == NA_DATETIME_TYPE))
      {
        // convert child(1)(DATETIME) to char type
        srcChildIndex = 1;
        convType = 1;
      }
    else if ((type1.getTypeQualifier() == NA_DATETIME_TYPE) &&
             (type2.getTypeQualifier() == NA_CHARACTER_TYPE))
      {
        // convert child(1)(DATETIME) to char type
        srcChildIndex = 0;
        convType = 1;
      }
    else if ((type1.getTypeQualifier() == NA_NUMERIC_TYPE) &&
             (type2.getTypeQualifier() == NA_CHARACTER_TYPE))
      {
        // convert child(0)(NUMERIC) to char type
        srcChildIndex = 0;
        convType = 2;
      }
    else if ((type1.getTypeQualifier() == NA_CHARACTER_TYPE) &&
             (type2.getTypeQualifier() == NA_NUMERIC_TYPE))
      {
        // convert child(1)(NUMERIC) to char type
        srcChildIndex = 1;
        convType = 2;
      }
    
    if ((srcChildIndex >= 0) &&
        ((convType == 2) ||
         ((convType == 1) &&
          (CmpCommon::getDefault(MODE_SPECIAL_1) == DF_ON))))         
      {
        Lng32 dLen = 0;
        if (convType == 1)
          {
            DatetimeType &dtType = (DatetimeType&)
              child(srcChildIndex)->castToItemExpr()->getValueId().getType();
            dLen = dtType.getDisplayLength();
          }
        else if (convType == 2)
          {
            NumericType &nType = (NumericType&)
              child(srcChildIndex)->castToItemExpr()->getValueId().getType();
            dLen =
              nType.getDisplayLength(nType.getFSDatatype(),
                                     nType.getNominalSize(),
                                     nType.getPrecision(),
                                     nType.getScale(),
                                     0);
          }
        
        ItemExpr * newChild = NULL;
        if (convType == 1)
          {
            newChild =
              new (bindWA->wHeap())
              Cast(child(srcChildIndex),
                   new (bindWA->wHeap())
                   SQLChar(bindWA->wHeap(), dLen,
                           child(srcChildIndex)->castToItemExpr()->
                           getValueId().getType().supportsSQLnull()));
            newChild = newChild->bindNode(bindWA);
            if (bindWA->errStatus())
              return this;
          }
        else if (convType == 2)
          {
            Parser parser(bindWA->currentCmpContext());
            char buf[128];
            
            sprintf(buf, "CAST(CAST(@A1 AS VARCHAR(%d)) AS VARCHAR(%d))",
                    dLen, dLen);
            newChild = 
              parser.getItemExprTree(buf, strlen(buf), BINDITEMEXPR_STMTCHARSET, 1, child(srcChildIndex));
            
            newChild = newChild->bindNode(bindWA);
            if (bindWA->errStatus()) 
              return this;
          }
        
        setChild(srcChildIndex, newChild);
      }
  }

  // Concat inherits from BuiltinFunction .. Function .. ItemExpr.
  BuiltinFunction::bindNode(bindWA);
  if (bindWA->errStatus()) 
    return this;

  return getValueId().getItemExpr();
}

ItemExpr *UnLogic::bindNode(BindWA *bindWA)
{
  bindWA->getCurrentScope()->context()->inPredicate() = TRUE;

  // Check for a DEFAULT child -- 'DEFAULT IS NULL' is illegal
  ItemExpr *itm = this;
  if (!checkForSQLnullChild(bindWA, this, TRUE/*Tdm extension allows NULL arg*/))
    itm = ItemExpr::bindNode(bindWA);

  bindWA->getCurrentScope()->context()->inPredicate() = FALSE;
  return itm;
}

ItemExpr * ExtractOdbc::bindNode(BindWA * bindWA)
{
  if (nodeIsBound()) return this;

  bindSelf(bindWA);
  if (bindWA->errStatus()) return this;

  // if my child is a char/varchar, insert a Cast node
  // to convert from char to timestamp.
  if (child(0)->castToItemExpr()->getValueId().getType().getTypeQualifier()
      == NA_CHARACTER_TYPE)
    {
      ItemExpr * newChild =
	new (bindWA->wHeap()) Cast(child(0), new (bindWA->wHeap())
				   SQLTimestamp(bindWA->wHeap(), TRUE));
      setChild(0, newChild);
    }
  unBind();

  allowsSQLnullArg() = TRUE;  // do not raise Nullability type errors during call to bindNode
                              // This is being done so that the same error is raised for YEAR(NULL)
                              // type syntax.
  ItemExpr * ie = BuiltinFunction::bindNode(bindWA);
  allowsSQLnullArg() = FALSE; // reset the nullability flag to not allowing NULLs.
  return ie ;
}

ItemExpr * DateFormat::quickDateFormatOpt(BindWA * bindWA)
{
  const NAType *naType0 = &child(0)->getValueId().getType();

  if ((CmpCommon::getDefault(MODE_SPECIAL_4) == DF_ON) &&
      (child(0)->getOperatorType() == ITM_CONSTANT) &&
      (formatStr_ == "DD-MON-YYYY") &&
      (NOT naType0->isVaryingLen()) &&
      (naType0->getFSDatatype() == REC_BYTE_F_ASCII) &&
      (formatStr_.length() == naType0->getNominalSize()))
    {
      NABoolean canXfrm = TRUE;
      ConstValue * cNode = (ConstValue*)child(0)->castToItemExpr();
      NAString cv = *cNode->getRawText();
      const char * str = cv.data();
      if (NOT ((str[2] == '-') && (str[6] == '-')))
        canXfrm = FALSE;

      NAString dv;
      if (canXfrm)
        {
          dv.append(&str[7], 4);
          dv += "-";
          NAString mon(&str[3], 3);
          mon.toUpper();
          if (mon == "JAN")
            dv += "01";
          else if (mon == "FEB")
            dv += "02";
          else if (mon == "MAR")
            dv += "03";
          else if (mon == "APR")
            dv += "04";
          else if (mon == "MAY")
            dv += "05";
          else if (mon == "JUN")
            dv += "06";
          else if (mon == "JUL")
            dv += "07";
          else if (mon == "AUG")
            dv += "08";
          else if (mon == "SEP")
            dv += "09";
          else if (mon == "OCT")
            dv += "10";
          else if (mon == "NOV")
            dv += "11";
          else if (mon == "DEC")
            dv += "12";
          else
            canXfrm = FALSE;
        }

      ItemExpr * newNode = NULL;
      if (canXfrm)
        {
          dv += "-";
          dv.append(&str[0], 2);

          // nuke the Format node and return a DATE constant
          newNode = literalOfDate(&dv, TRUE);
          if (newNode)
            {
              newNode = newNode->bindNode(bindWA);
              if (bindWA->errStatus())
                {
                  canXfrm = FALSE;
                }
            }
          else
            {
              canXfrm = FALSE;
            }
        }
      
      if ((canXfrm) && (newNode))
        {
          return newNode;
        }
      
      SqlParser_Diags->clear();
      bindWA->resetErrStatus();
    }

  return NULL;
}

ItemExpr * Format::bindNode(BindWA * bindWA)
{
  bindChildren(bindWA);
  if (bindWA->errStatus()) 
    return this;

  const NAType *naType0 = &child(0)->getValueId().getType();
  const NumericType * nType0 = NULL;

  NABoolean formatX = FALSE;
  NABoolean format9 = FALSE;
  NABoolean formatExtract = FALSE;
  Lng32 dotPos = 0;
  NABoolean formatNumericAsX = FALSE;
  NABoolean formatStringAsX  = FALSE;

  if ((formatStr_ == "HH24") ||
      (formatStr_ == "D") ||
      (formatStr_ == "MM") ||
      (formatStr_ == "YYYY"))
    {
      if (CmpCommon::getDefault(MODE_SPECIAL_4) == DF_OFF)
        {
          *CmpCommon::diags() << DgSqlCode(-4065) << DgString0(formatStr_)
                              << DgString1(formatType_ == FORMAT_GENERIC ? "FORMAT" 
                                           : (formatType_ == FORMAT_TO_CHAR ? "TO_CHAR" : "TO_DATE"));
          bindWA->setErrStatus();
          return this;
        }

      if ((formatType_ != FORMAT_TO_CHAR)  &&
	  (naType0->getTypeQualifier() != NA_DATETIME_TYPE))
        {
          *CmpCommon::diags() << DgSqlCode(-4071) << DgString0("TO_CHAR");
          bindWA->setErrStatus();
          return this;
        }

      if ((naType0->getPrecision() != SQLDTCODE_TIMESTAMP) &&
          (naType0->getPrecision() != SQLDTCODE_TIME))
        {
          *CmpCommon::diags() << DgSqlCode(-4072) << DgString0("TO_CHAR") << DgString1("time");;
          bindWA->setErrStatus();
          return this;
	}
      
      formatExtract = TRUE;
    }
  else
    {
      formatX = TRUE;
      for (CollIndex i = 0; i < formatStr_.length(); i++)
	{
	  if ((formatStr_.data()[i] != 'X') &&
	      (formatStr_.data()[i] != 'x'))
	    formatX = FALSE;
	}
      if (formatX)
	{
	  if ((naType0->getTypeQualifier() == NA_CHARACTER_TYPE) &&
	      ((Lng32)(formatStr_.length()) != naType0->getNominalSize()))
	    formatStringAsX = TRUE;
	  else if ((naType0->getTypeQualifier() == NA_NUMERIC_TYPE) &&
		   ((nType0 = ((NumericType*)naType0))->isExact()) &&
		   (NOT nType0->isBigNum()) &&
		   (nType0->getScale() == 0))
	    formatNumericAsX = TRUE;
	  else
	    formatX = FALSE;
	}

      if (NOT formatX)
        {
          format9 = TRUE;
          // check if format is of the form:   99999[.99]
          Lng32 numDots = 0;
          dotPos = -1;
          for (CollIndex i = 0; i < formatStr_.length(); i++)
            {
              if ((formatStr_.data()[i] != '9') &&
                  (formatStr_.data()[i] != '.'))
                format9 = FALSE;
              else if (formatStr_.data()[i] == '.')
                {
                  numDots++;
                  dotPos = i;
                }
            }
          if ((format9) && (numDots > 1))
            format9 = FALSE;
        }
    }

  ItemExpr * newIE= NULL;
  if ((formatX) || (format9) || (formatExtract))
    {
      Parser parser(bindWA->currentCmpContext());
      char buf[200];
      buf[0] = 0;

      if (formatNumericAsX)
	{
	  Lng32 dLen =
	    nType0->getDisplayLength(nType0->getFSDatatype(),
				     nType0->getNominalSize(),
				     nType0->getPrecision(),
				     nType0->getScale(),
				     0);

	  if ((Lng32)(formatStr_.length()) < dLen)
	    {
	      sprintf(buf, "SUBSTRING(CAST(@A1 as CHAR(%d)), %d, " PFSZ ")", 
		      dLen, 1, formatStr_.length());
	    }
	  else if ((Lng32)(formatStr_.length()) >= dLen)
	    {
	      // format using Cast
	      sprintf(buf, "CAST(@A1 as CHAR(" PFSZ "))", formatStr_.length());
	    }
	  
	}
      else if (formatStringAsX)
	{
	  if ((Lng32)(formatStr_.length()) < naType0->getNominalSize())
	    {
	      sprintf(buf, "SUBSTRING(@A1, %d, " PFSZ ")", 1, formatStr_.length());
	    }
	  else if ((Lng32)(formatStr_.length()) > naType0->getNominalSize())
	    {
	      // format using Cast
	      sprintf(buf, "CAST(@A1 as CHAR(" PFSZ "))", formatStr_.length());
	    }
	}
      else if (format9)
        {
          if (dotPos == -1)
            dotPos = 0;
          else
            dotPos = formatStr_.length() - dotPos -1;
          sprintf(buf, "CAST(@A1 as NUMERIC(%d,%d))", (Lng32)formatStr_.length(), dotPos);
        }
      else if (formatExtract)
        {
          if (formatStr_ == "YYYY")
            sprintf(buf, "CAST(EXTRACT (YEAR FROM @A1) AS CHAR(4))");
          else if (formatStr_ == "MM")
            sprintf(buf, "CAST(EXTRACT (MONTH FROM @A1) AS CHAR(2))");
          else if (formatStr_ == "HH24")
            sprintf(buf, "CAST(EXTRACT (HOUR FROM @A1) AS CHAR(2))");
          else if (formatStr_ == "D")
            sprintf(buf, "CAST(DAYOFWEEK(@A1) AS CHAR(2));");
          else
            {
              bindWA->setErrStatus();
              return NULL;
            }
        }
       else
	{
	  bindWA->setErrStatus();
	  return NULL;
	}

      if (strlen(buf) > 0)
	{
	  newIE = parser.getItemExprTree(buf, strlen(buf), BINDITEMEXPR_STMTCHARSET, 1, child(0));
	  if (! newIE)
	    {
	      bindWA->setErrStatus();
	      return NULL;
	    }
	  
	  newIE = newIE->bindNode(bindWA);
	  if (bindWA->errStatus())
	    return NULL;
	}
    }
  else
    {
      if (CmpCommon::getDefault(MODE_SPECIAL_1) == DF_OFF)
        {
          *CmpCommon::diags() << DgSqlCode(-4065) << DgString0(formatStr_)
                              << DgString1(formatType_ == FORMAT_GENERIC ? "FORMAT" 
                                           : (formatType_ == FORMAT_TO_CHAR ? "TO_CHAR" : "TO_DATE"));
          bindWA->setErrStatus();
          return this;
        }
      
      // In mode_special_1, ignore this format and return the child pointer.
      newIE = child(0);
    }
  
  return newIE;
}

///////////////////////////////////////////////////////
// various error checks, details below.
//////////////////////////////////////////////////////
NABoolean DateFormat::errorChecks(Lng32 frmt, BindWA *bindWA, 
                                  const NAType* opType)
{
  Lng32 error = 0;

  NABoolean toChar  = (formatType_ == FORMAT_TO_CHAR);
  NABoolean toDate  = (formatType_ == FORMAT_TO_DATE);
  NABoolean toTime  = (formatType_ == FORMAT_TO_TIME);
  NABoolean df  = ExpDatetime::isDateFormat(frmt);
  NABoolean tf  = ExpDatetime::isTimeFormat(frmt);
  NABoolean tsf = ExpDatetime::isTimestampFormat(frmt);
  NABoolean nf  = ExpDatetime::isNumericFormat(frmt);
  NABoolean ms4 = (CmpCommon::getDefault(MODE_SPECIAL_4) == DF_ON);
  
  if (NOT (df || tf || tsf || nf))
    {
      // format must be date, time, timestamp or numeric
      error = 1; // error 4065
    }
  else if ((NOT ms4) && nf)
    {
      // format can only be numeric in mode_special_4
      error = 1; // error 4065
    }

  if (toDate && NOT (df || tsf))
    {
      // TO_DATE requires date format or timestamp format
      // unless we are in mode_special_4 in which case
      // numeric format is accepted
      if (NOT (ms4 && nf))
        error = 1; // error 4065
    }

  if (!error && toTime)
    {
      if (NOT tf)
        {
          // TO_TIME requires time format
          error = 1; // error 4065
        }
      // source must be datetime containing time field or a character string
      else if (((opType->getTypeQualifier() == NA_DATETIME_TYPE) &&
                (opType->getPrecision() == SQLDTCODE_DATE)) ||
               (opType->getTypeQualifier() != NA_CHARACTER_TYPE))
        {
          error = 9; // error 3415
        }
    }

  if (!error && toChar)
    {
      // source must be datetime with to_char function
      if (opType->getTypeQualifier() != NA_DATETIME_TYPE)
        error = 2; // error 4071

      // cannot convert date source to time format
      else if (tf && (opType->getPrecision() == SQLDTCODE_DATE))
        error = 3; // error 4072
      
      // cannot convert time source to date format or timestamp format
      // for TO_CHAR only (for DATEFORMAT it is OK)
      else if ((df || tsf) && (!wasDateformat_) && (opType->getPrecision() == SQLDTCODE_TIME))
        error = 8; // error 4072
    }

  if (!error && toDate)
    {
      // source must be char or numeric with to_date
      if ((opType->getTypeQualifier() != NA_CHARACTER_TYPE) &&
          (opType->getTypeQualifier() != NA_NUMERIC_TYPE))
        error = 4; //error 4043

      // source can only be numeric in mode_special_4
      else if ((NOT ms4) && (opType->getTypeQualifier() != NA_CHARACTER_TYPE))
        error = 4; // error 4043

      // operand must be numeric with nf (numeric format)
      else if (ms4 && nf && (opType->getTypeQualifier() != NA_NUMERIC_TYPE))
        {
          error = 7; // error 4045
        }

      // numeric must be exact with scale of 0
      else if (ms4 && (opType->getTypeQualifier() == NA_NUMERIC_TYPE))
        {
          if (NOT ((NumericType*)opType)->isExact())
            error = 5; // error 4046
          else if (NOT ((NumericType*)opType)->getScale() == 0)
            error = 6; // error 4047
        }
    }

  if (error)
    {
      switch (error)
        {
        case 1: 
          {
            *CmpCommon::diags() << DgSqlCode(-4065) << DgString0(formatStr_)
                                << DgString1((toChar ? "TO_CHAR" : 
                                              (toDate ? "TO_DATE" : "TO_TIME")));
            bindWA->setErrStatus();
          }
          break;

        case 2:
          {
            *CmpCommon::diags() << DgSqlCode(-4071) << DgString0(wasDateformat_ ? "DATEFORMAT" : "TO_CHAR");
            bindWA->setErrStatus();
          }
          break;

        case 3:
          {
            *CmpCommon::diags() << DgSqlCode(-4072) << DgString0("TO_CHAR") << DgString1("time");
            bindWA->setErrStatus();
          }
          break;

        case 4:
          {
            *CmpCommon::diags() << DgSqlCode(-4043) << DgString0("TO_DATE");
            bindWA->setErrStatus();
          }
          break;
          
        case 5:
          {
            *CmpCommon::diags() << DgSqlCode(-4046) << DgString0("TO_DATE");
            bindWA->setErrStatus();
          }
          break;
          
        case 6:
          {
            *CmpCommon::diags() << DgSqlCode(-4047) << DgString0("TO_DATE");
            bindWA->setErrStatus();
          }
          break;

        case 7:
          {
            *CmpCommon::diags() << DgSqlCode(-4045) << DgString0("TO_DATE");
            bindWA->setErrStatus();
          }
          break;

        case 8:
          {
            *CmpCommon::diags() << DgSqlCode(-4072) << DgString0("TO_CHAR") << DgString1("date");
            bindWA->setErrStatus();
          }
          break;

        case 9:
          {
            *CmpCommon::diags() << DgSqlCode(-3415) << DgString0("TO_TIME")
                                << DgString1(" It must be a datetime datatype containing the time field or a character datatype.");
            bindWA->setErrStatus();
          }
          break;

        } // switch

      return TRUE;
    }
  
  return FALSE;
}

// used for TO_DATE, TO_CHAR, TO_TIME, DATEFORMAT functions.
DateFormat::DateFormat(ItemExpr *val1Ptr, const NAString &formatStr,
                       Lng32 formatType, NABoolean wasDateformat)
     : CacheableBuiltinFunction(ITM_DATEFORMAT,
                                1, val1Ptr),
       formatStr_(formatStr),
       wasDateformat_(wasDateformat),
       formatType_(formatType),
       frmt_(-1),
       origString_(""),
       dateFormat_(DATE_FORMAT_NONE)
{ 
  allowsSQLnullArg() = FALSE; 

  if (formatStr_ == "SYYYYMM")
    formatStr_ = "YYYYMM";
  else if (formatStr_ == "HH:MI:SS")
    formatStr_ = "HH24:MI:SS";

  frmt_ = ExpDatetime::getDatetimeFormat(formatStr_.data());
}

ItemExpr * DateFormat::bindNode(BindWA * bindWA)
{
  if (checkForSQLnullChild(bindWA, this, allowsSQLnullArg(), FUNCTION_))
    return this;

  bindChildren(bindWA);
  if (bindWA->errStatus()) 
    return this;

  const NAType *naType0 = &child(0)->getValueId().getType();
  const DatetimeType* operand = (DatetimeType *)naType0;
  const NumericType * nType0 = NULL;

  // if the date time format was not specified in TO_CHAR, supply a
  // default now based on the datatype of the first operand
  if (frmt_ == ExpDatetime::DATETIME_FORMAT_UNSPECIFIED)
    {
      if ((naType0->getTypeQualifier() == NA_DATETIME_TYPE) &&
          (operand->getPrecision() == SQLDTCODE_TIME))
        frmt_ = ExpDatetime::DATETIME_FORMAT_TS4;
      else
        frmt_ = ExpDatetime::DATETIME_FORMAT_DEFAULT;
      formatStr_ = ExpDatetime::getDatetimeFormatStr(frmt_);
    }

  // a quick optimization for the date format.
  ItemExpr *newNode = quickDateFormatOpt(bindWA);
  if (newNode)
    return newNode;

  if (errorChecks(frmt_, bindWA, naType0))
    {
      return this;
    }

  dateFormat_ = DateFormat::DATE_FORMAT_NONE;

  if (ExpDatetime::isDateTimeFormat(frmt_))
    {
      // if DATEFORMAT function was specified, then time portion of the
      // format depends on the operand. Date portion remains the same as
      // what was specified (DEFAULT, USA, EUROPEAN).
      if ((wasDateformat_) &&
          (naType0->getTypeQualifier() == NA_DATETIME_TYPE))
        {
          if (operand->getPrecision() == SQLDTCODE_TIMESTAMP)
            {
              if (frmt_ == ExpDatetime::DATETIME_FORMAT_DEFAULT)
                frmt_ = ExpDatetime::DATETIME_FORMAT_TS3;// YYYY-MM-DD HH24:MI:SS
              else if (frmt_ == ExpDatetime::DATETIME_FORMAT_USA)
                frmt_ = ExpDatetime::DATETIME_FORMAT_TS7;// MM/DD/YYYY HH24:MI:SS AM|PM
              else if (frmt_ == ExpDatetime::DATETIME_FORMAT_EUROPEAN)
                frmt_ = ExpDatetime::DATETIME_FORMAT_TS10;// DD.MM.YYYY HH24:MI:SS
            }
        }

       if (ExpDatetime::isTimestampFormat(frmt_))
        dateFormat_ = DateFormat::TIMESTAMP_FORMAT_STR;
      else if (ExpDatetime::isTimeFormat(frmt_))
        dateFormat_ = DateFormat::TIME_FORMAT_STR;
      else
        dateFormat_ = DateFormat::DATE_FORMAT_STR;

     if (naType0->getTypeQualifier() == NA_NUMERIC_TYPE)
        {
          // convert number to char before formatting.
          // Length of target char is equal to formatStr_.
          ItemExpr * newChild =
            new (bindWA->wHeap())
            Cast(child(0),
                 new (bindWA->wHeap())
                 SQLChar(bindWA->wHeap(), formatStr_.length(),
                         child(0)->castToItemExpr()->
                         getValueId().getType().supportsSQLnull()));
          setChild(0, newChild->bindNode(bindWA));
          naType0 = &child(0)->getValueId().getType();
        }
    }
  else if (ExpDatetime::isNumericFormat(frmt_))
    {
      dateFormat_ = DateFormat::TIME_FORMAT_STR;

      if (naType0->getTypeName() != LiteralLargeInt)
        {
          // convert to largeint. We have already verified that
          // child is exact with scale of 0.
          ItemExpr * newChild =
            new (bindWA->wHeap())
            Cast(child(0),
                 new (bindWA->wHeap())
                 SQLLargeInt(bindWA->wHeap(), TRUE,
                             child(0)->castToItemExpr()->
                             getValueId().getType().supportsSQLnull()));
          setChild(0, newChild->bindNode(bindWA));
        }
    }
  else
    {
      CMPASSERT(FALSE); // should not reach here
    }

  // if source is a timestamp and target is date or time, extract
  // date or time part from source before formatting.
  ItemExpr * newChild = NULL;
  if (naType0->getPrecision() == SQLDTCODE_TIMESTAMP)
    {
      if (ExpDatetime::isTimeFormat(frmt_))
        {
          newChild =
            new (bindWA->wHeap())
            Cast(child(0),
                 new (bindWA->wHeap())
                 SQLTime(bindWA->wHeap(), child(0)->castToItemExpr()->
                         getValueId().getType().supportsSQLnull(),
                         0));
        }
      else if (ExpDatetime::isDateFormat(frmt_))
        {
          newChild =
            new (bindWA->wHeap())
            Cast(child(0),
                 new (bindWA->wHeap())
                 SQLDate(bindWA->wHeap(), child(0)->castToItemExpr()->
                         getValueId().getType().supportsSQLnull()));
        }
      
      if (newChild)
        setChild(0, newChild->bindNode(bindWA));
    }

  BuiltinFunction::bindNode(bindWA);
  if (bindWA->errStatus()) 
    return this;

  return getValueId().getItemExpr();  
}

ItemExpr *Trim::bindNode(BindWA *bindWA)
{
  if (nodeIsBound())
    return getValueId().getItemExpr();

  // this will bind/type-propagate all children.
  bindChildren(bindWA);
  if (bindWA->errStatus()) 
    return this;

  if (CmpCommon::getDefault(ALLOW_INCOMPATIBLE_OPERATIONS) == DF_ON)
    {
      // if argument is numeric, convert it to string.
      const NAType &type1 = 
        child(1)->castToItemExpr()->getValueId().getType();
      if (type1.getTypeQualifier() == NA_NUMERIC_TYPE)
        {
          const NumericType &numeric  = (NumericType&)type1;
          Lng32 dLen =
            numeric.getDisplayLength(numeric.getFSDatatype(),
                                     numeric.getNominalSize(),
                                     numeric.getPrecision(),
                                     numeric.getScale(),
                                     0);
          
          ItemExpr * newChild =
            new (bindWA->wHeap())
            Cast(child(1),
                 new (bindWA->wHeap())
                 SQLChar(bindWA->wHeap(), dLen, type1.supportsSQLnull()));
          
          newChild = newChild->bindNode(bindWA);
          if (bindWA->errStatus())
            return this;
          setChild(1, newChild);
        }
    }

  // Trim inherits from BuiltinFunction .. Function .. ItemExpr.
  BuiltinFunction::bindNode(bindWA);
  if (bindWA->errStatus()) 
    return this;

  return getValueId().getItemExpr();
}

// -----------------------------------------------------------------------
// ItemList (which is not ItemExprList!) has arity 2 but arbitrary degree
// (number of list elements), which we capture via this currChildNo()
// propagation.
// -----------------------------------------------------------------------

ItemExpr *ItemList::bindNode(BindWA *bindWA)
{
  ItemList *save = bindWA->getCurrentScope()->context()->inItemList();
  bindWA->getCurrentScope()->context()->inItemList() = this;
  if (save) currChildNo() = save->currChildNo();

  ItemExpr::bindNode(bindWA);

  if (save) save->currChildNo() = currChildNo();
  bindWA->getCurrentScope()->context()->inItemList() = save;

  return this;
} // ItemList::bindNode()

// -----------------------------------------------------------------------
// A method for binding host variables, dynamic parameters and constants.
// -----------------------------------------------------------------------

ItemExpr *ItemExpr::bindUserInput(BindWA *bindWA,
				  const NAType *type,
				  const NAString &fabricatedName)
{
  AssignmentStHostVars *varPtr;
  OperatorTypeEnum opTyp = getOperatorType();

  // If we have a SET statement of compound statements, we return the value id
  // stored in the list assignmentStHostVars_ in bindWA. Such list contains the
  // latest value id assigned to this variable. If it is not there, we bind this ItemExpr
  if ( (opTyp == ITM_HOSTVAR) &&
       (bindWA->getAssignmentStArea()) && (bindWA->getAssignmentStArea()->getAssignmentStHostVars()) &&
       (varPtr = bindWA->getAssignmentStArea()->getAssignmentStHostVars()->findVar(fabricatedName))) {
    ValueId vid = varPtr->currentValueId();
    if ((vid != NULL_VALUE_ID) && !(((HostVar *)this)->isHVInputAssignment())) {
      varPtr->currentValueId().getItemExpr()->previousHostVar() = TRUE;
      varPtr->currentValueId().getItemExpr()->previousName() = ((HostVar *)this)->getName();
      //markAsBound();
      return varPtr->currentValueId().getItemExpr();
    }
  }

  if (nodeIsBound())
    return getValueId().getItemExpr();

  CMPASSERT(isAUserSuppliedInput()) ;

  CMPASSERT(bindWA);
  // Currently we disallow parameters or hostvars in DDL.
  if ( bindWA->inDDL() AND ( getOperatorType() == ITM_DYN_PARAM OR
			     getOperatorType() == ITM_HOSTVAR ) ) {
    *CmpCommon::diags() << DgSqlCode(-3186) << DgString0(fabricatedName);
    bindWA->setErrStatus();
    return this;
  }


  const CharType *ct = (type && type->getTypeQualifier() == NA_CHARACTER_TYPE) ?
		       (const CharType*)type : NULL;

  if (opTyp == ITM_DYN_PARAM AND getText() == "?") {
    DynamicParam* orig = ((DynamicParam*)this)->getOriginal();
    if (orig == NULL) {
      // we're an original dynamic parameter.
      setValueId(createValueDesc(bindWA, this, type));
    }
    else {
      // dynamic parameters must preserve their valueids.
      // otherwise, the result can be uninitialized variables at runtime.
      // dynamic parameters are initialized in the root fragment.
      if (orig->getValueId() == NULL_VALUE_ID)
        orig->setValueId(createValueDesc(bindWA, this, type));
      setValueId(orig->getValueId());
    }
  }
  else if (opTyp == ITM_CONSTANT  AND getText() == "NULL") {
    setValueId(createValueDesc(bindWA, this, type));
  }
  else if (opTyp == ITM_CACHE_PARAM) {
    setValueId(createValueDesc(bindWA, this, type));
    bindWA->addInputValue(fabricatedName, getValueId());
  }
  else if (ct && ct->getCharSet() == CharInfo::UnknownCharSet)
    // Do not reuse valueId on an UnknownCharSet const value.
    setValueId(createValueDesc(bindWA, this, type));
  else {
    NAString fabName(fabricatedName, bindWA->wHeap());
    if (ct) {
      // Collations might be coerced later, in type synth,
      // going up the parse tree.  We need to add this discriminant info!
      char coco[30];
      sprintf(coco, " %d,%d", ct->getCollation(), ct->getCoercibility());
      fabName += coco;
    }
    ColumnNameMap *xcnmEntry = bindWA->findInputValue(fabName);
    if (!xcnmEntry) {
      setValueId(createValueDesc(bindWA, this, type));
      bindWA->addInputValue(fabName, getValueId());
    }
    else {
      if (type &&
          type->getTypeQualifier() == NA_CHARACTER_TYPE)
      {
        if (*type == xcnmEntry->getValueId().getType())
          {
           setValueId(xcnmEntry->getValueId());
          }
          else
          {
            // CR 10-010314-1733
            // For a given constant, the fabricated name needs to be distinct from
            // other names as this name is used as the hash value.
            // The name is initialized using the initial
            // value set by constructor based on the length of the string.
            // Occasionally, if the length and the initial value are same
            // then two different constants may be initialized to the same name: this
            // may cause problems such as type mismatch.

            // To prevent this, we create two random digits and append to
            // the name. Since these names are on statement heap, the probability of
            // two different constants having the same name is almost zero.

            setValueId(createValueDesc(bindWA, this, type));
            char fab[3];
            memset(fab, 0, 3);
            sprintf(fab, "%d", rand() % 100);
            fab[2] = '\0';
            fabName += fab;
            bindWA->addInputValue(fabName,getValueId());
          }
          // else continue binding this item expression
      }
      else
      {
        setValueId(xcnmEntry->getValueId());
        CMPASSERT(!type ||
		  type->getTypeQualifier() == NA_UNKNOWN_TYPE ||
		  *type == getValueId().getType());
      }
    }
  }
  //
  // All user inputs **except constants** are treated as
  // outer references in the current scope.
  //
  if (opTyp != ITM_CONSTANT)
    bindWA->getCurrentScope()->addOuterRef(getValueId());

  bindSelf(bindWA);
  if (bindWA->errStatus()) return this;

  return getValueId().getItemExpr();
} // ItemExpr::bindUserInput()

// -----------------------------------------------------------------------
// Convert a backbone of certain nodes (usually AND nodes) into a value id
// list and get rid of the backbone (NOTE: this does not strictly
// require a left-linear or right-linear backbone, any shape tree with
// 0 or more nodes of type 'backboneType' on its top will work)
// -----------------------------------------------------------------------
Int32 ItemExpr::convertToValueIdList(ValueIdList &vl,
				   BindWA *bindWA,
				   OperatorTypeEnum backboneType,
                                   RelExpr *parent)
{
  // use local stack to implement recursive calls
  stack<ItemExpr*> stk;
  ItemExpr *current_ie;

  stk.push (this);

  while (!stk.empty())
  {
    current_ie = stk.top();
    stk.pop();

    if (current_ie->getOperatorType() == backboneType)
    {
       if (current_ie->child(1))
          stk.push(current_ie->child(1));
       if (current_ie->child(0))
          stk.push(current_ie->child(0));
    }
  else
    {
      // ok, we've reached a non-backbone node, bind the node and insert its
      // value id into the list.
      ItemExpr *boundExpr = current_ie;
      if (!bindWA)
	current_ie->synthTypeAndValueId();
      else
	{
          StmtDDLCreateView *pcvn = NULL;
          if (bindWA->inViewDefinition())
	    {
	      pcvn = bindWA->getCreateViewParseNode();
	      if (pcvn->isProcessingViewColList() &&
		  parent == pcvn->getQueryExpression())
		{
		  if (current_ie->containsSubquery())
		    pcvn->getViewUsages().setViewIsSurelyNotUpdatableFlag();
		  if (current_ie->getOperatorType() == ITM_REFERENCE)
		    {
		      pcvn->setItmColRefInColInRowValsFlag(TRUE);
		      ((ColReference*) current_ie)->setParent(parent);
		    }
		  else
		    pcvn->setItmColRefInColInRowValsFlag(FALSE);
	      }
	    }

	  BindScope *currScope = bindWA->getCurrentScope();
	  if (current_ie->inGroupByOrdinal())
	    {
	      currScope->context()->inGroupByOrdinal() = TRUE;
	    }
          if (current_ie->isGroupByExpr())
	    {
	      currScope->context()->inGroupByExpr() = TRUE;
	    }
	  boundExpr = (ItemExpr *) (current_ie->bindNodeRoot(bindWA));
	  if (current_ie->inGroupByOrdinal())
	    {
	      currScope->context()->inGroupByOrdinal() = FALSE;
	    }
          if (current_ie->isGroupByExpr())
	    {
	      currScope->context()->inGroupByExpr() = FALSE;
	    }

	  if (!boundExpr || bindWA->errStatus())
            return TRUE;		// error

          if (pcvn &&
              pcvn->isProcessingViewColList() &&
              parent == pcvn->getQueryExpression() &&
              NOT pcvn->isItmColRefInColInRowVals())
	    { // see notes in BindUtil_CollectColumnUsageInfo()
	      pcvn->incrCurViewColNum();
	    }
	  else
	  if (parent &&
	      bindWA->getCurrentScope()->context()->counterForRowValues())
	    {
	      bindWA->getCurrentScope()->context()->counterForRowValuesIncr();
	    }
	}

      if (current_ie->getOperatorType() == ITM_REFERENCE &&
          ((ColReference*) current_ie)->getColRefNameObj().isStar() && 
          ((ColReference*) current_ie)->getStarExpansion())
	{
	  ((ColReference*) current_ie)->getStarExpansion()->getValueIdList(vl);
	}
      else
	{
	  vl.insert(boundExpr->getValueId());
	}


      if (bindWA && (boundExpr->getValueId() != NULL_VALUE_ID) &&
	  (boundExpr->getValueId().getType().isLob()))
      {
	BindScope *currScope = bindWA->getCurrentScope();

	BindContext *currContext = currScope->context();
	if (currContext->inOrderBy() ||
	    currContext->inExistsPredicate() ||
	    currContext->inGroupByClause() ||
	    currContext->inHavingClause() ||
	    currContext->inUnion() ||
	    currContext->inJoin()
	  )
	{
	  *CmpCommon::diags() << DgSqlCode(-4322);
	  bindWA->setErrStatus();
	  return TRUE;  // error
	}
      }

    // If the valueId of the column corresponds to the USER(x) function
    // and appears at any place other than the outer select list, then give
    // an error. If the user(x) function appears directly in the query
    // then these errors will be caught while binding the user function itself.
    // This check is for case where column derived from user(x) is being
    // used in the query. This will have to be caught after it has got its valuId
    // and that valueId corresponds to the user(x) function.

    if (bindWA && (boundExpr->getOperatorType() == ITM_USER))
    {
      BindScope *prevScope = NULL;
      BindScope *currScope = bindWA->getCurrentScope();

      while (currScope)
      {
	BindContext *currContext = currScope->context();
	if (currContext->inSubquery() ||
	    currContext->inOrderBy() ||
	    currContext->inExistsPredicate() ||
	    currContext->inGroupByClause() ||
	    currContext->inWhereClause() ||
	    currContext->inHavingClause() ||
	    currContext->inUnion() ||
	    currContext->inJoin()
	  )
	{
 	    *CmpCommon::diags() << DgSqlCode(-4310)
				<< DgString0("USER(x)");
	    bindWA->setErrStatus();
	    return TRUE;  // error
	}
	prevScope = currScope;
	currScope = bindWA->getPreviousScope(prevScope);
      }
    }
    else if ( bindWA &&
              (bindWA->getCurrentScope()->context()->inOrderBy() ||
               bindWA->getCurrentScope()->context()->inGroupByClause()) )
    {
      // Temporary fix till random is supported in ORDER BY, GROUP BY
      // For now do not allow random in order by clause, Group By
      // and distinct.  
      if (boundExpr->containsOpType(ITM_RANDOMNUM)) {
        *CmpCommon::diags() << DgSqlCode(-4313);
        bindWA->setErrStatus();
        return TRUE; // error
      }
    }
  }
 }

 if (stk.empty())
   return FALSE;

  return TRUE;
} // ItemExpr::convertToValueIdList()

//
// MACROS used by SEMI-NON-RECURSIVE version of ItemExpr::convertToValueIdSet(...) below
//
#define AVR_STATE0 0
#define AVR_STATE1 1
#define AVR_STATE2 2

// -----------------------------------------------------------------------
// Convert a backbone of certain nodes (usually AND nodes) into a value id
// set and get rid of the backbone (NOTE: this does not strictly
// require a left-linear or right-linear backbone, any shape tree with
// 0 or more nodes of type 'backboneType' on its top will work)
// -----------------------------------------------------------------------
Int32 ItemExpr::convertToValueIdSet(ValueIdSet &vs,
				  BindWA *bindWA,
				  OperatorTypeEnum backboneType,
				  NABoolean tfmSubq,
				  NABoolean flattenLists)
{
  //
  // convertToValueIdSet() used to be called recursively not just
  // for all the items in an expression but for all the items in the node
  // tree for an entire query. Consequently, we must eliminate the recursive
  // calls to convertToValueIdSet() by keeping the information needed by
  // each "recursive" level in the HEAP and using a "while" loop to look
  // at each node in the tree in the same order as the old recursive technique
  // would have done.
  // The information needed by each "recursive" level is basically just
  // * a pointer to what node (ItemExpr *) to look at next, and
  // * a "state" value that tells us where we are in the convertToValueIdSet()
  //   code for the ItemExpr node that we are currently working on
  //
  ARRAY( ItemExpr * ) IEarray(HEAP, 10) ; //Initially 10 elements (no particular reason to choose 10)
  ARRAY( Int16 )      state(HEAP, 10)   ; //These ARRAYs will grow automatically as needed.)

  Int32  currIdx    = 0           ;
  IEarray.insertAt( currIdx, this       ) ; //Initialize first array element
  state.insertAt(   currIdx, AVR_STATE0 ) ;

  Int32 status = FALSE ;

  while( currIdx >= 0 )
  {
    ItemExpr * currIE = IEarray[currIdx] ;

    if ( currIE->getOperatorType() == backboneType )
    {
      switch ( state[currIdx] )
      {
        case AVR_STATE0:
          // this is a backbone node, recurse and then delete the backbone node
          CMPASSERT( currIE->getArity() == 2 );

          state.insertAt( currIdx, AVR_STATE1 ) ;
          currIdx++ ;                               //"Recurse" down to child 0
          state.insertAt(   currIdx, AVR_STATE0 ) ; // and start that child's state at 0
          IEarray.insertAt( currIdx, currIE->child(0) ) ;

          // if (status) return status; Commented out since return will be done later
          continue ;

        case AVR_STATE1:
          state.insertAt( currIdx, AVR_STATE2 ) ;
          currIdx++ ;                               //"Recurse" down to child 1
          state.insertAt(   currIdx, AVR_STATE0 ) ; // and start that child's state at 0
          IEarray.insertAt( currIdx, currIE->child(1) ) ;

          // if (status) return status; Commented out since return will be done later
          continue ;

        case AVR_STATE2:
          state.insertAt( currIdx, AVR_STATE0 ) ; // We are done processing 'currIE'
          break;
      }

      // If user had specified selectivity for the compound predicate, then make 
      // sure the child predicates get proportionate share of the selectivity.
      if( currIE->isSelectivitySetUsingHint() )
      {
        double newSelFactor = sqrt( currIE->getSelectivityFactor() );

        currIE->child(0)->setSelectivitySetUsingHint();
        currIE->child(0)->setSelectivityFactor( newSelFactor );

        currIE->child(1)->setSelectivitySetUsingHint();
        currIE->child(1)->setSelectivityFactor( newSelFactor );
      }
    }
    else
    {
      // ok, we've reached a non-backbone node, bind the node and insert its
      // value id into the set.
      ItemExpr *boundExpr = currIE;
      if (!bindWA)
         currIE->synthTypeAndValueId() ;
      else
      {
        boundExpr = (ItemExpr *) currIE->bindNodeRoot(bindWA) ;
        if (bindWA->errStatus()) 
          return TRUE;
        if (! boundExpr)
          {
            bindWA->setErrStatus();
            return TRUE;             // error
          }

        if ( bindWA->getCurrentScope()->context()->inOrderBy() ||
             bindWA->getCurrentScope()->context()->inGroupByClause() )
        {
          // Temporary fix till random is supported in ORDER BY, GROUP BY
          // For now do not allow random in ORDER BY clause, GROUP BY
          // and DISTINCT.
          if (boundExpr->containsOpType(ITM_RANDOMNUM))
          {
            *CmpCommon::diags() << DgSqlCode(-4313);
            bindWA->setErrStatus();
            return TRUE; // error
          }
        }

        if ( bindWA && (boundExpr->getValueId() != NULL_VALUE_ID) &&
             ( boundExpr->getValueId().getType().isLob() ) )
        {
          BindScope *currScope = bindWA->getCurrentScope();

          BindContext *currContext = currScope->context();
          if (currContext->inOrderBy() ||
              currContext->inExistsPredicate() ||
              currContext->inGroupByClause() ||
              currContext->inHavingClause() ||
              currContext->inUnion() ||
              currContext->inJoin()
            )
          {
            *CmpCommon::diags() << DgSqlCode(-4322);
            bindWA->setErrStatus();
            return TRUE; // error
          }
        }
      }

      if ( currIE->getOperatorType() == ITM_REFERENCE &&
          ((ColReference *)currIE)->getColRefNameObj().isStar()  &&
          ((ColReference *)currIE)->getStarExpansion())
      {
        const ColumnDescList& cl = *(((ColReference *)currIE)->getStarExpansion());
        for (CollIndex i = 0; i < cl.entries(); i++)
          vs.insert(cl[i]->getValueId());
      }
      else if ( tfmSubq && backboneType == ITM_AND
                && currIE->containsSubquery() )
      {
        // If *all* my children are MVPs, insert my transform (not me).
        //
        // If a "raw-mode" retry could transform *any* MVPs,
        // insert the raw transform (containing all my subqueries) *AND*
        // insert me too.
        //
        // See dissectOutSubqueries in NormItemExpr.cpp for rationale.
        //
        ItemExpr *tfm = currIE->transformMultiValuePredicate(FALSE/*do NOT flatten*/);
        if (tfm)
          tfm->convertToValueIdSet(vs, bindWA, backboneType, FALSE);
        else
        {
          if (!bindWA) // do not do this at bindtime
            tfm = currIE->transformMultiValuePredicate(FALSE, ANY_CHILD_RAW);
          if (tfm)
            tfm->convertToValueIdSet(vs, bindWA, backboneType, FALSE);
          vs.insert(boundExpr->getValueId());
        }

        if(tfm && ( tfm->getOperatorType() == ITM_AND))
        {
          tfm->synthTypeAndValueId(TRUE);

          // check for the added prefix predicate
          ItemExpr * leftChildOfAND = (ItemExpr *)tfm->child(0);

          if((leftChildOfAND->isARangePredicate()) &&
             ((BiRelat *)leftChildOfAND)->isDerivedFromMCRP())
          {
            BiRelat * addedComparison = (BiRelat *) leftChildOfAND;
            addedComparison->translateListOfComparisonsIntoValueIds();
          }
        }
      }
      else if ( ( flattenLists == TRUE )
                && ( currIE->getOperatorType() == ITM_ITEM_LIST ) )
      {
        status = currIE->convertToValueIdSet(vs, bindWA, ITM_ITEM_LIST, 
                                             tfmSubq, flattenLists);
        if (status) return status;
      }
      else 
      {
        vs.insert(boundExpr->getValueId());
      }
    }
    if ( state[currIdx] == AVR_STATE0 )
       currIdx-- ;       // Return to the parent node & continue working on it

  } // end of while( currIdx >= 0 )

  return status ;
} // ItemExpr::convertToValueIdSet

// -----------------------------------------------------------------------
// member functions for class Aggregate
// -----------------------------------------------------------------------

ItemExpr *Aggregate::bindNode(BindWA *bindWA)
{
  if (nodeIsBound())
    return getValueId().getItemExpr();

  if(isOLAP()) {
    ItemExpr *olap = transformOlapFunction( bindWA );
    if(!olap) {
      return NULL;
    }

    return olap->bindNode(bindWA);
  }

  // Genesis 10-000222-6892:
  // An AVG is really "SUM / COUNT_NONULL";
  // the fix saves the outer Agg Scope (bindWA->outerAggScope())from the first part (SUM)
  // to be applied to the second part (COUNT).
  //
  // VARIANCE and STDDEV are likewise compositions of primitive aggr-funcs.
  // See Variance::bindNode() and subaggBindNode()
  // where the outer Agg Scope (bindWA->outerAggScope())is saved + reapplied in a similar fashion.
  //
  // Lines which have been CLONED or COPIED are marked "AggBind#n".

  if (origOpType() != ITM_AVG)      // AggBind#1 support
    bindWA->outerAggScope() = NULL;

  else if (getOperatorType() == ITM_AVG) {

    ItemExpr *sum = new (bindWA->wHeap())
      Aggregate(ITM_SUM,          child(0), isDistinct(), ITM_AVG, '!');
    ItemExpr *cnt = new (bindWA->wHeap())
      Aggregate(ITM_COUNT_NONULL, child(0), isDistinct(), ITM_AVG, '!');
    ItemExpr *avg = new (bindWA->wHeap())
      BiArith(ITM_DIVIDE, sum, cnt);
    avg->setOrigOpType(ITM_AVG);

    bindWA->outerAggScope() = NULL;			// SUM may change this for CNT

    // 
    // NOTE: Removed code from right here.  That code was calling bindNode
    // on the *sum and *cnt nodes.  The code was not needed since the 
    // following avg->bindNode() operation will call bindChildren() to bind
    // the children.  Furthermore, now that we are supporting OLAP functions,
    // the bindNode() operation on each of the children may return a pointer
    // to a different node (a ITM_NOTCOVERED node) than the original child
    // nodes.  bindChildren() will handle that properly, whereas the code
    // that has been deleted from here was ignoring the possibility that
    // sum->bindNode() and/or cnt->bindNode() might return different ptrs.
    // 

    avg = avg->bindNode(bindWA);
    if (bindWA->errStatus()) return NULL;

    markAsBound();
    setValueId(avg->getValueId());
    return getValueId().getItemExpr();		// AVG node is never seen again

  } // top-level AVG

  BindScope   *currScope = bindWA->getCurrentScope();
  BindContext *context   = currScope->context();

  if (context->inAggregate()) {
    // 4009 An aggregate is not allowed inside an aggregate.
    *CmpCommon::diags() << DgSqlCode(-4009);
    bindWA->setErrStatus();
    return NULL;
  }

  // an aggregate is not allowed to be referenced as a group by expr.
  if (bindWA->getCurrentScope()->context()->inGroupByExpr()) {
    *CmpCommon::diags() << DgSqlCode(-4197)
                        << DgString0("GROUP BY");
    bindWA->setErrStatus();
    return NULL;
  }

  // an aggregate is not allowed to be referenced as a group by ordinal.
  if (bindWA->getCurrentScope()->context()->inGroupByOrdinal()) {
    *CmpCommon::diags() << DgSqlCode(-4185);
    bindWA->setErrStatus();
    return NULL;
  }

  context->inAggregate() = TRUE;

  CMPASSERT(NOT context->colRefInAgg());
  CMPASSERT(NOT context->outerColRefInAgg() ||
	    origOpType() == ITM_STDDEV || origOpType() == ITM_VARIANCE);

  if (checkForSQLnullChild(bindWA, this, FALSE, FUNCTION_)) return this;


  // The Aggregates are bound in the environment (RETDesc) of
  // the child of the OLAP Sequence if one exists
  //
  RelSequence *sequenceNode = (RelSequence *)currScope->getSequenceNode();
  RETDesc *currentRETDesc = NULL;
  NABoolean isOLAPSequence = FALSE;

  // An empty requiredOrder() indicates that this Sequence is for OLAP.
  // (may want to have a better way of indicating this.
  //
  if (sequenceNode && 
      (((const RelSequence *)sequenceNode)->requiredOrder().entries() == 0)) {

    currentRETDesc = currScope->getRETDesc();
   
    currScope->setRETDesc(sequenceNode->child(0)->getRETDesc());
    isOLAPSequence = TRUE;
  }

  if ((CmpCommon::getDefault(MODE_SPECIAL_1) == DF_ON) &&
      (getOperatorType() == ITM_SUM))
    {
      // bind/type-propagate all children.
      bindChildren(bindWA);
      if (bindWA->errStatus()) 
	return this;

      const NAType &type1 = 
	child(0)->castToItemExpr()->getValueId().getType();

      if (type1.getTypeQualifier() == NA_CHARACTER_TYPE)
	{
	  // convert to double precision. This will handle all precision,
	  // scale and type specified in the char value.
	  ItemExpr * newChild =
	    new (bindWA->wHeap())
	    Cast(child(0),
		 new (bindWA->wHeap())
		 SQLDoublePrecision(bindWA->wHeap(), type1.supportsSQLnull()));
	  setChild(0, newChild->bindNode(bindWA));
	}

    }

  ItemExpr::bindNode(bindWA);	// Aggregate is directly derived from ItemExpr
  
  // Restore current RETDesc.
  if(isOLAPSequence) {
    currScope->setRETDesc(currentRETDesc);
  }

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

  // Now that we allow UDFs and subqueries as inputs to aggregates, we need
  // to make sure they have a degree of 1.

  CollIndex childDegree = 0;
  Subquery * subq = NULL;
  UDFunction * udf = NULL;
  Int32 origArity = getArity();

  for (Int32 chld=0; chld < origArity; chld++)
  {
    switch (child(chld)->getOperatorType())
    {
       case ITM_ROW_SUBQUERY:
       case ITM_USER_DEF_FUNCTION:
       {
         subq = (Subquery *) child(chld)->castToItemExpr();
         udf = (UDFunction *) child(chld)->castToItemExpr();
         Lng32 myDegree = 
                       (child(chld)->getOperatorType() == ITM_ROW_SUBQUERY)?
                       subq->getSubquery()->getDegree() :
                       udf->getRoutineDesc()->getOutputColumnList().entries(); 
         childDegree += myDegree;
           // If the subquery or MVF was the only given input, and it has a 
           // degree of 2, assign child1 of the aggregate to be the 
           // second element of the subquery/MVF output.
           // This will allow us to use a subquery or MVF to specify all 
           // inputs to STDDEV or VARIANCE
         if ((childDegree == 2) && (getArity() == 1))
         {
           ItemExprList *mDegreeList = (ItemExprList *) new(bindWA->wHeap())
                                     ItemExprList(child(chld)->castToItemExpr()
                                     ,bindWA->wHeap());

           ItemExpr * ie = mDegreeList->convertToItemExpr();
           ie->bindNode(bindWA);
           if (bindWA->errStatus()) return this;

           ValueIdList mDegreeVlist;
           ie->convertToValueIdList(mDegreeVlist, bindWA, ITM_ITEM_LIST);

           child(1) = mDegreeVlist[1].getItemExpr(); 
           // we do not need to adjust the arity, since the aggregate
           // arity method looks at how many child pointers are not null.
         }
       }
       break;

       default:
         childDegree += 1;
         break;
    }
  }
  if (getOperatorType() == ITM_STDDEV || getOperatorType() == ITM_VARIANCE)
  {
    if (childDegree < 1 || childDegree > 2 )
    {
      *CmpCommon::diags() << DgSqlCode(-4077) << DgString0(getTextUpper());
      bindWA->setErrStatus();
      return NULL;
    }
  }
  else
  {
      // We don't want to test the ITM_ONEROW since it is an internal 
      // constructs and will often have a subquery or UDF as a child 
      // The subquery or UDF outputs will eventually get a separate ITM_ONEROW
      // per output 
    if (childDegree != 1  && getOperatorType() != ITM_ONEROW )
    {
      *CmpCommon::diags() << DgSqlCode(-4476) << DgString0(getTextUpper());
      bindWA->setErrStatus();
      return NULL;
    }
  }

  context->colRefInAgg() = FALSE;
  context->inAggregate() = FALSE;

  // Return now to Variance::bindNode() after binding child of the initial
  // STDDEV or VARIANCE.  The important thing is that returning now preserves
  // the BindContext, in particular outerColRefInAgg() and (outer)aggScope.
  //
  if (getOperatorType() == ITM_STDDEV || getOperatorType() == ITM_VARIANCE)
    return getValueId().getItemExpr();

  // If second or subsequent part of any other decomposed aggregate like AVG,
  // reestablish the outer agg scope (stored in bindWA->outerAggScope())
  if (bindWA->outerAggScope()) {			// reestablish AggBind#1
    context->outerColRefInAgg() = TRUE;			//
    context->aggScope() = bindWA->outerAggScope();	// reestablish AggBind#2
  }

  if (getOperatorType() == ITM_COUNT_NONULL &&
      !isDistinct() &&
      !child(0)->getValueId().getType().supportsSQLnullLogical() &&
      !(bindWA->inDDL() && bindWA->isBindingMvRefresh()) ) {
    context->outerColRefInAgg() = FALSE;
    context->aggScope() = NULL;
    ItemExpr *countStar = new (bindWA->wHeap()) SystemLiteral(1);
    countStar = countStar->bindNode(bindWA);
    if (bindWA->errStatus()) return NULL;
    setChild(0, countStar);
    setOperatorType(ITM_COUNT);
  }

  // Outer column reference
  if (context->outerColRefInAgg()) {				// AggBind#1
    currScope->addOuterRef(getValueId());			// AggBind#2
    context->aggScope()->addLocalRef(getValueId());		// AggBind#3
    context->outerColRefInAgg() = FALSE;			// AggBind#4
    bindWA->outerAggScope() = context->aggScope();		// save for next time, maybe
    CMPASSERT(context->aggScope() != currScope);
  }
  // No column reference, i.e. constant ref:  COUNT(*) internally is COUNT(1)
  else if (context->aggScope() == NULL)
    context->aggScope() = currScope;
  else
    CMPASSERT(context->aggScope() == currScope);    // Local column reference

  // If this is an aggregate for a scalar GroupByAgg make it nullable
  // if it isn't already and if it isn't a count
  if (context->aggScope()->context()->inScalarGroupBy()) {

    // Mark the aggregate expr as one that is computed by a scalar GroupByAgg
    setInScalarGroupBy();

    if (getOperatorType() != ITM_COUNT &&
        getOperatorType() != ITM_COUNT_NONULL) {
      // Note that synthesizeNullableType() returns self if already nullable
      const NAType* nullableType =
	getValueId().getType().synthesizeNullableType(bindWA->wHeap());
      getValueId().changeType(nullableType);
    }
  }

  if (isDistinct())
    setDistinctValueId(child(0)->getValueId());

  // This may introduce a GroupByAgg in RelRoot::bindNode().
  ValueId aggrId = context->aggScope()->addUnresolvedAggregate(getValueId());

  // May have found an equivalent aggregate.  If so, make sure we use
  // the replacement.
  //
  setValueId(aggrId);

  context->aggScope() = NULL;					  // AggBind#6

  // If there is an Sequence operator for OLAP functions, then add
  // this non-OLAP Aggregate to the outputs of the Sequence operator.
  // All outputs of the Sequence operator have an NotCovered on top of
  // them
  //
  if(isOLAPSequence &&
     !context->inOtherSequenceFunction() &&
     // no need to add aggregate to sequenced columns if it is in having clasue
     // and we don't want to add NotCovered on top of it
     !context->inHavingClause()) 
  {
    ItemExpr *notCov = new (bindWA->wHeap()) NotCovered (this);
    ItemExpr *boundExpr = notCov->bindNode(bindWA);
    if (bindWA->errStatus()) return NULL;
    
    // Add the aggregate to the sequenced columns.  These represent the 
    // outputs of the Sequence Operator.  More outputs will be added
    // when the Sequence operator is bound.
    //
    sequenceNode->addSequencedColumn(boundExpr->getValueId());
    
    return boundExpr;

  } else {
    return getValueId().getItemExpr();
  }
} // Aggregate::bindNode()

// -----------------------------------------------------------------------
// Variance::bindNode()
//
// Variance is a subclass of Aggregate.
// This class implements the compiler side of the Variance and Stddev
// aggregates.  This new class redefines the {con,de}structor, the bindNode
// method, and the getText method.  The other methods are NEVER called
// for this class and have (for now) been redefined to ASSERT if called.
//
// The bindNode method does some type checking and error reporting and then
// replaces the Variance node with a tree of nodes rooted by a ScalarVariance
// node.  This new tree is bound and returned as the result of bindNode of
// Variance.  Because of this, the Variance node should never appear after
// binding.  The Variance is translated in the following way:
//
// (unweighted)
// Variance(<expr>) ->
//
// ScalarVariance(SUM(Cast(<expr>) * Cast(<expr>)),
//                SUM(Cast(<expr>)),
//                Cast(COUNT(Cast(<expr>))))
//
// (weighted)
// Variance(<expr>, <weight>) ->
//
// ScalarVariance(SUM(Cast(<expr>) * Cast(<expr>) * Cast(<weight>)),
//                SUM(Cast(<expr>) * Cast(<weight>)),
//                SUM(Cast(<weight>)))
//
// All Cast expressions are cast to Nullable SQLDoublePrecision.
// Each occurrence of a common subexpression is constructed once, then reused.
// -----------------------------------------------------------------------

static Aggregate *subaggBindNode(BindWA *bindWA,
				 BindScope *currScope,
				 BindScope *outerAggScope,
				 Aggregate *&agg,		// INOUT
				 const Aggregate *origAgg,
				 ValueId distinctId)
{
  agg->setOriginalChild(origAgg->getOriginalChild());
  agg->setOrigOpType(origAgg->origOpType());

  if (outerAggScope) {						// AggBind#1
    BindContext *context = currScope->context();
    CMPASSERT(context->aggScope() == NULL ||
    	      context->aggScope() == outerAggScope);
    context->aggScope() = outerAggScope;			// AggBind#6,1
    context->outerColRefInAgg() = TRUE;				// AggBind#4,1
  }

  agg = (Aggregate *)agg->bindNode(bindWA);			// INOUT pointer
  if (bindWA->errStatus()) return NULL;

  Aggregate *AggTmp  = agg;

  //
  // Now that we support OLAP functions, the agg->bindNode() operation above
  // may have returned a pointer to an ITM_NOTCOVERED node.  If so, we
  // need to check its child(0) node rather than the ITM_NOTCOVERED node.
  //
  if (AggTmp->getOperatorType() == ITM_NOTCOVERED )
      AggTmp = (Aggregate *)(ItemExpr *)AggTmp->child(0);

  CMPASSERT(AggTmp->isAnAggregate());

  if (distinctId != NULL_VALUE_ID)
    AggTmp->setDistinctValueId(distinctId);

  return agg; //Return ptr to original node (NOTCOVERED node, if there is one)
}

ItemExpr *Variance::bindNode(BindWA *bindWA)
{
  if (nodeIsBound())
    return getValueId().getItemExpr();

  if (isOLAP())
  {
    if (getArity() > 1) 
    {
      *CmpCommon::diags() << DgSqlCode(-4078) << DgString0(getTextUpper());
      bindWA->setErrStatus();
      return NULL;
    }
    ItemExpr *olap = Aggregate::bindNode(bindWA);
    if (! olap || bindWA->errStatus()) return NULL;
    
    setValueId(olap->getValueId());
    return getValueId().getItemExpr();
  }
    // Variance/Stddev must have either one or two arguments.
  // The optional second argument is the weighting parameter.
  //
  if (getArity() < 1 || getArity() > 2) {
    *CmpCommon::diags() << DgSqlCode(-4077) << DgString0(getTextUpper());
    bindWA->setErrStatus();
    return NULL;
  }

  // The steps to bind this node are:
  //
  // 1) Bind the children of this node.
  // 2) Check the datatypes of the children.
  // 3) Construct the replacement ItemExpr tree.
  // 4) Bind the newly constucted tree.
  // 5) return this as the result of binding Variance.

  // Variance is directly derived from class Aggregate.
  //
  ItemExpr *result;
  ItemExpr *tmp = Aggregate::bindNode(bindWA);
  if (bindWA->errStatus()) return NULL;

  // Needed to do this check after binding our inputs in case we had 
  // a MVF or subquery > 1 as an input. 
  const Int32 weighted = (getArity() >= 2);

  // Variance/Stddev does not support both Distinct and Weighted simultaneously.
  //
  if (weighted && isDistinct()) {
    *CmpCommon::diags() << DgSqlCode(-4078) << DgString0(getTextUpper());
    bindWA->setErrStatus();
    return NULL;
  }

  //
  // Now that we support OLAP functions, the bindNode() operation above
  // may have returned a pointer to an ITM_NOTCOVERED node.  If so, we
  // need to work with its child(0) node rather than the ITM_NOTCOVERED node.
  //
  if (tmp->getOperatorType() == ITM_NOTCOVERED )
     tmp = tmp->child(0);

  ItemExpr *boundChild0 = tmp->child(0);
  ItemExpr *boundChild1 = tmp->child(1);

  BindScope   *currScope     = bindWA->getCurrentScope();
  BindContext *context       = currScope->context();
  BindScope   *outerAggScope = NULL;
  if (context->outerColRefInAgg()) {				// AggBind#1
    outerAggScope = context->aggScope();
    CMPASSERT(outerAggScope);
  }

  // Get the types of the children determined by binding.
  // Make sure they are NUMERIC or INTERVAL (later)
  //
  const NAType& oper0 = boundChild0->getValueId().getType();
  const NAType& oper1 = weighted ? boundChild1->getValueId().getType() : oper0;

  // Only NUMERIC datatypes are supported. INTERVAL will be supported later.
  //
  if (oper0.getTypeQualifier() != NA_NUMERIC_TYPE ||
      oper1.getTypeQualifier() != NA_NUMERIC_TYPE) {
    *CmpCommon::diags() << DgSqlCode(-4079) << DgString0(getTextUpper());
    bindWA->setErrStatus();
    return NULL;
  }

  // Cast the children nodes to this type.
  // This will force the calculations to be done using
  // double precision floating point.
  // Assumes that the type propogation will make the types
  // of the child of the ScalarVariance node all double precision floats.
  //
  const NAType *desiredType = new (bindWA->wHeap()) SQLDoublePrecision(bindWA->wHeap(), TRUE);

  // Cast the first child to the desired type.
  // This is the itemExpr which should be distinct.
  //
  ItemExpr *variChild = new (bindWA->wHeap()) Cast(boundChild0, desiredType);
  ValueId distinctId = isDistinct() ? boundChild0->getValueId() : NULL_VALUE_ID;

  // Cast the second child (if it exists) to the desired type.
  // If it does not exist, it is set to NULL, and should not be used.
  //
  ItemExpr *variWeight = weighted
    ? new (bindWA->wHeap()) Cast(boundChild1, desiredType)
    : NULL;

  // The weighted child is the ItemExpr
  //   (Cast(<expr>) * Cast(<weight>)) 				-- weighted
  //   (Cast(<expr>)) 						-- unweighted
  //
  ItemExpr *weightedChild = weighted
    ? new (bindWA->wHeap()) BiArith(ITM_TIMES,
				    variChild,
				    variWeight)
    : variChild;

  // The Sum of Val Squared is the ItemExpr
  //   (SUM(Cast(<expr>) * Cast(<expr>) * Cast(<weight>)))	-- weighted
  //   (SUM(Cast(<expr>) * Cast(<expr>)))			-- unweighted
  //
  Aggregate *sumOfValSquared =
    new (bindWA->wHeap())
    Aggregate(ITM_SUM,
	      new (bindWA->wHeap())
	      BiArith(ITM_TIMES,
		      variChild,
		      weightedChild),
	      isDistinct());

  result = subaggBindNode(bindWA, currScope, outerAggScope,
  			  sumOfValSquared, this, distinctId);
  if (bindWA->errStatus()) return NULL;

  // Sum of Val is the ItemExpr (SUM(Cast(<expr>) * Cast(<weight>)))
  // for the weighted case and (SUM(Cast(<expr>)) for the unweighted case.
  //
  Aggregate *sumOfVal =
    new (bindWA->wHeap())
    Aggregate(ITM_SUM,
	      weightedChild,
	      isDistinct());

  result = subaggBindNode(bindWA, currScope, outerAggScope,
  			  sumOfVal, this, distinctId);
  if (bindWA->errStatus()) return NULL;

  // Count of Val is the ItemExpr (SUM(Cast(<weight>))) for the
  // weighted case and (Cast(COUNT(Cast(<expr>)))) for the unweighted case.
  //
  Aggregate *countOfVal =
    		 weighted
		 ? new (bindWA->wHeap()) Aggregate(ITM_SUM,
						   variWeight,
						   isDistinct())
		 : new (bindWA->wHeap()) Aggregate(ITM_COUNT_NONULL,
						   weightedChild,
						   isDistinct());

  result = subaggBindNode(bindWA, currScope, outerAggScope,
  			  countOfVal, this, distinctId);
  if (bindWA->errStatus()) return NULL;

  // The result is the ItemExpr
  //
  // (ScalarVariance(SUM(Cast(<expr>) * Cast(<expr>) * Cast(<weight>)),
  //                 SUM(Cast(<expr>) * Cast(<weight>)),
  //                 SUM(Cast(<weight>))))
  // for the weighted case and
  //
  // (ScalarVariance(SUM(Cast(<expr>) * Cast(<expr>)),
  //                 SUM(Cast(<expr>)),
  //                 Cast(COUNT(<expr>))))
  // for the unweighted case.
  //
  // Bind the newly constructed ItemExpr Tree and return it as the
  // result of binding the Variance node.  The Variance node should
  // not be seen after this point.

  result = new (bindWA->wHeap())
    ScalarVariance(getOperatorType(),
		   sumOfValSquared,
		   sumOfVal,
		   weighted
		     ? (ItemExpr *)countOfVal
		     : (ItemExpr *)new (bindWA->wHeap())
		     		   Cast(countOfVal, desiredType)
		  );
  result->setOrigOpType(origOpType());

  result = result->bindNode(bindWA);
  if (bindWA->errStatus()) return NULL;

  // Make sure that the assumptions about type propagation producing the
  // desired types are correct.
  //
  NumericType &type_ret =
    (NumericType &)(result->getValueId().getType());

  NumericType &type_op0 =
    (NumericType &)(result->child(0)->getValueId().getType());

  NumericType &type_op1 =
    (NumericType &)(result->child(1)->getValueId().getType());

  NumericType &type_op2 =
    (NumericType &)(result->child(2)->getValueId().getType());

  CMPASSERT(type_ret.getTypeQualifier() == NA_NUMERIC_TYPE &&
	    type_op0.getTypeQualifier() == NA_NUMERIC_TYPE &&
	    type_op1.getTypeQualifier() == NA_NUMERIC_TYPE &&
	    type_op2.getTypeQualifier() == NA_NUMERIC_TYPE &&
	    !type_ret.isExact() &&
	    !type_op0.isExact() &&
	    !type_op1.isExact() &&
	    !type_op2.isExact() &&
	    type_ret.getBinaryPrecision() == SQL_DOUBLE_PRECISION &&
	    type_op0.getBinaryPrecision() == SQL_DOUBLE_PRECISION &&
	    type_op1.getBinaryPrecision() == SQL_DOUBLE_PRECISION &&
	    type_op2.getBinaryPrecision() == SQL_DOUBLE_PRECISION);

  setValueId(result->getValueId());
  return getValueId().getItemExpr();
} // Variance::bindNode()

// -----------------------------------------------------------------------
// member functions for class PivotGroup
// -----------------------------------------------------------------------

ItemExpr *PivotGroup::bindNode(BindWA *bindWA)
{
  ItemExpr * result = NULL;
  
  if (nodeIsBound())
    return getValueId().getItemExpr();
  
  result = Aggregate::bindNode(bindWA);
  if (! result || bindWA->errStatus()) 
    return NULL;
  
  return result;
}

// -----------------------------------------------------------------------
// member functions for class BiArith
// -----------------------------------------------------------------------

ItemExpr *BiArith::bindNode(BindWA *bindWA)
{
  ItemExpr * result = NULL;

  if (nodeIsBound())
    return getValueId().getItemExpr();

  if (checkForSQLnullChild(bindWA, this, FALSE, ARITH_, isUnaryNegate()))
    return this;

  // Unary negate "-x" is represented as binary minus "0 - x".
  // Need to change this to "INTERVAL '0...0' qualifier - x" if x is INTERVAL.
  if (isUnaryNegate()) {
    CMPASSERT(getOperatorType() == ITM_MINUS);

    child(1) = child(1)->bindNode(bindWA);
    if (bindWA->errStatus()) return this;

    const NAType *naType = &child(1)->getValueId().getType();

    if (naType->getTypeQualifier() == NA_UNKNOWN_TYPE) {
      // Emitting errmsg here is necessary for Tandem extension to allow use of
      // INSERT INTO t VALUES(..., -DEFAULT, ...)
      // and because here we've bypassed the checking in ItemExpr::bindSelf,
      // by doing our own child() processing.
      //
      // SELECT -?param FROM t  strictly speaking deserves an error message.
      // We're going to do what the user intended, i.e. to allow it
      // (the synthType will implicitly CAST the param to some numeric type).
      // Genesis 10-981110-4799.
      //
      if (child(1)->getOperatorType() != ITM_DYN_PARAM &&
          !checkForSQLnullChild(bindWA, this, FALSE, ARITH_, isUnaryNegate()))
        CMPASSERT(FALSE);
    }
    else {

      if (naType->supportsSQLnull()) {
	// E.g., in "SELECT -CAST(99 AS INTERVAL DAY) ...",
	// child1's type is nullable (the CAST), but the child0 we're about
	// to fabricate needs to have a NONnullable type.
        NAType *t = naType->newCopy(bindWA->wHeap());
	t->setNullable(FALSE);
	naType = t;
      }

      if (naType->getTypeQualifier() == NA_INTERVAL_TYPE) {
	// NAType : IntervalType : SQLInterval : IntervalQualifier
	const IntervalQualifier *qualifier = (IntervalQualifier *)naType;
        NAString *literal;
 Lng32 tmpvallen = 20;
	char tmpval[20];
	CMPASSERT(tmpvallen >= qualifier->getTotalSize());
	qualifier->getZeroValue(tmpval, &tmpvallen, &literal, bindWA->wHeap());

	// Replace ConstValue NUMERIC "0" (from Parser) with INTERVAL "0 units"
	delete child(0).getPtr();
	child(0) = new (bindWA->wHeap()) SystemLiteral(qualifier,
						    (void *)tmpval,
						    tmpvallen,
						    literal);
      }
    }

    setIsUnaryNegate(FALSE);
  }

  // See the NOTE on side effects of rounding mode on datetime arithmetic
  // in common/OperTypeEnum.h
  // Disable rounding on arithmetic operations added to implement
  // DATE_TRUNC(). Usually these operations are added by Generator while
  // adjusting scales and Generator propagates OrigOpType these operators.
  const OperatorTypeEnum srcOrigOpType = origOpType();
  if (srcOrigOpType >= ITM_DATE_TRUNC_YEAR &&
      srcOrigOpType <= ITM_TSI_WEEK)
    setIgnoreSpecialRounding();

  // bind/type-propagate all children.
  bindChildren(bindWA);
  if (bindWA->errStatus()) 
    return this;

   Int32 childDegree = 0;
   Subquery * subq = NULL;
   UDFunction * udf = NULL;
   Int32 origArity = getArity();
      
   for (Int32 chld=0; chld < origArity; chld++)
   {
     if (child(chld)->getOperatorType() == ITM_USER_DEF_FUNCTION)
     {       
       udf = (UDFunction *) child(chld)->castToItemExpr();
       childDegree += udf->getRoutineDesc()->getOutputColumnList().entries();
     }
     else
       childDegree += 1;
   }
      
   if (childDegree > origArity) 
   {
     NAString upperFunc(getText(), bindWA->wHeap());
     
     upperFunc.toUpper();
     *CmpCommon::diags() << DgSqlCode(-4479) << DgString0(upperFunc) 
                           << DgInt1(origArity) << DgInt2(childDegree);
     
     bindWA->setErrStatus();
     return NULL;
   }

  // If special1 mode is on, then <datetime> +|- <number> and
  // <interval> +|- are allowed.
  //
  // <number> is the interval value equivalent of the least sig field 
  // of <datetime> for datetime computation.
  const NAType *naType0 = &child(0)->getValueId().getType();
  const NAType *naType1 = &child(1)->getValueId().getType();
  if (isDateMathFunction() &&
      ((naType0->getTypeQualifier() == NA_DATETIME_TYPE) &&
       (naType1->getTypeQualifier() != NA_INTERVAL_TYPE) 	))
    {
      *CmpCommon::diags() << DgSqlCode(-4116)
      			  << DgString0("DATE_ADD or DATE_SUB");
      bindWA->setErrStatus();
      return this;
    }

  if ((((naType0->getTypeQualifier() == NA_DATETIME_TYPE) &&
	(naType1->getTypeQualifier() == NA_NUMERIC_TYPE)) ||
       ((naType0->getTypeQualifier() == NA_INTERVAL_TYPE) &&
	(naType1->getTypeQualifier() == NA_NUMERIC_TYPE)) ||
       ((naType0->getTypeQualifier() == NA_NUMERIC_TYPE) &&
	(naType1->getTypeQualifier() == NA_INTERVAL_TYPE)) ) ||
      
      (isDateMathFunction() &&
       (naType0->getTypeQualifier() == NA_DATETIME_TYPE) &&
       (naType1->getTypeQualifier() == NA_INTERVAL_TYPE)) ||
      
      ((CmpCommon::getDefault(ALLOW_INCOMPATIBLE_OPERATIONS) == DF_ON) &&
       (((naType0->getTypeQualifier() == NA_INTERVAL_TYPE) &&
         (naType1->getTypeQualifier() == NA_INTERVAL_TYPE)) ||
        ((naType0->getTypeQualifier() == NA_CHARACTER_TYPE) &&
         (naType1->getTypeQualifier() == NA_NUMERIC_TYPE)) ||
        ((naType0->getTypeQualifier() == NA_NUMERIC_TYPE) &&
         (naType1->getTypeQualifier() == NA_CHARACTER_TYPE)) ||
        ((naType0->getTypeQualifier() == NA_DATETIME_TYPE) &&
         (naType1->getTypeQualifier() == NA_DATETIME_TYPE)))))
    {
      // if datetime +|- numeric, then cast numeric to interval type.
      // Validate that this is being done for
      // the appropriate numeric type(exact with scale of zero).
      if ((naType0->getTypeQualifier() == NA_DATETIME_TYPE) &&
	  (naType1->getTypeQualifier() == NA_NUMERIC_TYPE))
	{
	  const DatetimeType* datetime = (DatetimeType*)naType0;
	  const NumericType*  numeric  = (NumericType*)naType1;
	  if (((getOperatorType() == ITM_PLUS) ||
	       (getOperatorType() == ITM_MINUS)) &&
	      ((numeric->isExact()) &&
	       (NOT numeric->isBigNum()) &&
	       (numeric->getScale() == 0)))
	    {	  
	      Lng32 maxDigits = (numeric->getMagnitude() + 9) / 10;
	      maxDigits = MINOF(maxDigits, 
				SQLInterval::MAX_LEADING_PRECISION);
	      SQLInterval * interval =  
		new(bindWA->wHeap()) SQLInterval(
                     bindWA->wHeap(),
		     naType1->supportsSQLnull(),
		     datetime->getEndField(),
		     maxDigits,
		     datetime->getEndField(),
		     0);
	      
	      ItemExpr * newChild = 
		new(bindWA->wHeap()) Cast(child(1), interval);
	      setChild(1, newChild->bindNode(bindWA));
	      if (bindWA->errStatus())
		return this;
	    }
	}
	// if datetime +|- interval, then cast datetime to timestamp type.

     else if ((naType0->getTypeQualifier() == NA_DATETIME_TYPE) &&
              (naType1->getTypeQualifier() == NA_INTERVAL_TYPE))
	{
	  const DatetimeType* datetime = (DatetimeType*)naType0;
	  const IntervalType*  interval  = (IntervalType*)naType1;
	  if (interval->getEndField() > REC_DATE_DAY)
	    {	  
	   SQLTimestamp * ts = new(bindWA->wHeap()) SQLTimestamp ( bindWA->wHeap(), naType0->supportsSQLnull(),
                               interval->getFractionPrecision() > datetime->getFractionPrecision()
                               ?interval->getFractionPrecision()
                               :datetime->getFractionPrecision());
	   	      
	   ItemExpr * newChild = 
		new(bindWA->wHeap()) Cast(child(0), ts);
	      setChild(0, newChild->bindNode(bindWA));
	      if (bindWA->errStatus())
		return this;
	    }
	}
      else if ((naType0->getTypeQualifier() == NA_INTERVAL_TYPE) &&
	       (naType1->getTypeQualifier() == NA_NUMERIC_TYPE))
	{
	  const IntervalType* interval = (IntervalType*)naType0;
	  const NumericType*  numeric  = (NumericType*)naType1;
	  if ((numeric->isExact()) &&
	      (NOT numeric->isBigNum()) &&
	      (numeric->getScale() == 0) &&
	      (interval->getFractionPrecision() == 0) &&
	      ((getOperatorType() == ITM_PLUS) ||
	       (getOperatorType() == ITM_MINUS)))
	    {	  
	      Lng32 maxDigits = (numeric->getMagnitude() + 9) / 10;
	      maxDigits = MINOF(maxDigits, 
				SQLInterval::MAX_LEADING_PRECISION);
	      SQLInterval * newInterval =  
		new(bindWA->wHeap()) SQLInterval(
                     bindWA->wHeap(),
		     numeric->supportsSQLnull(),
		     interval->getEndField(),
		     maxDigits,
		     interval->getEndField(),
		     0);

	      ItemExpr * newChild = 
		new(bindWA->wHeap()) Cast(child(1), newInterval);
	      setChild(1, newChild->bindNode(bindWA));
	      if (bindWA->errStatus())
		return this;
	    }
	}
      else if ((naType0->getTypeQualifier() == NA_NUMERIC_TYPE) &&
	       (naType1->getTypeQualifier() == NA_INTERVAL_TYPE))
	{
	  if(isDateMathFunction()){
	    // 4035 cannot cast between types.
		*CmpCommon::diags() << DgSqlCode(-4035)
      			  << DgString0("NUMERIC") << DgString1("DATE");
	    bindWA->setErrStatus();
	    return this;
	  }
	  
	  const IntervalType* interval = (IntervalType*)naType1;
	  const NumericType*  numeric  = (NumericType*)naType0;
	  if ((numeric->isExact()) &&
	      (NOT numeric->isBigNum()) &&
	      (numeric->getScale() == 0) &&
	      (interval->getFractionPrecision() == 0) &&
	      ((getOperatorType() == ITM_PLUS) ||
	       (getOperatorType() == ITM_MINUS)))
	    {	  
	      Lng32 maxDigits = (numeric->getMagnitude() + 9) / 10;
	      maxDigits = MINOF(maxDigits, 
				SQLInterval::MAX_LEADING_PRECISION);
	      SQLInterval * newInterval =  
		new(bindWA->wHeap()) SQLInterval(bindWA->wHeap(),
		     numeric->supportsSQLnull(),
		     interval->getEndField(),
		     maxDigits,
		     interval->getEndField(),
		     0);

	      ItemExpr * newChild = 
		new(bindWA->wHeap()) Cast(child(0), newInterval);
	      setChild(0, newChild->bindNode(bindWA));
	      if (bindWA->errStatus())
		return this;
	    }
	}
      else if ((naType0->getTypeQualifier() == NA_INTERVAL_TYPE) &&
	       (naType1->getTypeQualifier() == NA_INTERVAL_TYPE))
	{
	  const IntervalType* interval1 = (IntervalType*)naType0;
	  const IntervalType* interval2 = (IntervalType*)naType1;
	  if ((getOperatorType() == ITM_DIVIDE) &&
	      (interval1->getFractionPrecision() == 0) &&
	      (interval2->getFractionPrecision() == 0))
	    {	  
	      const Int16 DisAmbiguate = 0;
	      ItemExpr * newChild =
		new (bindWA->wHeap())
		Cast(child(0),
		     new (bindWA->wHeap())
		     SQLNumeric(bindWA->wHeap(), TRUE,
				interval1->getTotalPrecision(),
				0,
				DisAmbiguate, // added for 64bit proj.
				child(0)->castToItemExpr()->
				getValueId().getType().supportsSQLnull()));
	      setChild(0, newChild->bindNode(bindWA));
	      if (bindWA->errStatus())
		return this;

	      newChild =
		new (bindWA->wHeap())
		Cast(child(1),
		     new (bindWA->wHeap())
		     SQLNumeric(bindWA->wHeap(), TRUE,
				interval2->getTotalPrecision(),
				0,
				DisAmbiguate, // added for 64bit proj.
				child(1)->castToItemExpr()->
				getValueId().getType().supportsSQLnull()));
	      setChild(1, newChild->bindNode(bindWA));
	      if (bindWA->errStatus())
		return this;
	    }
	}
      else if ((naType0->getTypeQualifier() == NA_DATETIME_TYPE) &&
	       (naType1->getTypeQualifier() == NA_DATETIME_TYPE) &&
               (getOperatorType() == ITM_MINUS))
	{
          // timestamp(0) - date          =  diff in days
          // date - date                  = diff in days
          //
          // In mode_special_4,
          // Column of DATE datatype is internally created as TIMESTAMP(0)
          // and their diff is in days.
          // timestamp(0) - timestamp(0)  = diff in days
	  const DatetimeType* datetime1 = (DatetimeType*)naType0;
	  const DatetimeType* datetime2 = (DatetimeType*)naType1;
          if (((datetime1->getSubtype() == DatetimeType::SUBTYPE_SQLTimestamp) &&
               (datetime2->getSubtype() == DatetimeType::SUBTYPE_SQLDate)) ||
              ((datetime1->getSubtype() == DatetimeType::SUBTYPE_SQLDate) &&
               (datetime2->getSubtype() == DatetimeType::SUBTYPE_SQLDate)) ||
              ((CmpCommon::getDefault(MODE_SPECIAL_4) == DF_ON) &&
               (datetime1->getSubtype() == DatetimeType::SUBTYPE_SQLTimestamp) &&
               (datetime2->getSubtype() == DatetimeType::SUBTYPE_SQLTimestamp) &&
               (datetime1->getFractionPrecision() == 0) &&
               (datetime2->getFractionPrecision() == 0)))
            {
              ItemExpr * newChild = NULL;
              if (datetime1->getSubtype() == DatetimeType::SUBTYPE_SQLTimestamp)
                {
                  newChild = new (bindWA->wHeap())
                    Cast(child(0),
                         new (bindWA->wHeap())
                         SQLDate(bindWA->wHeap(), datetime1->supportsSQLnull()));
                  setChild(0, newChild->bindNode(bindWA));
                  if (bindWA->errStatus())
                    return this;
                }
 
              if (datetime2->getSubtype() == DatetimeType::SUBTYPE_SQLTimestamp)
                {
                  newChild = new (bindWA->wHeap())
                    Cast(child(1),
                         new (bindWA->wHeap())
                         SQLDate(bindWA->wHeap(), datetime2->supportsSQLnull()));
                  setChild(1, newChild->bindNode(bindWA));
                  if (bindWA->errStatus())
                    return this;
                }
	    }
	}
      else
	{
	  Int32 srcChildIndex = -1;
	  Int32 otherChildIndex = -1;
	  if (naType0->getTypeQualifier() == NA_CHARACTER_TYPE)
	    {
	      srcChildIndex = 0;
	      otherChildIndex = 1;
	    }
	  else
	    {
	      srcChildIndex = 1;
	      otherChildIndex = 0;
	    }

	  const NumericType &numeric = (NumericType&)
	    child(otherChildIndex)->getValueId().getType();

	  if ((numeric.isExact()) &&
	      (NOT numeric.isBigNum()) &&
	      (numeric.getScale() == 0))
	    {
	      //doing a char to numeric conversion
	      // convert to largeint.
	      ItemExpr * newChild =
		new (bindWA->wHeap())
		Cast(child(srcChildIndex),
		     new (bindWA->wHeap())
		     SQLLargeInt(bindWA->wHeap(), TRUE,
				 child(srcChildIndex)->castToItemExpr()->
				 getValueId().getType().supportsSQLnull()));
	      setChild(srcChildIndex, newChild->bindNode(bindWA));
	    }
	  else
	    {
	      // convert to double precision. This will handle all precision,
	      // scale and type specified in the char value.
	      ItemExpr * newChild =
		new (bindWA->wHeap())
		Cast(child(srcChildIndex),
		     new (bindWA->wHeap())
		     SQLDoublePrecision(bindWA->wHeap(), child(srcChildIndex)->castToItemExpr()->getValueId().getType().supportsSQLnull()));
	      setChild(srcChildIndex, newChild->bindNode(bindWA));
	    }
	}
    }
  
  // (BiArith is a directly derived subclass of ItemExpr; safe to invoke this)
  result = ItemExpr::bindNode(bindWA);
  if (bindWA->errStatus()) 
    return this;

  NAType * result_type = (NAType *)(&(getValueId().getType()));
  if ((result_type->getTypeQualifier() == NA_NUMERIC_TYPE) &&
      (getRoundingMode()) && 
      (getOperatorType() == ITM_DIVIDE) &&
      (((NumericType*)result_type)->isExact()) &&
      (result_type->getFSDatatype() != REC_BIN64_SIGNED))
    {
      // rounded division are only supported for Int64 datatypes.
      // Make the result to be NUMERIC(MAX_PRECISION, original_result_scale).
      // Save the current result attribute (attr_result).
      // Converted rounded result to the original result datatype.
      
      const Int16 DisAmbiguate = 0;
      NAType * orig_result_type = result_type->newCopy(bindWA->wHeap());
      result_type = new(bindWA->wHeap()) 
	SQLNumeric(bindWA->wHeap(), TRUE, 
		   MAX_NUMERIC_PRECISION,
		   result_type->getScale(),
                   DisAmbiguate,
		   result_type->supportsSQLnull());
      getValueId().changeType(result_type);

      // convert result back to its original type
      result = new(bindWA->wHeap()) Cast(result, orig_result_type);
      result = result->bindNode(bindWA);
      if (bindWA->errStatus()) 
	return this;
    }
  
  return result;

} // BiArith::bindNode()

// -----------------------------------------------------------------------
// member functions for class UnArith
// -----------------------------------------------------------------------

ItemExpr *UnArith::bindNode(BindWA *bindWA)
{
  ItemExpr * result = NULL;

  if (nodeIsBound())
    return getValueId().getItemExpr();

  CMPASSERT(getOperatorType() == ITM_NEGATE);

  child(0) = child(0)->bindNode(bindWA);
  if (bindWA->errStatus()) 
    return this;

  result = ItemExpr::bindNode(bindWA);
  if (bindWA->errStatus()) 
    return this;

  return result;

} // UnArith::bindNode()

// -----------------------------------------------------------------------
// member functions for class Assign
// -----------------------------------------------------------------------
// Helper function
// Soln:10-040915-9806 This function is used to find the mapping between
// the exposed name and the base column name. This was initially introduced
// to find the mapping between the view column name and the base column
// name to report proper names in error messages.
const NAString& findMappedName(ValueId vid,BindWA *bindWA)
{
   ValueIdList colList;
   RETDesc *myRetDesc = bindWA->getCurrentScope()->getRETDesc();
   myRetDesc->getValueIdList(colList);
   for (CollIndex i = 0; i < colList.entries(); i++)
   {
      if(colList[i].getNAColumn() == vid.getNAColumn())
          return myRetDesc->findColumn(colList[i])->getColRefNameObj().getColName();
   }
   return vid.getNAColumn()->getColName();
}

// -----------------------------------------------------------------------
// member functions for class Assign
// -----------------------------------------------------------------------

ItemExpr *Assign::bindNode(BindWA *bindWA)
{
  if (nodeIsBound())
    return getValueId().getItemExpr();

#ifndef NDEBUG
  if (getenv("ASSIGN_DEBUG")) {
    NAString unparsed(bindWA->wHeap());
    unparse(unparsed);
    cout << getValueId() << ":	" << unparsed << endl;
  }
#endif  

  ItemExpr *boundExpr = NULL;
  ItemExpr *boundExpr_0, *boundExpr_1 ;

  boundExpr_0 = child(0)->bindNode(bindWA);
  if (bindWA->errStatus())
      return this;
  child(0) = boundExpr_0;
 
  if (child(1))
    {
      boundExpr_1 = child(1)->bindNode(bindWA);
      if (bindWA->errStatus())
        return this;
      child(1) = boundExpr_1;
    }
 
 
  NABuiltInTypeEnum targetType =  child(0)->castToItemExpr()->getValueId().getType().getTypeQualifier() ;
  if  (targetType == NA_LOB_TYPE)
    {  
      if (child(1))
        {
          NABuiltInTypeEnum sourceType =  child(1)->castToItemExpr()->getValueId().getType().getTypeQualifier() ; 
          //If it's a dynamic param with unknown type or if it is a 
          // character type, trasnform the insert.
          if ((((child(1)->getOperatorType() == ITM_DYN_PARAM) ||(child(1)->getOperatorType() == ITM_ROWSETARRAY_SCAN))  && sourceType == NA_UNKNOWN_TYPE)  || sourceType == NA_CHARACTER_TYPE)
            {
              ValueId vid1 = child(1)->castToItemExpr()->getValueId();  
              // Add a stringToLob node
              ItemExpr *newChild;
              const NAType &desiredType = child(0)->getValueId().getType();
              SQLBlob &lobType = (SQLBlob&)desiredType;
              short fs_datatype = child(0)->castToItemExpr()->getValueId().getType().getFSDatatype();

              NAType * newType = NULL;

              double lob_input_limit_for_batch = CmpCommon::getDefaultNumeric(LOB_INPUT_LIMIT_FOR_BATCH)*1024;
                  double lob_size = lobType.getLobLength();
              if (fs_datatype == REC_CLOB) {
                newType = new (bindWA->wHeap()) SQLClob(bindWA->wHeap(), lob_input_limit_for_batch < lob_size ? lob_input_limit_for_batch : lob_size,
                         lobType.getLobStorage(),
                         TRUE, FALSE, FALSE,
                         lob_input_limit_for_batch < lob_size ? lob_input_limit_for_batch : lob_size);
              }
              else {
                newType = new (bindWA->wHeap()) SQLBlob(bindWA->wHeap(),lob_input_limit_for_batch < lob_size ? lob_input_limit_for_batch : lob_size ,
                                             lobType.getLobStorage(), 
                                             TRUE, FALSE, FALSE, 
                                             lob_input_limit_for_batch < lob_size ? lob_input_limit_for_batch : lob_size);
              }
             
              CMPASSERT(lob_input_limit_for_batch < INT_MAX);
              vid1.coerceType(*newType, NA_LOB_TYPE); 
              if (bindWA->getCurrentScope()->context()->inUpdate())
                {
                  newChild =  new (bindWA->wHeap()) LOBupdate( vid1.getItemExpr(), child(0), NULL,LOBoper::STRING_, FALSE,TRUE);
                }
              else
                {
                  newChild =  new (bindWA->wHeap()) LOBinsert( vid1.getItemExpr(),NULL, LOBoper::STRING_, FALSE,TRUE); 
                }   
              newChild->bindNode(bindWA);
              if (bindWA->errStatus())
                return boundExpr; 
              setChild(1, newChild);
            }
        }
    }
  // Assign is a directly derived subclass of ItemExpr; safe to invoke this
  boundExpr = ItemExpr::bindNode(bindWA);
  if (bindWA->errStatus())
      return boundExpr;
	    

  //
  if (isUserSpecified()) {
    //
    // Ensure the target is a column;
    // and that it is a user column (4013).
    //
    const NAColumn *nacolTgt = child(0).getNAColumn();
    if (nacolTgt->isSystemColumn()) {
      *CmpCommon::diags() << DgSqlCode(-4013)
      			  << DgColumnName(nacolTgt->getColName());
      bindWA->setErrStatus();
      return boundExpr;
    }
    //
    // ## For first release,
    // ## ensure it is not a clustering column being updated (4033)
    // ## (when we do allow it we of course must ensure, just as insert does,
    // ## that the resulting row does not violate PK uniqueness constraint).
    //
    if (bindWA->getCurrentScope()->context()->inUpdate())
      if (nacolTgt->isClusteringKey() ||
	  nacolTgt->isPrimaryKey()) 
      {
	if (CmpCommon::getDefault(UPDATE_CLUSTERING_OR_UNIQUE_INDEX_KEY) == DF_OFF)
	{
	  *CmpCommon::diags() << DgSqlCode(-4033)
	      		<< DgColumnName(findMappedName(child(0).getValueId(),bindWA));
	  bindWA->setErrStatus();
	  return boundExpr;
	}
      }

    //
    // If target requires upshifting, and source is not already upshifted,
    // then interpose a new upshift-function node and bind it.
    // This need not be done if not user-specified, i.e. if default value,
    // for CatMan should be storing upshift columns' default values already
    // upshifted.
    //
    if (nacolTgt->isUpshiftReqd()) {
      boundExpr = applyUpperToSource(bindWA, boundExpr, 1);
      if (bindWA->errStatus()) return boundExpr;
    }

    // QSTUFF
    // For ON ROLLBACK assignment statements we need to ensure that the
    // respective column is not a clustering key or index column and that
    // the respective column size is of fixed size since we can't
    // handle variable length columns during abort.
    if (onRollback()) {

      NAString str0(bindWA->wHeap());
      if      (nacolTgt->isIndexKey())        str0 = "Index Key";
      else if (nacolTgt->isPrimaryKey())      str0 = "Primary Key";
      else if (nacolTgt->isClusteringKey())   str0 = "Clustering Key";
      else if (nacolTgt->isPartitioningKey()) str0 = "Partitioning Key";
      // if (nacolTgt->isReferencedForHistogram())	str0 = "Histogram Reference";

      if (!str0.isNull()) {
        *CmpCommon::diags() << DgSqlCode(-4177)
          << DgString0(str0)
	  << DgColumnName(nacolTgt->getColName());
        bindWA->setErrStatus();
        return boundExpr;
      }

      if (DFS2REC::isAnyVarChar(nacolTgt->getType()->getFSDatatype())) {
        *CmpCommon::diags() << DgSqlCode(-4178)
          << DgColumnName(nacolTgt->getColName());
        bindWA->setErrStatus();
        return boundExpr;
      }
      // test for not null on rollback
      if (nacolTgt->getType()->supportsSQLnullLogical()) {
        *CmpCommon::diags() << DgSqlCode(-4209)
          << DgColumnName(nacolTgt->getColName());
        bindWA->setErrStatus();
        return boundExpr;
      }
    } // QSTUFF

  } // isUserSpecified
 
 targetType =  child(0)->castToItemExpr()->getValueId().getType().getTypeQualifier() ;
 
  if ((NOT child(0)->getValueId().getType().
       isCompatible(child(1)->getValueId().getType())) &&
      (CmpCommon::getDefault(ALLOW_INCOMPATIBLE_OPERATIONS) == DF_ON) &&
      ((child(1)->getOperatorType() != ITM_CONSTANT) ||
       (NOT ((ConstValue *) child(1).getPtr() )->isNull())))
    {
      // target type is not the same as source type.
      // Add an explicit CAST node.
      // All supported incompatible conversions will be handled by CAST.
      ItemExpr * newChild = 
	new(bindWA->wHeap()) Cast(child(1),
				  &child(0)->getValueId().getType());
      newChild->bindNode(bindWA);
      if (bindWA->errStatus())
	return boundExpr;
      setChild(1, newChild);
    }
    
 
  // If we assign a numeric type and the source has a larger scale then
  // the target we cast the source to reduce the scale (truncate).
  // We also cast (truncate) if we deal with char and the source is larger
  // than the target.
  targetType =  child(0)->castToItemExpr()->getValueId().getType().getTypeQualifier() ;
  if (targetType == NA_CHARACTER_TYPE) {
    Lng32 sourceLength = ((CharType&)(child(1)->getValueId().getType())).getStrCharLimit();
    Lng32 targetLength = ((CharType&)(child(0)->getValueId().getType())).getStrCharLimit();
    Lng32 sourceLength_bytes = ((CharType&)(child(1)->getValueId().getType())).getNominalSize();
    Lng32 targetLength_bytes = ((CharType&)(child(0)->getValueId().getType())).getNominalSize();
    if ( (targetLength < sourceLength) || (targetLength_bytes < sourceLength_bytes) ){
      ItemExpr *newChild;
      
      // if the targetLength is smaller than sourceLength, and since the
      // target type is of character type, make sure to set the
      // checkTruncationError flag in the cast node if this is an insert
      // or an update command. If MODE_SPECIAL_1 is on, then turn off the
      // checkTruncationError flag. Also, turn off string truncation warnings
      // in this case.
      
      OperatorTypeEnum opType = bindWA->getCurrentScope()->context()
	->inUpdateOrInsert();
      if ((opType == REL_UPDATE) || (opType == REL_INSERT))
	{
	  NABoolean specialMode = 
	    (CmpCommon::getDefault(MODE_SPECIAL_1) == DF_ON);

          NABoolean checkForTrunc = TRUE;
          NABoolean noStringTruncWarn = FALSE;
          if (specialMode)
            {
              checkForTrunc = FALSE;
              noStringTruncWarn = TRUE;
            }
          else
            {
              if (CmpCommon::getDefault(TRAF_STRING_AUTO_TRUNCATE) == DF_ON)
                {
                  checkForTrunc = FALSE;
                  noStringTruncWarn = TRUE;
                  if (CmpCommon::getDefault(TRAF_STRING_AUTO_TRUNCATE_WARNING) == DF_ON)
                    noStringTruncWarn = FALSE;
                }
            }

	  newChild = new(bindWA->wHeap()) Cast(child(1),
					       &child(0)->getValueId().getType(),
					       ITM_CAST,
                                               checkForTrunc,
                                               noStringTruncWarn);
	}
      else
	newChild = new (bindWA->wHeap()) Cast(child(1),
					      &child(0)->getValueId().getType());
      setChild(1, newChild->bindNode(bindWA));
      if (bindWA->errStatus())
	return boundExpr;
    }
  }
  else if (targetType == NA_NUMERIC_TYPE) {
    NumericType *source = (NumericType*) &child(1)->getValueId().getType();
    NumericType *target = (NumericType*) &child(0)->getValueId().getType();
    if (target->getScale() < source->getScale()) {
      ItemExpr * newChild = new(bindWA->wHeap()) Cast(child(1),
						      &child(0)->getValueId().getType());
      setChild(1, newChild->bindNode(bindWA));
      if (bindWA->errStatus())
	return boundExpr;
    }
  }
  else if (targetType == NA_DATETIME_TYPE) {
    DatetimeIntervalCommonType *source =
      (DatetimeIntervalCommonType*) &child(1)->getValueId().getType();
    DatetimeIntervalCommonType *target =
      (DatetimeIntervalCommonType*) &child(0)->getValueId().getType();
    if (target->getFractionPrecision() < source->getFractionPrecision()) {
      ItemExpr * newChild = new(bindWA->wHeap()) Cast(child(1),
						      &child(0)->getValueId().getType());
      setChild(1, newChild->bindNode(bindWA));
      if (bindWA->errStatus())
	return boundExpr;
    }
  }
  
  if (!child(0)->getValueId().getType().supportsSQLnull() &&
      child(1)->getOperatorType() == ITM_CONSTANT &&
      ( (ConstValue *) child(1).getPtr() )->isNull())
    {
      // - Triggers
      // Check if this table has before triggers on it.
      // If so - don't create the error. Maybe a before trigger will fix this
      // NULL value for us. If not - the error will be caught in execution.
      // Don't check on the temp table, so the error will not be on the wrong table.
      const NAColumn *nacol = child(0)->getValueId().getNAColumn(TRUE/*no err*/);
      if (nacol != NULL)
      {
        if (nacol->getNATable()->getSpecialType() !=
                    ExtendedQualName::TRIGTEMP_TABLE)
	{
	  QualifiedName table(*nacol->getTableName(), bindWA->wHeap());
          if ( nacol->getNATable()->getSpecialType() ==
                                      ExtendedQualName::GHOST_TABLE)
              table.setIsGhost(TRUE);
	  ComOperation op = COM_UNKNOWN_IUD;
	  switch (bindWA->getCurrentScope()->context()->inUpdateOrInsert())
	    {
	    case REL_INSERT: op = COM_INSERT;
	      break;
	    case REL_UPDATE: op = COM_UPDATE;
	      break;
	    default        : CMPASSERT(FALSE);
	    }
	  BeforeAndAfterTriggers *allTriggers =
	    bindWA->getSchemaDB()->getTriggerDB()->getTriggers(table, op, bindWA);
	  if (bindWA->errStatus())
	    return boundExpr;
	  if ((allTriggers==NULL) || (allTriggers->getBeforeTriggers()==NULL))
	    {
	      // No before triggers found. Go ahead with the error.
	      // 4122 NULL cannot be assigned to NOT NULL column $column.
	      NAString colname(nacol->getFullColRefNameAsAnsiString());
		  *CmpCommon::diags() << DgSqlCode(-4122) << DgColumnName(colname);
	      bindWA->setErrStatus();
	    }
	}
      }
      else
      {
	  NAString colname("");
	  *CmpCommon::diags() << DgSqlCode(-4122) << DgColumnName(colname);
	  bindWA->setErrStatus();
      }
    }

  return boundExpr;
} // Assign::bindNode()



// -----------------------------------------------------------------------
// member functions for class Cast
// -----------------------------------------------------------------------

ItemExpr *Cast::bindNode(BindWA *bindWA)
{
  if (nodeIsBound())
    return getValueId().getItemExpr();

  // Cast inherits from BuiltinFunction .. Function .. ItemExpr.
  ItemExpr *boundExpr = BuiltinFunction::bindNode(bindWA);
  if (bindWA->errStatus())
    return boundExpr;

  if (getType()->getTypeQualifier() == NA_CHARACTER_TYPE &&
      ((CharType *)getType())->isUpshifted())
    boundExpr = applyUpperToSource(bindWA, boundExpr, 0);

// COMMENTED OUT -- causing problems in Generator key-building --	     ##
// FIX LATER -- for now, just catch this problem at run-time instead of compile,
// via Executor error 8421 ...
//
//  if (!getType()->supportsSQLnull() &&
//      child(0)->getOperatorType() == ITM_CONSTANT &&
//      ( (ConstValue *) child(0).getPtr() )->isNull()) {
//    // 4123 NULL cannot be cast to a NOT NULL datatype.
//    *CmpCommon::diags() << DgSqlCode(-4123);
//    bindWA->setErrStatus();
//  }

  // in mode_special_1, if a character datatype is being converted
  // to a numeric type, then treat an empty string or a string with all spaces
  // to be the same as the value 0.
  if ((CmpCommon::getDefault(MODE_SPECIAL_1) == DF_ON) &&
      (child(0)->castToItemExpr()->getValueId().getType().getTypeQualifier() == NA_CHARACTER_TYPE) &&
      (getType()->getTypeQualifier() == NA_NUMERIC_TYPE))
    {
      setTreatAllSpacesAsZero(TRUE);
    }

  return boundExpr;
} // Cast::bindNode()

// -----------------------------------------------------------------------
// member functions for class Like
// -----------------------------------------------------------------------

ItemExpr *PatternMatchingFunction::bindNode(BindWA *bindWA)
{
  if (nodeIsBound())
    return getValueId().getItemExpr();

  NABoolean savedInPred = bindWA->getCurrentScope()->context()->inPredicate();
  bindWA->getCurrentScope()->context()->inPredicate() = TRUE;

  // this will bind/type-propagate all children.
  bindChildren(bindWA);
  if (bindWA->errStatus()) 
    return this;

  //=================================================================
  //10-040212-3209-begin
  // Like inherits from Function .. ItemExpr.
  //10-040212-3209-end

  // case 10-020314-7397
  // BuiltInFunction::bindNode() seems to add a cast node on top of
  // all base columns and this results in a full table scan
  // for queries like
  // select * from t where a like 'abc%';
  // hence like will inherit from Function not BuiltInFunction
  //==================================================================
  ItemExpr *boundExpr = Function::bindNode(bindWA);
  if (bindWA->errStatus()) 
    return this;

  // update both operands if case insensitive comparions
  // are to be done.
  const NAType &type1 = 
    child(0)->castToItemExpr()->getValueId().getType();
  const NAType &type2 = 
    child(1)->castToItemExpr()->getValueId().getType();
  
  if ((type1.getTypeQualifier() == NA_CHARACTER_TYPE) &&
      (type2.getTypeQualifier() == NA_CHARACTER_TYPE))
    {
      const CharType &cType1 = (CharType&)type1;
      const CharType &cType2 = (CharType&)type2;
      
      NABoolean doCIcomp = 
      	((cType1.isCaseinsensitive()) && (cType2.isCaseinsensitive()));
      ItemExpr * newChild = NULL;
      if (doCIcomp) 
        {
          if (NOT cType1.isUpshifted())
            {
              newChild = new (bindWA->wHeap()) Upper(child(0));
              newChild->bindNode(bindWA);
              setChild(0, newChild);
            }
          if (NOT cType2.isUpshifted())
            {
              newChild = new (bindWA->wHeap()) Upper(child(1));
              newChild->bindNode(bindWA);
              setChild(1, newChild);
            }
          // for CaseInSensitive escape character, Soln 10-080310-1225
          if (getArity()>2)  
            {
              const NAType &type3 = 
                child(2)->castToItemExpr()->getValueId().getType();
              if (type3.getTypeQualifier() == NA_CHARACTER_TYPE)
              {
                const CharType &cType3 = (CharType&)type3;
                if (NOT cType3.isUpshifted())
                  {
                    newChild = new (bindWA->wHeap()) Upper(child(2));
                    newChild->bindNode(bindWA);
                    setChild(2, newChild);
                  }
              }
            }  
        }
 
    }

  bindWA->getCurrentScope()->context()->inPredicate() = savedInPred;

  return applyBeginEndKeys(bindWA, boundExpr, bindWA->wHeap());

} // PatternMatchingFunction::bindNode()

NABoolean PatternMatchingFunction::beginEndKeysApplied(CollHeap *heap)
{
  // Called by optimizer, long after binding (thus bindNode has already
  // called the common method applyBeginEndKeys and done the appropriate
  // node allocations there).  Calling applyBeginEndKeys again in optimizer
  // rather than setting a flag in the Like object was chosen so we don't
  // have to analyze the survivability of a new flag across optimizer's
  // copyTopNode and rules assigning object members here and there.

  return beginEndKeysApplied_;

} // PatternMatchingFunction::beginEndKeysApplied()

ItemExpr *Regexp::applyBeginEndKeys(BindWA *bindWA, ItemExpr *boundExpr,
				  CollHeap *heap)
{
  return boundExpr;
}

ItemExpr *Like::applyBeginEndKeys(BindWA *bindWA, ItemExpr *boundExpr,
				  CollHeap *heap)
{
  CMPASSERT((bindWA && boundExpr) || (!bindWA && !boundExpr));
  CMPASSERT(heap);

  // Assert that Like::bindNode, and importantly, Like::synthesizeType,
  // has been called -- the latter ensures all LIKE arguments are of
  // compatible/coercible character string type.
  CMPASSERT(nodeIsBound());

  // Now we want to optimize the common case where the pattern is a literal
  // and so is the optional escape character, if one.
  // Note that we don't care about the match value (first argument) here.
  // Help the optimizer by ANDing another predicate above this node,
  // letting the optimizer estimate selectivity and avoid a full table scan.
  //	mv LIKE 'ab%yz'  ->  mv >= 'ab{0}' AND mv LIKE 'ab%yz' AND mv < 'ac{0}'
  //	mv LIKE 'ab_yz'  ->  mv >= 'ab{0}' AND mv LIKE 'ab_yz' AND mv < 'ac{0}'
  // where {0} is a sequence of enough ascii-zero characters to fill the
  // literal comparand out to the same length as mv.
  //
  // Further, LIKE processing can be optimized away entirely:
  //   	mv LIKE 'ab%'    ->  mv >= 'ab{0}' AND mv < 'ac{0}'
  //    ('ab%', 'ab%%', 'ab%%%' -- all can have the LIKE optimized away.)
  // Note that 'ab_' CANNOT have the LIKE optimized away.
  //
  // mv LIKE 'ab'	->  mv = 'ab' [if mv is CHAR type]
  // mv LIKE '%'	->  if mv is nullable return IS_NOT_NULL else return TRUE
  //
  // We do not optimize case like:
  //	mv LIKE 'ab'	if mv is of VARCHAR type
  //
  // The following begin with wildcards; no optimization is possible:
  //	mv LIKE '%yz' , mv LIKE '_yz' , mv LIKE '_'	-- no change
  //
  // Some of this code copied from ex_like_clause::eval().

  ItemExpr *matchExpr = child(0)->castToItemExpr();		// arity 1
  ItemExpr *strExpr = child(1)->castToItemExpr();		// arity 2

  const ConstValue *patternNode, *escapeNode = NULL;

  NABoolean specialMode = (CmpCommon::getDefault(MODE_SPECIAL_1) == DF_ON);

  if (specialMode)
  {
    if(strExpr->getOperatorType() == ITM_UPPER)
      strExpr = strExpr->child(0);
  }

  patternNode = (ConstValue *)strExpr->castToItemExpr();	// arity 2
  NABoolean optimizeLike =
    patternNode->getOperatorType() == ITM_CONSTANT && !patternNode->isNull();
  if (getArity() > 2)
  {
    ItemExpr *escapeExpr = child(2)->castToItemExpr();
    if (specialMode)
    {
      if(escapeExpr->getOperatorType() == ITM_UPPER)
	escapeExpr = escapeExpr->child(0);
    }
    escapeNode = (ConstValue *)escapeExpr->castToItemExpr();	// arity 3
    optimizeLike = optimizeLike &&
      escapeNode->getOperatorType() == ITM_CONSTANT && !escapeNode->isNull();
  }

  // The following comment is added based on the inspection discussion for fix
  // for 10-040127-4126 (NF: LIKE with ESCAPE kanji char '_' gets assertion failure ).
  //
  // optimizerLike = true means both the pattern and the escape clause contain constants
  // are not NULL. It is possible that this optimization step is bypassed when either
  // clause contains a non-constant expression with all components are constants. After
  // constant-folding, the expression evaluates to a constant value and the optimization
  // step can be performed, if this function is called (occasionally from the Analyzer
  // or the Optimizer). If this function is not called, then some error, if any, will be
  // caught during run-time.
  //
  //
  // On the other hand, the cost of calling binder after const-folding, the infrequent
  // use of such constant expressions in real-world queries, and the error will get
  // caught during run-time, this defect can be considered as a "limitation or regret"
  // of the current architecture. It is a defect nice-to-be-fixed but the overhead of
  // fixing it and its consequence can be very  big  for us to bear.
  //
  if (optimizeLike)
  {
    // Seems like a weird way to cast, but only way to do in on NT C++
    const CharType *matchCharType = (const CharType *)
				    &matchExpr->getValueId().getType();
    // Already ensured by Like::synthesizeType, but what the heck...

    CMPASSERT(matchCharType->getTypeQualifier() == NA_CHARACTER_TYPE);

    // 2/15/98: remove the following assertion.
    //CMPASSERT(matchCharType->getBytesPerChar() == 1);

    const char *escapeChar = NULL;
    Int32 escapeChar_len = 0;
    if (escapeNode)
    {
      CharInfo::CharSet cs = matchCharType->getCharSet();
      escapeChar_len = escapeNode->getRawText()->length();
      escapeChar = escapeNode->getRawText()->data();

      if      (  CharInfo::isSingleByteCharSet(cs) && escapeChar_len == 1) /*ok*/;
      else if (! CharInfo::isSingleByteCharSet(cs) && escapeChar_len == 2) /*ok*/;
      else
      {
	*CmpCommon::diags() << DgSqlCode(EXE_INVALID_ESCAPE_CHARACTER,
					 DgSqlCode::ERROR_);
	if (bindWA)
	  bindWA->setErrStatus();
	return boundExpr;
      }
    } // if (escapeNode)

    //
    // We currently cannot optimize if CZECH collation is involved
    // because the Optimizer doesn't understand various things about
    // CZECH collation ... such as H < CH < I.
    //
    // Since all arguments to LIKE must have the same collation (or
    // they would not be comparable), we need to check only one
    // of the arguments.
    //
    CharInfo::Collation Coll = matchCharType->getCollation();
    if ( Coll == CharInfo::CZECH_COLLATION )
    {
      return boundExpr; // Cannot optimize
    }

  // 2/15/98: prepare the right version of underscore,
  // percent any bytesPerChar info.

   const char* underscoreChar;
   UInt16 underscoreChar_len = BYTES_PER_NAWCHAR;
   NAWchar wideUnderscoreChar;
   switch (matchCharType->getCharSet())
   {
     case CharInfo::UNICODE:
       underscoreChar = (char*)L"_";
       break;

     case CharInfo::KANJI_MP:
       wideUnderscoreChar = kanji_char_set::underscore_char();
       underscoreChar = (char*)&wideUnderscoreChar;
       break;

     case CharInfo::KSC5601_MP:
       wideUnderscoreChar = ksc5601_char_set::underscore_char();
       underscoreChar = (char*)&wideUnderscoreChar;
       break;

     case CharInfo::ISO88591:
     default:
       underscoreChar = (char*)"_";
       underscoreChar_len = 1;
       break;
   }

   const char* percentChar;
   UInt16 percentChar_len = BYTES_PER_NAWCHAR;
   NAWchar widePercentChar;
   switch (matchCharType->getCharSet())
   {
     case CharInfo::UNICODE:
       percentChar = (char*)L"%";
       break;

     case CharInfo::KANJI_MP:
       widePercentChar = kanji_char_set::percent_char();
       percentChar = (char*)&widePercentChar;
       break;

     case CharInfo::KSC5601_MP:
       widePercentChar = ksc5601_char_set::percent_char();
       percentChar = (char*)&widePercentChar;
       break;

     case CharInfo::ISO88591:
     default:
       percentChar = (char*)"%";
       percentChar_len = 1;
       break;
   }

   const char* pattern_str = 0;
   Int32 pattern_str_len = 0;

   pattern_str = patternNode->getRawText() -> data();
   pattern_str_len = patternNode->getRawText()->length();

    CharInfo::CharSet cs = matchCharType->getCharSet();


    LikePatternString patternString( pattern_str,
				     pattern_str_len, cs,
				     escapeChar, escapeChar_len,
				     underscoreChar, underscoreChar_len,
				     percentChar, percentChar_len
				   );

    LikePattern pattern(patternString, heap, cs);

    if (pattern.error())
    {
      if(pattern.error() == EXE_INVALID_CHARACTER)
      {
        *CmpCommon::diags() << DgSqlCode(pattern.error(), DgSqlCode::ERROR_)
          << DgString0(CharInfo::getCharSetName(cs))
          << DgString1("LIKE PATTERN"); 
      }
      else
        *CmpCommon::diags() << DgSqlCode(pattern.error(), DgSqlCode::ERROR_);

      // fix for 10-040127-4126.
      // Like::beginEndKeysApplied(CollHeap *heap) actually supplies
      // a NULL bindWA and NULL boundExpr when calling this method during the ANALYSIS
      // phase. Need to check the nullness of bindWA before call its members.
      if (bindWA)
        bindWA->setErrStatus();
      return boundExpr;
    }

    if (bindWA)
    {
      // we are here from the Binder and not from the Optimizer
      // so calculate the total number of non_wildcard characters
      // including underscores and set them in the Like expression.
      // This will be used later in the Optimizer to estimate the
      // selectivity
      setNumberOfNonWildcardChars(patternString);

      // do all equality and '%' transformations, only if the call is from
      // the Binder.

      // We first check if the predicate like '%' is being applied to a
      // not_nullable column. If the column does not allow NULLS, then
      // the like % is transformed to '*' or TRUE. Similarly predicates such 
      // as col LIKE '____'(N underscores) for not nullable columns of length 
      // N are converted to TRUE.
      // For nullable columns, the LIKE predicate is transformed to IS_NOT_NULL.

      Int32 BytesInNonWildCardChars = getBytesInNonWildcardChars();
      if (BytesInNonWildCardChars == 0)
      {
	if (( pattern.getNextHeader() &&
	    !pattern.getNextHeader()->getNextHeader() &&
	    (pattern.getNextHeader()->getType() == LikePatternStringIterator:: PERCENT) &&
            ((pattern.getType() != LikePatternStringIterator:: UNDERSCORE) ||  // like '%'
              (matchCharType->getNominalSize() >= pattern.getLength()) &&
              (!matchCharType->isVaryingLen())))  // like '___%', but not like '___%_'  col len >= # of underscores
	    ||
	    (!pattern.getNextHeader() &&
	    (pattern.getType() == LikePatternStringIterator:: UNDERSCORE) &&
            (!matchCharType->isVaryingLen()) &&
            (!CharInfo::isVariableWidthMultiByteCharSet(cs)) &&
            // like '___', column must be same length as pattern
	    (matchCharType->getStrCharLimit() == pattern.getLength())))
	{
	  ItemExpr * result = NULL;
	  if (!(matchExpr->getValueId().getType().supportsSQLnullLogical()) )
	    result = new (heap) BoolVal(ITM_RETURN_TRUE);
	  else
	  {
           //10-061019-9936 -Begin
           // For nullable columns, the LIKE predicate is transformed as shown
           // in case statement below.

           Parser parser(bindWA->currentCmpContext());
           ItemExpr * itmtrue = NULL, *itmnull = NULL;
           char buf[200];
           buf[0] = 0;
           itmnull = new(heap) BoolVal(ITM_RETURN_NULL);
           itmtrue = new(heap) BoolVal(ITM_RETURN_TRUE);
           strcpy(buf, "CASE WHEN @A1 is not null then @A2 ELSE @A3 END;");

           result = parser.getItemExprTree(buf,strlen(buf), BINDITEMEXPR_STMTCHARSET, 3, matchExpr, itmtrue,itmnull);

           //10-061019-9936 -End
	 }
	  boundExpr = result;

	  // Now bind the newly created expression, and return
	  boundExpr = boundExpr->bindNode(bindWA);
	  return boundExpr;
	}
      } // if (BytesInNonWildCardChars == 0)

      // Then check for cases - col like 'ab'. These will be converted to
      // equality predicates.

      // If it is a CHAR type and pattern_str_len contains the total number
      // of characters in the like pattern
      // Get number of non-wild-characters in the string. If they are equal, then
      // that implies there are no wild card characters.
      // Then transform the like predicate as follows:
      // Col LIKE 'ab' can be transformed to FALSE if Col is not nullable,
      // and (Col a CHAR(n) with n <> 2, or if Col is a VARCHAR(n) with n < 2)
      // if col is a CHAR type then it is transormed to an equality predicate

      if (pattern_str_len == BytesInNonWildCardChars)
      {
	// set a flag in the expression to indicate that the pattern is a
	// string literal (col LIKE 'ab'). This will be used later to set
	// the selectivity of LIKE predicate, if for some reason the LIKE
	// predicate could not be transformed.
	setPatternAStringLiteral();

	// take care of all cases if the column is VARCHAR type
	if (matchCharType->getTypeName() == "VARCHAR")
	{
	  if ( ( !matchCharType->supportsSQLnullLogical()  ) &&
	       (matchCharType->getNominalSize() < BytesInNonWildCardChars ) )
	  {
	    // if the col is VARCHAR type and the length of the col is
	    // less than the length of the pattern, return FALSE
	    ItemExpr * result = new (heap) BoolVal(ITM_RETURN_FALSE);
	    boundExpr = result;

	    // Now bind the newly created equality expression, and return
	    boundExpr = boundExpr->bindNode(bindWA);
	    return boundExpr;
	  }
	  else
	  {
	    // length of the column is equal to or greater than the  length
	    // of the pattern. Ideally we should have been able to convert the
	    // LIKE predicate to an equality predicate of exact length, but
	    // because of a bug in equality predicates on VARCHAR columns, we
	    // will set the default selectivity equal to 1/UEC. The bug is
	    // followed by Sol: 10-050412-6599. Once this problem is fixed
	    // the LIKE predicate should be transformed to
	    // col LIKE 'ab' -> col = 'ab' and char_length(col) = 2
	    // As of now we shall not do anything right now, and take care
	    // of it later while estimating cardinality.

	    return boundExpr;
	  }
	} // col LIKE 'ab' on a VARCHAR column
	else
	{
	  if ( !matchCharType->supportsSQLnullLogical()  &&
	       (matchCharType->getNominalSize() != BytesInNonWildCardChars ) )
	  {
	    // col is not nullable, is CHAR type but the length of the col
	    // is not same as the LIKE pattern length. Hence return FALSE
	    ItemExpr * result = new (heap) BoolVal(ITM_RETURN_FALSE);
	    boundExpr = result;

	    // Now bind the newly created equality expression, and return
	    boundExpr = boundExpr->bindNode(bindWA);
	    return boundExpr;

	  }
	  else
	  {
	    if (matchCharType->getNominalSize() == BytesInNonWildCardChars )
	    {
	      // col is the same length as the pattern, so transform the
	      // predicate into an equality predicate
	      // Left child of the expression would be matchExpr, which is the left
	      // child of Like pred, which is the column
	      // Right child of the equality expression will be the Like pattern
	      // which is a literal. Type of the literl is same as the type of
	      // the column it is being equated to.

	      ItemExpr * child1 = new (heap) SystemLiteral(
					     NAString(pattern_str, pattern_str_len),
					     matchCharType->getCharSet(),
					     matchCharType->getCollation(),
					     matchCharType->getCoercibility()
								);
	      if ((specialMode) && (matchCharType->isCaseinsensitive()))
		child1 = new (bindWA->wHeap()) Upper(child1);

	      BiRelat *eqExpr =
			new (heap) BiRelat(ITM_EQUAL,
					     matchExpr,
					     child1,
					     FALSE,	  // specialNulls flag
					     FALSE
					  );

	      eqExpr->setOriginalLikeExprId(getValueId() );

	      boundExpr = eqExpr;

	      // Now bind the newly created equality expression, and return
	      boundExpr = boundExpr->bindNode(bindWA);

	      return boundExpr;
	    } // matchCharType->getNominalSize() == BytesInNonWildCardChars
	  } // length of col <> pattern length, and col is NULLable
	} // col is CHAR (dataType.getTypeName() <> "VARCHAR")

	// for all other cases, return without any transformation. Apply default
	// selectivity later.
	return boundExpr;

      } // if (pattern_str_len == BytesInNonWildCardChars)
    } // end of all the transformations for special cases

    if (pattern.getType() == LikePatternStringIterator::NON_WILDCARD &&
	pattern.getClauseLength() > 0)
    {
      // If called by beginEndKeysApplied, return non-NULL pointer,
      // so beginEndKeysApplied() will return TRUE.
      if (!bindWA) return this;

      // Test if pattern ends with percent and has no underscores --
      // 'ab%', 'ab%%', 'ab%%%', ..., but not
      // 'ab', 'ab_', 'ab%yz', 'ab%_', 'ab%_yz', ... --
      // If so then we can optimize the LIKE away entirely.
      //
      if (pattern.getLength() == pattern.getClauseLength() &&
	  pattern.getNextHeader() &&
	  pattern.getNextHeader()->getType() == LikePatternStringIterator::
	  					PERCENT &&
	  !pattern.getNextHeader()->getNextHeader())
      {
	    CMPASSERT(!pattern.getNextClause() &&
		      !pattern.getNextHeader()->getNextClause());
	    CMPASSERT(pattern.getNextHeader()->getLength() ==
		      pattern.getNextHeader()->getClauseLength());
	// boundExpr==this, so do not delete it!
	boundExpr = NULL;
      }

      // Get the prefix, e.g. "ab", and the minimal key value, e.g. '\0'
      NAString prefix(pattern.getPattern(),
		      pattern.getClauseLength(),
		      heap);
      Lng32 zeroChar = matchCharType->getMinSingleCharacterValue();

      // Get the maximum length of the comparands.
      // Note that there's another silly case we don't bother optimizing
      // but just allow here (the if-test, after which we widen matchLen):
      //   m < p  (where m = mv length, p = pattern non-wild prefix length)
      // could be optimized to
      //   if mv is null return NULL else return FALSE
      //

      // matchLen must be number of BYTES, not SQL CHAR's
      size_t matchLen = matchCharType->getNominalSize();

      if (matchLen < prefix.length()) matchLen = prefix.length();

      // Zero-pad into prefixZ, e.g. for mv type VARCHAR(4), make "ab\0\0"
      char *prefixZ = new (heap) char[matchLen];
      byte_str_cpy(prefixZ, matchLen, prefix.data(), prefix.length(),
		   (char)zeroChar);

      ItemExpr *child1 = new (heap) SystemLiteral(
			      NAString(prefixZ, matchLen),
			      matchCharType->getCharSet(),
			      matchCharType->getCollation(),
			      matchCharType->getCoercibility()
						);
      if ((specialMode) && (matchCharType->isCaseinsensitive()))
	child1 = new (bindWA->wHeap()) Upper(child1);

      ItemExpr *beginKey =
		new (heap) BiRelat(ITM_GREATER_EQ, matchExpr,
				     child1,
				     FALSE,	  // specialNulls flag
				     FALSE // derivative from Like
				  );
      ((BiRelat*)beginKey)->setAddedForLikePred(TRUE);

      // Now set the selectivity that should be applied for this
      // predicate.

      // Selectivity from like would depend on the number of non_wildcard
      // characters in the Like string.
      // Selectivities are computed as follows:
      // ab% -> >= ab and < c. The two range predicates are applied the usual way
      // but the final selectivity is based on the default selectivity of like
      // predicates adjusted based on the number of non-wildcard characters. This
      // selectivity is applied to the first range predicate. Selectivity of
      // the second range predicate is set to 1.
      // a%b -> >= a and < b and like %b. The selectivities in this case are
      // computed and applied similar to the previous case. This implies, that
      // we shall compute the selectivity based on the number of non-wildcard
      // characters. Apply that to the first range predicate and would use
      // selectivity equal to 1 for the two remaining predicates (> b and like %b)

      double selectivity = computeSelForNonWildcardChars();

      // If user had specified selectivity for original LIKE predicate via selectivity
      // hint, then store that as LikeSelectivity on BiRelat predicate and unset the 
      // selecitivity hint on the original LIKE predicate.
      if(isSelectivitySetUsingHint())
      {
        selectivity = getSelectivityFactor();
        beginKey->setSelectivitySetUsingHint();
        beginKey->setSelectivityFactor(selectivity);
        setSelectivitySetUsingHint(FALSE);
        setSelectivityFactor(-1);
      }

      BiRelat *br = (BiRelat *) beginKey;
      br->setLikeSelectivity(selectivity);
      // Like pred has non_wildcard beginning and ends in %
      // Later we will collapse histogram into one interval if this flag is set.
      // In this simple case, it is better to not flag this BiRelat as 
      // originating from LIKE so that we get a better histogram on it. 
      // We may lose some knowledge of correlation between begin/end keys 
      // but it is better to have 2 unrelated birelats with good stats than 
      // correlated begin/end preds with a single interval histogram. JIRA 2512
      if(boundExpr)
        br->setOriginalLikeExprId(getValueId());

      // Compute the value following the beginKey prefix:
      // If beginKey == 'ab', this will return 'ac';
      // if 'a\377', then 'b'; if '\377\377', then '' and FALSE;
      // if can't compute next key (due to multibyte chars or nondefault
      // collating sequence), then it returns '' and FALSE.
      // If we get a TRUE return, then build endKey predicate.
      //

      NABoolean foundNextKey = FALSE;

      if ( matchCharType->getCharSet() == CharInfo::ISO88591 )
      {
	  foundNextKey = matchCharType->computeNextKeyValue(prefix);
	  byte_str_cpy(prefixZ, matchLen, prefix.data(), prefix.length(),
		       (char)zeroChar);
      }
      else if ( matchCharType->getCharSet() == CharInfo::UCS2 )
      {
	  NAWString prefixW((NAWchar*)pattern.getPattern(),
			    pattern.getClauseLength()>>1
			   );
	  foundNextKey = matchCharType->computeNextKeyValue(prefixW);
	  byte_str_cpy(prefixZ, matchLen,
		       (char*)prefixW.data(), prefixW.length()<<1,
		       (char)zeroChar
		      );
      }
      else if ( matchCharType->getCharSet() == CharInfo::UTF8 )
      {
	  foundNextKey = matchCharType->computeNextKeyValue_UTF8(prefix);
	  byte_str_cpy(prefixZ, matchLen, prefix.data(), prefix.length(),
		       (char)zeroChar);
      }

      if ( foundNextKey )
      {
	ItemExpr *child1 = new (heap) SystemLiteral(
				NAString(prefixZ, matchLen),
				matchCharType->getCharSet(),
				matchCharType->getCollation(),
				matchCharType->getCoercibility()
						  );
	if ((specialMode) && (matchCharType->isCaseinsensitive()))
	  child1 = new (bindWA->wHeap()) Upper(child1);

	ItemExpr *endKey =
	    new (heap) BiRelat(ITM_LESS, matchExpr,
				     child1,
				     FALSE,	  // specialNulls flag
				     FALSE	  // partKeyPred flag
			      );

	BiRelat *br = (BiRelat *) endKey;
	br->setAddedForLikePred(TRUE);

	// set selectivity of the second range predicate equal to 1.0
	br->setLikeSelectivity(1.0);
        if(boundExpr)
          br->setOriginalLikeExprId(getValueId());


	if (boundExpr)
	  boundExpr = new (heap) BiLogic(ITM_AND, boundExpr, endKey);
	else
	  boundExpr = endKey;
      } // foundNextKey

      if (boundExpr)
	boundExpr = new (heap) BiLogic(ITM_AND, beginKey, boundExpr);
      else
	boundExpr = beginKey;

      CMPASSERT(bindWA);
      boundExpr = boundExpr->bindNode(bindWA);

      NADELETEBASIC(prefixZ, heap);
      
      beginEndKeysApplied_ = TRUE;

    } // pattern has a non-wild prefix
    else
    {
      // pattern has a wild card prefix. At this point see if the user
      // has used the old CQD HIST_DEFAULT_SEL_FOR_LIKE_WILDCARD. If he has
      // then set a flag here to indicate that the optimizer should use the
      // old CQD as the default selectivity for '%ab type cases. This is to
      // maintain upward compatibility for the compiler

      if (bindWA)
      {
	// check the CQD list set by the user to see if HIST_DEFAULT_SEL_FOR_LIKE_WILDCARD
	// has been set

        ControlDB *cdb = ActiveControlDB();

	for (CollIndex i = 0; i < cdb->getCQDList().entries(); i++)
	{
	   ControlQueryDefault *cqd = cdb->getCQDList()[i];
	   if (cqd->getAttrEnum() == HIST_DEFAULT_SEL_FOR_LIKE_WILDCARD)
	   {
	     oldDefaultSelForLikeWildCardUsed_ = TRUE;
	     break;
	   }
	} // done checking for HIST_DEFAULT_SEL_FOR_LIKE_WILDCARD
      }
    }
  } // optimizeLike: pattern && escape are non-null constants

  return boundExpr;
} // Like::applyBeginEndKeys()

// -----------------------------------------------------------------------
// member functions for class Case
// -----------------------------------------------------------------------

ItemExpr *Case::bindNode(BindWA *bindWA)
{
  if (nodeIsBound())
    return getValueId().getItemExpr();

  //
  // Check whether the CASE statement is in the following form:
  //
  // CASE val0 WHEN val1 THEN result1 WHEN val2 THEN result2 ...
  //
  // If so, convert it to the following form:
  //
  // CASE WHEN val0 = val1 THEN result1 WHEN val0 = val2 THEN result2 ...
  //
  ItemExpr *caseOperand = removeCaseOperand();
  if (caseOperand) {
    caseOperand = caseOperand->bindNode(bindWA);
    if (bindWA->errStatus())
      return this;
    ItemExpr *ifThenElse = child(0);
    CMPASSERT(ifThenElse->getOperatorType() == ITM_IF_THEN_ELSE);
    //
    // The ELSE clause may be a NULL pointer if this is part of a CASE
    // statement created by the generator.
    //
    do {
      ifThenElse->child(0) = new (bindWA->wHeap())
	BiRelat(ITM_EQUAL, caseOperand,	ifThenElse->child(0));
      ifThenElse = ifThenElse->child(2);
    } while (ifThenElse AND ifThenElse->getOperatorType() == ITM_IF_THEN_ELSE);
  }

  if (CmpCommon::getDefault(ALLOW_INCOMPATIBLE_OPERATIONS) == DF_ON)
    {
      // if operands are incompatible, insert cast node to convert them
      // to a common datatype.
      // Right now, only done for CHAR and NUMERICs.
      ItemExpr *ifThenElse = child(0);
      ItemExpr * thenClause = ifThenElse->child(1)->castToItemExpr();
      NABoolean done = FALSE;
      NABoolean charFound = FALSE;
      NABoolean numericFound = FALSE;
      Lng32 dLen = 0;
      Lng32 thenClauseNum = 1;
      while ((ifThenElse) && (NOT done))
        {
          thenClause = thenClause->bindNode(bindWA);
          if (bindWA->errStatus())
            return this;
      
          ifThenElse->setChild(thenClauseNum, thenClause);
      
          if ((thenClause->getOperatorType() == ITM_CONSTANT) &&
              ((ConstValue *)thenClause)->isNull())
            {
              // do nothing
            }
          else if (thenClause->getValueId().getType().getTypeQualifier() 
                   == NA_CHARACTER_TYPE)
            {
              if (thenClause->getValueId().getType().getNominalSize() > dLen)
                dLen = thenClause->getValueId().getType().getNominalSize();
              charFound = TRUE;
            }
          else if (thenClause->getValueId().getType().getTypeQualifier() 
                   == NA_NUMERIC_TYPE)
            {
              NumericType &numeric = (NumericType&)
                thenClause->getValueId().getType();
              Lng32 numericDLen =
                numeric.getDisplayLength(numeric.getFSDatatype(),
                                         numeric.getNominalSize(),
                                         numeric.getPrecision(),
                                         numeric.getScale(),
                                         0);
              
              if (numericDLen > dLen)
                dLen = numericDLen;
              numericFound = TRUE;
            }
          else
            {
              done = TRUE;
            }
      
          if (thenClauseNum == 2)
            ifThenElse = NULL;
          else
            {
              if (ifThenElse->child(2)->getOperatorType() == ITM_IF_THEN_ELSE)
                {
                  ifThenElse = ifThenElse->child(2);
                  thenClause = ifThenElse->child(1);
                  thenClauseNum = 1;
                }
              else
                {
                  // this is the else clause
                  thenClause = ifThenElse->child(2);
                  thenClauseNum = 2;
                }
            }
        } // while
  
      if ((NOT done) && (charFound) && (numericFound))
        {
          ifThenElse = child(0);
          thenClause = ifThenElse->child(1)->castToItemExpr();
          thenClauseNum = 1;
          while (ifThenElse)
            {
              if (thenClause->getValueId().getType().getTypeQualifier() 
                  == NA_NUMERIC_TYPE)
                {
                  // cast to character
                  thenClause =
                    new (bindWA->wHeap())
                    Cast(thenClause,
                         new (bindWA->wHeap())
                         SQLChar(bindWA->wHeap(), dLen,
                                 thenClause->
                                 getValueId().getType().supportsSQLnull()));
                  
                  thenClause = thenClause->bindNode(bindWA);
                  if (bindWA->errStatus())
                    return this;
                  
                  ifThenElse->setChild(thenClauseNum, thenClause);
                }
              
              if (thenClauseNum == 2)
                ifThenElse = NULL;
              else
                {
                  if (ifThenElse->child(2)->getOperatorType() == ITM_IF_THEN_ELSE)
                    {
                      ifThenElse = ifThenElse->child(2);
                      thenClause = ifThenElse->child(1);
                      thenClauseNum = 1;
                    }
                  else
                    {
                      // this is the else clause
                      thenClause = ifThenElse->child(2);
                      thenClauseNum = 2;
                    }
                }
            } // while
        }
    } // allow incompatible operations
  
  // Case inherits from BuiltinFunction .. Function .. ItemExpr.
  ItemExpr *boundExpr = BuiltinFunction::bindNode(bindWA);

  // Fix for "BR0094.txt", here and in ItemExpr::synthTypeAndValueId() --
  // If we are "CASE(select..from..) WHEN..ELSE..",
  // make sure our result type is NULLABLE, as the subq may produce zero rows.
  if (caseOperand && caseOperand->isASubquery()) {
    ValueId vid = boundExpr->getValueId();
    const NAType* nullableType =
      vid.getType().synthesizeNullableType(bindWA->wHeap());
    vid.changeType(nullableType);
    CMPASSERT(boundExpr->getOperatorType() == ITM_CASE);
    ((Case *)boundExpr)->caseOperandWasNullable() = TRUE;
  }

  return boundExpr;
} // Case::bindNode()

// -----------------------------------------------------------------------
// member functions for class ColReference
//
// (but first, a BindWA method called by ColReference::bindNode below,
// and by Natural Join binding code in BindRelExpr.C)
// -----------------------------------------------------------------------

// **FOR DML:**
//
// Mark column as of interest to the Optimizer (particularly ScanOptimizer.C).
// Optimizer will expect:
//
// - Full stats (a ColStats header and as many HistInts as there are)
// from each referenced column's *single-column* histogram, and
// will want full stats from any *multi-column* histogram
// that contains a referenced column (for MDAM).
//
// - Of columns that are not referenced in this query, those that belong to
// an index (any one) must have short stats (a ColStats header, no intervals)
// from their *single-column* histogram.  As there will always be at least
// one key column in a table (SYSKEY at the least), each table will end up
// having at least one ColStat, even if no refd cols ("SELECT c FROM t;"),
// which is another Optimizer assumption.
//
// - All other columns -- those not deemed referenced by the criteria below
// which also are not index keys -- the Optimizer has no use for any stats.
//
// The FetchHistograms function (in /ustat) uses this
// is-referenced flag, along with the columns' is-indexkey flags,
// and applies the rules above to deliver the minimum required stats.
//
// **FOR DDL -- actually only for CREATE VIEW:**
//
// On the first reference to a column, anywhere in the query per se
// (i.e. excluding constraints), add the column reference to the
// view-basetablecolumn list needed for one of the Ansi metadata tables.
// On any reference to a column within the top select-list of the view query,
// add to the viewcolumn-basetablecolumn list needed by CatMan to enforce
// the complicated REFERENCES privilege.
//

/*
Update: 09/14/2009

Columns are marked �REFERENCED_FOR_MULTI_INTERVAL_HISTOGRAM� which require full histograms. 
Full histogram means detailed histogram data which includes all the histogram interval data. 
For columns to be marked under this category, they should be part of one of the following groups:

- Key columns
- Where Clause
- Join predicate

Columns are marked "REFERENCED_FOR_SINGLE_INTERVAL_HISTOGRAM" which require only single 
interval histograms. For columns to be marked under this category, they should be part 
of one of the following groups:

- Union clause
- GroupBy Clause
- Having Clause

Columns are marked "REFERENCED_ANYWHERE" which do not fall into either of the above categories.
*/

void BindWA::markAsReferencedColumn(const ColumnDesc *cd, 
                                    NABoolean groupByRefForSingleIntHist)
{ 
  if (cd->getViewFileName())
  {
    setColumnRefsInStoi(cd->getViewFileName(),cd->getViewColPosition());
  }

  markAsReferencedColumn(cd->getValueId(), groupByRefForSingleIntHist); 
}

void BindWA::markAsReferencedColumn(const ValueId &vid,
                                    NABoolean markGroupByForSingleInt)
{
  BindContext *context = getCurrentScope()->context();

  // Pay attention only to the query per se, not to extra bits brought in from
  // the metadata.
  if (context->inAnyConstraint()) return;

  // If ColReference refers to a union of colrefs, or to an aggregate function,
  // or an instantiate-null, or whatever, no need to do anything --
  // the underlying colrefs will already have been marked by earlier binding.
  //
  NAColumn *nacol = vid.getNAColumn(TRUE/*okIfNotColumn*/);

   if (!nacol) 
  {
	if (vid.getItemExpr()->getOperatorType() == ITM_VALUEIDUNION) 
	{
	  ValueIdUnion *valIdUnion = (ValueIdUnion *)vid.getItemExpr();

	  NABoolean groupByRefForSingleIntHist = FALSE;

	  // If the GroupBy is due to UNION DISTINCT, do not mark grouping columns
	  // as referenced for histogram
	  if (valIdUnion->isTrueUnion() )
		groupByRefForSingleIntHist = TRUE;

	  for (CollIndex i = 0; i < valIdUnion->getSources().entries(); i++) 
	  {
		markAsReferencedColumn(valIdUnion->getSources()[i], groupByRefForSingleIntHist);
	  }
	}
	else
	{
	  ValueIdSet leafValues;

	  ItemExpr *tempPred = vid.getItemExpr();
	  if(!tempPred)
	    return;
	  
	  tempPred->findAll(ITM_BASECOLUMN, leafValues, TRUE, TRUE);

	  for ( ValueId id = leafValues.init();
		leafValues.next( id );
		leafValues.advance( id ) )
	  {
	      markAsReferencedColumn(id);
	  }
	}
	return;
  }

  const NATable * naTable = nacol->getNATable();

  if ( !naTable->isHiveTable() ) {
    NAString fileName( naTable->getViewText() ?
                    (NAString)naTable->getViewFileName() :
                    naTable->getClusteringIndex()->
                        getFileSetName().getQualifiedNameAsString(),
                    wHeap());

    setColumnRefsInStoi(fileName.data(),nacol->getPosition());
  }

  if (inDDL()||context->inOrderBy()) return;

  if ((CURRSTMT_OPTDEFAULTS->incorporateSkewInCosting()) )
  {
	if ( (nacol->isPartitioningKey() ) &&
		   (nacol->isUserColumn() ) &&
		   (nacol->getNATable()->getSpecialType() == ExtendedQualName::NORMAL_TABLE) )
	   nacol->setReferencedForMultiIntHist();
  }

  // column references that are in a prdicate - WHERE, HAVING,
  // column references that are in a GROUP BY. This does not include 
  // GroupBy created implicitly because of UNION DISTINCT
  // common columns in a NATURAL join,
  // column references that are in a join predicate
  // are marked as referenced for histogram

  BindScope *scope = getCurrentScope();

    while (scope) {
    BindContext *context = scope->context();
    if (context->inWhereClause()  ||
        context->inHavingClause() ||
        context->inJoinPred() ||
        // If the join has not been fully bound, the joinPred would not have
        // been set and the predicates would still exist as joinPredTree
        (context->inJoin() && context->inJoin()->getJoinPredTree()) ||
        context->inGroupByClause() ||
        context->inUnion())
     {
      //if column participates in a join pred mark it, since this
      //information is later used for reducing the number of histogram
      //intervals
      if (context->inJoinPred() || (context->inJoin() && context->inJoin()->getJoinPredTree()))
      	nacol->setHasJoinPred();

      //if column participates in a range pred mark it, since this
      //information is later used for reducing the number of histogram
      //intervals
      if (context->inRangePred())
    	nacol->setHasRangePred();
      
      // if it has already been marked referenced for histogram, we will not
      // reduce its scope, hence return
      // isReferencedForHistogram is set to TRUE if histogram is marked for either single interval
      // or full interval. If the histogram is marked for single interval, but another context
      // require it to be full histogram, we upgrade
      if (nacol->isReferencedForMultiIntHist())
        return;
      
      // the column is referenced in a predicate, used to determine
      // whether histograms should be fetched for this column reference
      if(markGroupByForSingleInt ||
         context->inGroupByClause() || 
         context->inHavingClause()  ||
         context->inUnion())
	nacol->setReferencedForSingleIntHist();
      else
	nacol->setReferencedForMultiIntHist();

      return;
    }
    scope = getPreviousScope(scope);
  }

  // column is referenced anywhere in a query, used by unpack
  nacol->setReferenced();

} // BindWA::markAsReferencedColumn()

ItemExpr *ColReference::bindNode(BindWA *bindWA)
{
  if (nodeIsBound()) 
    {
      if (getColRefNameObj().isStar())
        return this;

      BindScope *bindScope;
      ColumnNameMap *xcnmEntry = bindWA->findColumn(getColRefNameObj(), bindScope);
      if (bindScope != bindWA->getCurrentScope() &&
          (bindWA->getCurrentScope()->context()->inOlapOrderBy() || 
           bindWA->getCurrentScope()->context()->inOlapPartitionBy()))
        {
          *CmpCommon::diags() << DgSqlCode(-4391);
          bindWA->setErrStatus();
          return this;
        }    
      
      // this return has been there for a long time.
      // No idea what the code below it is doing since it will never be reached.
      return getValueId().getItemExpr();
      
      // In case the first time this Colreference was seen it was on
      // left side of a set clause
      NAColumn *nacol = getValueId().getNAColumn(TRUE/*okIfNotColumn*/);
      const NATable * naTable = nacol->getNATable();
      NAString fileName( naTable->getViewText() ?
                         (NAString)naTable->getViewFileName() :
                         naTable->getClusteringIndex()->
                         getFileSetName().getQualifiedNameAsString(),
                         bindWA->wHeap());
      
      bindWA->setColumnRefsInStoi(fileName.data(),nacol->getPosition());
      
    }
  
  // In mode_special_4,
  // if name is of the form:   IDENTIFIER.NEXTVAL or IDENTIFIER.CURRVAL,
  // then change it to:  seqnum(identifier, next) or seqnum(identifier, current)
  // If name is: ROWNUM, change it to ROWNUM() function.
  if (CmpCommon::getDefault(MODE_SPECIAL_4) == DF_ON) 
    {
      ColRefName &colRefName = getColRefNameObj();
      CorrName &cn = getCorrNameObj();
      
      const NAString &catName = cn.getQualifiedNameObj().getCatalogName();	       
      const NAString &schName = cn.getQualifiedNameObj().getSchemaName();		
      const NAString &objName = cn.getQualifiedNameObj().getObjectName();		
      const NAString &colName = colRefName.getColName();

      if (((catName.isNull()) &&
          (schName.isNull()) &&
          ((colName == "NEXTVAL") ||
           (colName == "CURRVAL"))) ||
          (((catName.isNull()) &&
            (schName.isNull()) &&
            (objName.isNull())) &&
           (colName == "ROWNUM")))
        {
          ItemExpr * itemExpr = NULL;

          if (colName == "ROWNUM")
            {
              itemExpr = new(bindWA->wHeap()) RowNumFunc();
            }
          else
            {
              CorrName seqName(objName);
              seqName.setSpecialType(ExtendedQualName::SG_TABLE);
              
              itemExpr = 
                new(bindWA->wHeap()) SequenceValue(seqName, 
                                                   (colName == "NEXTVAL" ? FALSE : TRUE),
                                                   (colName == "NEXTVAL" ? TRUE : FALSE));
            }

          itemExpr = itemExpr->bindNode(bindWA);
          if (bindWA->errStatus()) 
            return this;
          ValueId valId = itemExpr->getValueId();
          setValueId(valId);

          bindSelf(bindWA);
          return itemExpr;
        }
    }

  // override schema
  if ( ( bindWA->overrideSchemaEnabled() ) 
       // do not override if no column name
    && ( ! getColRefNameObj().getColName().isNull() )  
    // do not override if in a constraint (required override should have been done)
    && ( ! bindWA->getCurrentScope()->context()->inCheckConstraint() )) {
       bindWA->doOverrideSchema(getCorrNameObj());
    }

  // fix 0-061115-0532 (query cache didn't handle select with embedded
  // update correctly). New/Old corr. names are recorded here in bindWA.
  // 
  NABoolean hasSeenNewOrOldName = FALSE;
  if ( getCorrNameObj().getQualifiedNameObj().getObjectName() == "NEW" ) {
    bindWA->appendCorrNameToken('N');
    hasSeenNewOrOldName = TRUE;
  } else {
    if ( getCorrNameObj().getQualifiedNameObj().getObjectName() == "OLD" ) {
      bindWA->appendCorrNameToken('O'); 
      hasSeenNewOrOldName = TRUE;
    }
  }

  // See if UDF_SUBQ_IN_AGGS_AND_GBYS is enabled. It is enabled if the
  // default is ON, or if the default is SYSTEM and ALLOW_UDF is ON.
  NABoolean udfSubqInAggGrby_Enabled = FALSE;
  DefaultToken udfSubqTok = CmpCommon::getDefault(UDF_SUBQ_IN_AGGS_AND_GBYS);
  if ((udfSubqTok == DF_ON) ||
      (udfSubqTok == DF_SYSTEM))
    udfSubqInAggGrby_Enabled = TRUE;
  
  BindScope *currScope = bindWA->getCurrentScope();
  if (getColRefNameObj().isStar()) {			// "*" or "CORR.*"

    if ( hasSeenNewOrOldName == TRUE )
      bindWA->appendCorrNameToken('*'); 

    RETDesc* resultTable = currScope->getRETDesc();
    CorrName corrName = getCorrNameObj();
    const ColumnDescList *colList;

    if (resultTable == NULL) { // for example values(sas_score("HHH",t.*));
      NAString nam("*", bindWA->wHeap());
      NAString fmtdList(bindWA->wHeap());
      LIST(TableNameMap*) xtnmList(bindWA->wHeap());
      bindWA->getTablesInScope(xtnmList, &fmtdList);	// Tables in all scopes
      if(fmtdList.isNull())
        fmtdList = "NONE";

      *CmpCommon::diags() << DgSqlCode(-4002)
        << DgColumnName(nam)
        << DgTableName(getCorrNameObj().getExposedNameAsAnsiString())
        << DgString0(fmtdList)
        << DgString1(bindWA->getDefaultSchema().getSchemaNameAsAnsiString());
      bindWA->setErrStatus();
      return this;
    }
    if (collateClause()) {
      // 4034 The operation (T.* COLLATE coll-name) is not allowed.
      NAString nam("*", bindWA->wHeap());
      if (corrName != "")
        nam.prepend(corrName.getExposedNameAsAnsiString() + ".");
      *CmpCommon::diags() << DgSqlCode(-4034)
        << DgString0(nam)
	<< DgString1("COLLATE")
	<< DgString2(CharInfo::getCollationName(collateClause()->collation_));
      bindWA->setErrStatus();
      return this;
    }
    if (corrName == "")
    {
      colList = resultTable->getColumnList();
      if(CmpCommon::getDefault(DISPLAY_DIVISION_BY_COLUMNS) == DF_ON)
      {
    	ColumnDescList *divColList = new(bindWA->wHeap())
    			  ColumnDescList(bindWA->wHeap());

    	for (CollIndex i=0; i<colList->entries(); i++)
    		  divColList->insert(colList->at(i));

    	const ColumnDescList *sysColList = resultTable->getSystemColumnList();
    	for (CollIndex i=0; i<sysColList->entries(); i++)
    	{
    		ColumnDesc *colDesc = sysColList->at(i);
    		NAColumn *nacol = colDesc->getValueId().getNAColumn(TRUE);
    		if(nacol->isDivisioningColumn())
    			divColList->insert(colDesc);
    	}
    	colList = divColList;
      }
    }
    else {
      colList = resultTable->getQualColumnList(corrName);

      if (!colList || !colList->entries()) {
	// 4010 There are no user columns with the qualifier.
	*CmpCommon::diags() << DgSqlCode(-4010)
			  << DgTableName(corrName.getExposedNameAsAnsiString());
	bindWA->setErrStatus();
	return this;
      }
    }

    // -- MVs
    // Remove from the list columns that are system added.
    CMPASSERT(resultTable!=NULL &&  colList!=NULL);
    if (!getColRefNameObj().getStarWithSystemAddedCols())
    {
      ColumnDescList *minimalColList = new(bindWA->wHeap())
	ColumnDescList(bindWA->wHeap());
      for (CollIndex i=0; i<colList->entries(); i++)
      {
	ColumnDesc *colDesc = colList->at(i);
	NAColumn *col = colDesc->getValueId().getNAColumn(TRUE);
	if (col==NULL || !col->isMvSystemAddedColumn())
	    minimalColList->insert(colDesc);
      }
      colList = minimalColList;
    }

    //
    // If this is in a GROUP BY clause, mark each column as a grouping column.
    // (Our extension to ANSI)
    //
    if (currScope->context()->inGroupByClause() && 
        (!udfSubqInAggGrby_Enabled ||
         !currScope->context()->inUDFunction())) {
      for (CollIndex i = 0; i < colList->entries(); i++)
      {
        (*colList)[i]->setGroupedFlag();
        if ((*colList)[i]->getValueId().getItemExpr()
                             ->containsOpType(ITM_RANDOMNUM))
        {
          // Temporary fix till random is supported in ORDER BY, GROUP BY
          // For now do not allow random in ORDER BY clause, GROUP BY
          // and DISTINCT.
          *CmpCommon::diags() << DgSqlCode(-4313);
          bindWA->setErrStatus();
          return this;
        }
      }
    }

    ColumnDescList *collapseStar = NULL;
    if (currScope->context()->inSelectList()) {
	  CMPASSERT( (corrName != "") || // -- Triggers
		         (bindWA->getPreviousScope(currScope) != NULL));
      if (corrName == "" &&
	  bindWA->getPreviousScope(currScope)->	    // simply contained
		     context()->inExistsPredicate()) {
	//
	// ANSI 7.9 SR 3a applies to "*" (simply contained only!), not "T.*":
	// - "exists (select * from (select a,a from t) x)" is equivalent to
	//   "exists (select 1 from (select a,a from t) x)" (arbitrary literal).
	// Note that since
	// - "exists (select * from (...group by a,e having...) x)" is equiv to
	//   "exists (select 1 from (...group by a,e having...) x)",
	// we do not require that columns b,c,d be grouping columns.
	//
	// So to bind this case ("*" simply contained in "exists"),
	// we just expand the * into the first column in the list,
	// not checking for duplicate/ambiguous column references.
	// This collapsing to a degree-one (scalar) result makes
	// BindRelExpr.C/bindRowValues() happy.
	// Later on, Subquery::transformNode will remove the unnecessary
	// selected column from the characteristic output.
	//
	collapseStar = new (bindWA->wHeap()) ColumnDescList(bindWA->wHeap());
	collapseStar->insert((*colList)[0]);
	colList = collapseStar;
      } else {		// not bare "*" simply contained by an Exists pred
	//
	// ANSI 7.9 SR 3b + 4:  replace "*" and "T.*" with a sequence of
	// column references; referenced columns cannot be ambiguous (6.4 SR 4).
	// Unnamed columns should actually have unique implementation-dependent
	// names so must not be considered ambiguous.
	//
	for (CollIndex i = 0; i < colList->entries(); i++) {
	  ColumnDesc *columnDesc = (*colList)[i];
	  if (NOT columnDesc->getColRefNameObj().isEmpty()) {	// named column
	    ColumnNameMap *xcnmEntry = bindWA->findColumn(*columnDesc);
	    if (xcnmEntry->isDuplicate()) {
              // 4011: Ambiguous star column reference.
              *CmpCommon::diags() << DgSqlCode(-4011)
		 << DgColumnName(columnDesc->getColRefNameObj().
		 		             getColRefAsAnsiString());
	      bindWA->setErrStatus();
	      return this;
	    }
	  }	// named column
	}	// for-loop
	//
	// If the table is a grouped table, each column in the select list
	// must be a grouping column.
	//
	if (resultTable->isGrouped()) {
	  for (CollIndex i = 0; i < colList->entries(); i++) {
	    ColumnDesc *columnDesc = (*colList)[i];
	    if (NOT columnDesc->isGrouped()) {
              // 4012: col must be grouping col; on this tbl star ref is illegal
              *CmpCommon::diags() << DgSqlCode(-4012)
		 << DgColumnName(columnDesc->getColRefNameObj().
					     getColRefAsAnsiString());
	      bindWA->setErrStatus();
	      return this;
	    }
	  }
	}		// isGrouped
      }			// not bare "*" simply contained by an Exists pred
    }			// inSelectList
    //
    setStarExpansion(colList);
    // The collapseStar case is not a real column ref, so skip these two things:
    if (!collapseStar) {
      BindUtil_UpdateNameLocForStarExpansion(bindWA, *colList,
					     getColRefNameObj().getNamePosition(),
                                             getParent());
      for (CollIndex i = 0; i < colList->entries(); i++)
	bindWA->markAsReferencedColumn((*colList)[i]);
    }

    bindSelf(bindWA);
    return this;
  } 		// ColReference::bindNode -- reference to "*" or "CORR.*"

  Lng32 sqlCode = 0;
  BindScope *bindScope;
  ColumnNameMap *xcnmEntry = bindWA->findColumn(getColRefNameObj(), bindScope);

  // When nametype is SHORTANSI in RETDesc::addColumnDesc() columns
  // are fully qualified before being inserted into into xcnm_.insert().
  // For a statement  like :
  //            Select sys_vol_subvol.table.column
  //            from sys_vol_subvol.table;
  // or
  //            set schema 'sys_vol_subvol';
  //            select table.column
  //            from table;
  // xcnm_.insert() inserts \sys.vol.subvol.table.column.
  // But in the above bindWA->findColumn() it is still looking for
  // sys_vol_subvol.table.column, so in the below changes it looks for
  // \sys.vol.subvol.table.column and finds it successfully.
  // Fix for CR-10-000719-1267.




  if ((xcnmEntry == NULL) &&
      (NOT getColRefNameObj().getCorrNameObj().getQualifiedNameObj().getObjectName().isNull()) &&
      (CmpCommon::context()->sqlSession()->volatileSchemaInUse()))
    {
      CorrName newCorrName = 
	CmpCommon::context()->sqlSession()->getVolatileCorrName
	(getColRefNameObj().getCorrNameObj());

      newCorrName.applyDefaults(bindWA, bindWA->getDefaultSchema());
      if (bindWA->errStatus())
	return NULL;		
      
      ColRefName *cstColRefName = NULL;
      cstColRefName = new(bindWA->wHeap())
		      ColRefName(getColRefNameObj().getColName(),
				 newCorrName, bindWA->wHeap());

      xcnmEntry = bindWA->findColumn(*cstColRefName, bindScope);
      if (xcnmEntry)
	getColRefNameObj().getCorrNameObj() = newCorrName;
    }

  NAString colRefStr(  xcnmEntry ?
  		       xcnmEntry->getColRefNameObj().getColRefAsAnsiString()
                       :
		       getColRefNameObj().getColRefAsAnsiString(),
                       bindWA->wHeap()) ;

  // VO, Genesis solution 10-040107-2237:
  //     If the column WAS specified as delimited, but
  //     looks like a regular identifier, then add the quotes
  if ( getColRefNameObj().isDelimited()      &&     // colRef WAS   "FOO"
       colRefStr[(StringPos)0] != '"'               // colRef IS    FOO
     )
    colRefStr = NAString('"') + colRefStr + NAString('"');

  if ( xcnmEntry == NULL ||
       xcnmEntry->isQualifiedColumnAmbiguous() ||

       ( xcnmEntry->isDuplicate() &&
	 NOT getColRefNameObj().isQualified() )

     )
  {
    NAString fmtdList(bindWA->wHeap());
    LIST(TableNameMap*) xtnmList(bindWA->wHeap());

    if (xcnmEntry == NULL) {
      if (getCorrNameObj() == "")
	sqlCode = -4001;  // col not found.
      else if (!bindWA->findCorrName(getCorrNameObj(), bindScope))
	sqlCode = -4002;  // corr.col not found. table "corr" not exposed.
      else
	sqlCode = -4003;  // corr.col not a col of specified table "corr".
      bindWA->getTablesInScope(xtnmList, &fmtdList);	// Tables in all scopes
      //10-031030-0943 -begin
      //If the fmtdList is empty then dont give a blank
      //string  fill it with "NONE" so that the error message is meaningful
      if(fmtdList.isNull())
        fmtdList = "NONE";
      //10-031030-0943 -end
    }
    else {
      sqlCode = -4004;    // col is ambiguous.
      bindScope->getTablesInScope(xtnmList, &fmtdList);	// Tables in ambig scope
    }

    // Genesis case 10-971208-5113
    // Tandem extension allows an ORDER BY column to be absent from the SELECT
    // list except when aggregation or GROUP BY are involved. Of course, those
    // columns must be in the tables exposed.
    //
    // If we are getting -4001,-4002 or -4003 when binding an ORDER BY column,
    // a couple of scenarios are possible:
    //
    // 1. There is no aggregation or GROUP BY in the query, and the column is
    //    really not in tables exposed (in this case, xtnmList.entries() > 0).
    // 2. There is aggregation or GROUP BY in the query, and the column is not
    //    found in the SELECT-list.
    //
    if ( (sqlCode == -4001 || sqlCode == -4002 || sqlCode == -4003) &&
          currScope->context()->inOrderBy() &&
          currScope->getRETDesc()->isGrouped() )
    {
      sqlCode = (!xtnmList.entries()) ? -4120 : -4121;
      *CmpCommon::diags() << DgSqlCode(sqlCode)
			  << DgColumnName(colRefStr)
			  << DgString0(fmtdList);
    }
    // genesis case 10-031030-7250:"NE:R2 MX1013 INSERT/SELECT not able to
    // handle ORDER BY with all columns". We want to reject insert-selects
    // of the form "insert into t(a) select a from s order by b" because
    // they can cause lots of block splits. Ideally, we want the source to
    // be in the same clustering key sequence as the target.
    else if ((sqlCode == -4001 || sqlCode == -4002 || sqlCode == -4003) &&
             currScope->context()->inOrderBy() &&
             currScope->context()->inInsert()) {
      *CmpCommon::diags() << DgSqlCode(-4135) << DgColumnName(colRefStr);
    }
    else
    {
    *CmpCommon::diags() << DgSqlCode(sqlCode)
      << DgColumnName(colRefStr)
      << DgTableName(getCorrNameObj().getExposedNameAsAnsiString())
      << DgString0(fmtdList)
      << DgString1(bindWA->getDefaultSchema().getSchemaNameAsAnsiString());

    // Genesis 10-970902-0878:
    // user typed "foo" when they meant 'foo',
    // or "FOO" when they meant 'FOO'.
    //
    if (getCorrNameObj() == "")		     // sqlCode could be -4001 or -4004
      if (colRefStr[(StringPos)0] == '"')
      {
        NAString literalStr(colRefStr, bindWA->wHeap());
	literalStr[(StringPos)0] = '\'';
	literalStr[literalStr.length()-1] = '\'';	// literalStr is 'foo'
	*CmpCommon::diags() << DgSqlCode(4104)
                            << DgColumnName(colRefStr)
                            << DgString0(literalStr);
      }
    } // endif (sqlCode == -4001 ... && currScope->context()->inOrderBy())

  } // xcnmEntry error (col not found, or duplicate/ambiguous)

  // Genesis 10-970929-8459:
  //   'SELECT * FROM ta JOIN tb ON a=b,c;'
  //   is perfectly legal unambiguous Ansi, but ambiguous for SQL/MX
  //	 because our Tandem-extension allowing Sql-row-value-constructor
  //   does not require parens around a value list;
  //   thus 'c' in example above is parsed as a column ref
  //   but user may well have (here, they did!) intended it as a table ref.
  //
  // Hence here we emit 4101 in addition to the preceding errmsg.
  //   So in this case we misinterpret legal Ansi syntax, emitting an error.
  //	 That's unfortunate, but fixing SqlParser productions for search_cond
  //   is prohibitive at this time.  Also note that
  //   'SELECT * FROM ta JOIN tb ON a,a2=b,b2,c;'
  //   is not legal Ansi, but likewise ambiguous for our parser.
  //	 'SELECT * FROM ta JOIN tb ON (a,a2=b,b2),c;' -- legal-Ansi, unambig-Tdm
  //	 'SELECT * FROM ta JOIN tb ON a,a2=(b,b2),c;' -- legal-Ansi, unambig-Tdm
  //	 'SELECT * FROM c, ta JOIN tb ON a,a2=b,b2;'  -- unambig-Tdm
  //   (The last has the side-effect of reordering the output *-list.)
  //
  // 4101: If $0~String0 is intended to be a further table reference
  //   in the FROM clause, the preceding join search condition must be
  //   enclosed in parentheses.
  //   (Or the rightmost row-value-ctor must be parenthesized.
  //	  Or the table ref must come *first* in the list of FROM tbl-refs.
  //    But this is all too wordy for a single error message!)
  //
  // Note that if 'c' in the above query is unambiguously found in scope
  // (column of 'ta' or 'tb'), then we need to first emit error 4042, then 4101.
  //
  if (getColRefNameObj().getCorrNameObj().getQualifiedNameObj().getCatalogName()
      .isNull()) {  // a 4-part name can only be a colref, so 4101 doesn't apply

    // Does this colref appear in the rightmost arg of a BiRelat or Function
    // which appears rightmost in the join pred?
    //	  Note that  'mPred->containsRightmost(this)'
    //	  could NOT replace the mPredChNo lines below; e.g. in a case like
    //	  'SELECT * FROM ta JOIN tb ON a=b,c,d;'
    //	  -- c is not rightmost in the list but it is cause for error 4101.
    //
    BindContext *context = bindWA->getCurrentScope()->context();
    ItemExpr *jPred = context->inJoinPred();
    ItemExpr *mPred = context->inMultaryPred();
    Lng32 mPredChNo  = mPred? mPred->currChildNo() : 0;
    if (jPred->containsRightmost(mPred) &&	// BiR/Func is rtmost in JoinPrd
        mPredChNo &&				// RHS of BiRelat/Function
       (mPredChNo >= mPred->getArity()-1 ||	// absolute rightmost item
	!mPred->child(mPredChNo+1)))	{	// effective rightmost item

      // Does this colref appear in a list, at a position greater than
      // the degree of the LHS comparand list?
      //
      ItemExpr *iList = context->inItemList();
      Lng32 iListChNo  = iList? iList->currChildNo() : 0;
      Lng32 mPredPrevDegree = mPred->child(mPredChNo-1)->currChildNo();
      if (iListChNo && iListChNo >= mPredPrevDegree) {	// degree, not arity!

	if (!sqlCode) {
	  // The operands of a comparison predicate must be of equal degree.
	  // Error emitted here because we'll be setting errStatus and our
	  // caller won't be calling SynthType.C where this usually appears.
	  //
	  sqlCode = -4042;
	  *CmpCommon::diags() << DgSqlCode(sqlCode);
	}
	*CmpCommon::diags() << DgSqlCode(-4101) << DgString0(colRefStr);

	// Rather than emit these errors, we could take this "col" ref
	// and the remainder of the iList and rewrite them as tbl refs (Scans),
	// attaching them to the parent query tree in the proper place.
	// Then we could achieve full Ansi syntax conformance.
      }
    }
  }

  if (sqlCode) {
#ifndef NDEBUG					// ##tmp
    // The following debug code is often useful when debugging 
    // internal queries when the metadata changes. Just set the
    // environment variable in a debug build to see the output.
    if (getenv("COLREFERENCE_DEBUG")) {
      BindContext *ctxt = bindWA->getCurrentScope()->context();
      char ii = ctxt->inItemList() ?    'i' : ' ';
      char jj = ctxt->inJoinPred() ?    'j' : ' ';
      char mm = ctxt->inMultaryPred() ? 'm' : ' ';
      Int32 iia = ii == ' ' ? -99 : ctxt->inItemList()->getArity();
      Int32 iic = ii == ' ' ? -99 : ctxt->inItemList()->currChildNo();
      Int32 jja = jj == ' ' ? -99 : ctxt->inJoinPred()->getArity();
      Int32 jjc = jj == ' ' ? -99 : ctxt->inJoinPred()->currChildNo();
      Int32 mma = mm == ' ' ? -99 : ctxt->inMultaryPred()->getArity();
      Int32 mmc = mm == ' ' ? -99 : ctxt->inMultaryPred()->currChildNo();
      cout << getColRefNameObj().getColRefAsAnsiString()
        << "	(" << ii << " " << iia << " " << iic << ") "
        << "	(" << jj << " " << jja << " " << jjc << ") "
        << "	(" << mm << " " << mma << " " << mmc << ") "
        << endl;
    }
#endif // NDEBUG
    bindWA->setErrStatus();
    return this;
  }

  if (NULL == xcnmEntry)
  {
    bindWA->setErrStatus();
    return this;
  }

  // Continue with no-error, non-star column reference.
  ValueId valId = xcnmEntry->getValueId();
  setValueId(valId);	// not bound yet, but this makes more informative errmsg
  			// if ColReference::getText() or unparse() is used

  const NAType *xcnmType = &valId.getType();
  const NAType *thisType = synthTypeWithCollateClause(bindWA, xcnmType);

  if (thisType != xcnmType) {
    if (!thisType) return this;

    // We have a new type because an explicit COLLATE clause was specified
    // in the query (e.g., SELECT charColumn COLLATE SJIS FROM ...)
    // We must now CAST(BaseColumn AS xxx COLLATE zzz).
    // Yes, we must do this even if BaseColumn's collation is IMPLICITly "zzz".
    // Yes, we must CAST, not changeType, as that would change the BaseColumn
    // from IMPLICIT to EXPLICIT for *all* ColRef's!
    //
    // Compare propagateCoAndCoToChildren() in SynthType.cpp.
    //
    ItemExpr *itemExpr = valId.getItemExpr();
    itemExpr = new (bindWA->wHeap()) Cast(itemExpr, thisType);
    itemExpr = itemExpr->bindNode(bindWA);
    if (bindWA->errStatus()) return this;
    valId = itemExpr->getValueId();
    setValueId(valId);
  }

  const NAType &naType = valId.getType();
  if (!naType.isSupportedType() && !bindScope->context()->inSelectList()) {
    *CmpCommon::diags() << DgSqlCode(-1010);
    bindWA->setErrStatus();
    return this;
   }

  // If the column reference is in a GROUP BY, mark it as a grouping column.
  //
  if ((currScope->context()->inGroupByClause()) AND
      (bindScope == currScope) AND
      (!udfSubqInAggGrby_Enabled ||
       (!currScope->context()->inUDFunction())))
     xcnmEntry->getColumnDesc()->setGroupedFlag();
  //
  // If a local column reference is in a HAVING clause or in the select list of
  // a grouped table, or an outer reference is in a subquery that is in a
  // HAVING clause or in the select list of a grouped table, the column
  // reference must be a grouping column or be specified within an aggregate.
  //
  if (bindScope->context()->inHavingClause() OR (
      bindScope->context()->inSelectList() AND
      bindScope->getRETDesc()->isGrouped() AND
      (NOT bindScope->context()->inGroupByOrdinal())
     ))
    if (NOT xcnmEntry->getColumnDesc()->isGrouped() AND
	//NOT (currScope->context()->inAggregate() || currScope->context()->inUDFunction())) {
	NOT (currScope->context()->inAggregate() )) {
      // 4005: col must be grouping col or specified within an aggregate
      *CmpCommon::diags() << DgSqlCode(-4005)
                 << DgColumnName(getColRefNameObj().getColRefAsAnsiString());
      bindWA->setErrStatus();
      return this;
    }
  // If the bindScope's table later on turns into a grouped table
  // (no groupby columns exist, but if an aggregate on a column of that table,
  //  as an outer ref, will turn the table into a grouped table of one group),
  // then this nonaggregated column reference will become illegal, by
  // ANSI 7.9 SR 7.  Mark this here and check later in RelRoot::bindNode().
  // Also added check for the case where we have a subquery inside an
  // aggregate.
  if (bindScope->context()->inSelectList() AND
      NOT bindScope->getRETDesc()->isGrouped() AND
      NOT (currScope->context()->inAggregate() OR
           (udfSubqInAggGrby_Enabled AND
            (bindScope->context()->inAggregate() AND
             bindScope->context()->inSubquery()))) AND
      NOT bindScope->context()->unaggColRefInSelectList())
    bindScope->context()->unaggColRefInSelectList() = valId.getItemExpr();
  //
  // ANSI 6.5 SR 4 states that,
  // "If an outer reference is in an aggregate, it must be the only column
  // reference in the aggregate."
  // As an extension (the second if-test here), we say that all column refs
  // in an aggregate must come from the same scope.
  //
  if (currScope->context()->outerColRefInAgg() ||
      ((bindScope != currScope) && currScope->context()->colRefInAgg()))
    if (currScope->context()->aggScope() != bindScope) {
      // 4006: within aggregate all col refs must be from same scope
      *CmpCommon::diags() << DgSqlCode(-4006);
      bindWA->setErrStatus();
      return this;
    }
  if (currScope->context()->inAggregate()) {
    currScope->context()->colRefInAgg() = TRUE;
    currScope->context()->aggScope() = bindScope;	// outer OR local/curr
  }
  // If the column reference is an outer reference, add it to the outer
  // references list unless the outer reference is in an aggregate.  If it's
  // in an aggregate, the aggregate will be added to the outer references list
  // when the aggregate node has been bound.
  //
  if (bindScope != currScope) {
    if (currScope->context()->inAggregate())
      currScope->context()->outerColRefInAgg() = TRUE;
    else
      currScope->addOuterRef(valId);
  }

  if (bindScope != currScope) 
  {
    //Paramaters and outer references are not supported with rank function.
    if (currScope->context()->inTDFunction())
    {
      *CmpCommon::diags() << DgSqlCode(-4369);
      bindWA->setErrStatus();
      return this;
    }
    //Paramaters and outer references in the PARTITION BY or ORDER BY clause of a window function are not supported.
    if (currScope->context()->inOlapOrderBy() || 
        currScope->context()->inOlapPartitionBy())
    {
      *CmpCommon::diags() << DgSqlCode(-4391);
      bindWA->setErrStatus();
      return this;
    }
  }
  //4391

  BindUtil_UpdateNameLocForColRef(bindWA, getColRefNameObj(), xcnmEntry,
				  getParent());
  if (!currScope->context()->inComputedColumnExpr())
    bindWA->markAsReferencedColumn(xcnmEntry->getColumnDesc());

  bindSelf(bindWA);
  return valId.getItemExpr();
} // ColReference::bindNode()

// -----------------------------------------------------------------------
// member functions for class ConstValue
// -----------------------------------------------------------------------

ItemExpr *ConstValue::bindNode(BindWA *bindWA)
{
  if (nodeIsBound())
    return getValueId().getItemExpr();
  const NAType *type = synthTypeWithCollateClause(bindWA);
  if (!type) return this;

  // Fabricate a name for the constant such that its type prefixes the value.
  NAString typeName(type->getTypeSQLname(), bindWA->wHeap());
  size_t len = typeName.length();

  // If numeric constant, allocate space to hold the scale identifier.
  // Scale is implicit for exact numeric value and is not stored
  // with the constant value. So it is needed to differentiate between
  // two constants which 'look' the same except for their scale.
  // For example, 2 and .2 are both smallint, with length of 1,
  // still are different constants.
  char scale_val[4];			// max 2 digits of scale + 1 for null
  char *scale_buf = NULL;
  size_t scale_len = 0;
  if (type->getTypeQualifier() == NA_NUMERIC_TYPE) {
    scale_buf = scale_val;
    str_itoa(((NumericType *)type)->getScale(), scale_buf);
    scale_len = strlen(scale_buf);
  }

  size_t value_len = getStorageSize();

  char *buf = new char[len + scale_len + 2*value_len + 1];
  memset(buf,0, len + scale_len + 2*value_len +1);
  memcpy(buf,typeName.data(),len);

  if (scale_buf) {
    memcpy(&buf[len], scale_buf, scale_len);
    len += scale_len;
  }

  // Now encode the actual value into the fabricated name such that no
  // null bytes appear (because the name will be used as a hash key
  // and RogueWave will use C string comparison) --
  // so we precede every value byte with a tag byte.

  char *bufp = &buf[len];
  char *valp = (char *)value_;
  len += 2*value_len;
  while (value_len--)
  {
    if (*valp)
    {
      *bufp++ = 'n';		// tag byte
      *bufp++ = *valp++;
    }
    else
    {
      *bufp++ = 'z';		// tag byte
      *bufp++ = 'z';		// embedded null does not appear!
      valp++;
    }
  }

  buf[len++] = '\0';
  NAString fabricatedName(buf,len,bindWA->wHeap());
  delete [] buf;
  ItemExpr * result = ItemExpr::bindUserInput(bindWA,type,fabricatedName);
  ConstValue* cv = dynamic_cast<ConstValue*>(result);
  CURRENTQCACHE->getHQC()
             ->collectBinderRetConstVal4HQC(this, cv);
             
  return result;
} // ConstValue::bindNode()

// -----------------------------------------------------------------------
// member functions for class DefaultSpecification
// -----------------------------------------------------------------------

ItemExpr *DefaultSpecification::bindNode(BindWA *bindWA)
{
  if (nodeIsBound())
    return getValueId().getItemExpr();

  // If immediately contained in an Insert, and binding the source VALUES list
  BindScope   *scope   = bindWA->getCurrentScope();
  BindContext *context = scope->context();
  if (context->inInsert() &&
      context->updateOrInsertScope() == scope &&
      context->counterForRowValues()) {

    Insert *insert = (Insert *)context->updateOrInsertNode();
    if (insert &&
        insert->getOperatorType() == REL_UNARY_INSERT &&
        insert->canBindDefaultSpecification()) {

      const char *defaultValueStr =
	insert->getColDefaultValue(bindWA, *context->counterForRowValues());

      // If column has NO DEFAULT, then getColDefaultValue() emitted error -4107
      // and set bindWA errstatus.
      if (!defaultValueStr) return NULL;

      // The DEFAULT specification replaces itself with a ConstValue
      // whose value is the default value for the column corresponding
      // to this position in the source tuple and target column list.  E.g.,
      //   INSERT INTO T(C,B,A) VALUES(1,2,DEFAULT)
      // the DEFAULT == position 3 == *context->counterForRowValues()
      // and getColDefaultValue(3) gets the default literal for column A.
      //
      // After this, the DefaultSpecification node is not seen again.
      //

      // Set the special parser flag to allow IDENTITY as a function.

      ULng32 savedParserFlags = Get_SqlParser_Flags (0xFFFFFFFF);
      Set_SqlParser_Flags(ALLOW_VOLATILE_SCHEMA_IN_TABLE_NAME);

      Parser parser(bindWA->currentCmpContext());

      ItemExpr *defaultValueExpr =
        parser.getItemExprTree(defaultValueStr);

      Assign_SqlParser_Flags (savedParserFlags);

      // It is possible to have a SQL/MP default value that SQL/MX
      // cannot parser.  In these case SQL/MX is not compatible with
      // SQL/MP and an error is reported.
      //
      if(!defaultValueExpr)
        {
          bindWA->setErrStatus();
          return NULL;
        }

      ItemExpr *boundExpr = NULL;

      boundExpr = defaultValueExpr->bindNode(bindWA);

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

      if (defaultValueExpr->getOperatorType() == ITM_SEQUENCE_VALUE)
        {
          insert->setSystemGeneratesIdentityValue(TRUE);
        }

      // Remember the fact that the literal used to be a DEFAULT spec
      if (boundExpr->getOperatorType() == ITM_CONSTANT)
        ((ConstValue *)boundExpr)->setWasDefaultSpec();

      boundExpr->setWasDefaultClause(TRUE);

      setValueId(boundExpr->getValueId());
      return getValueId().getItemExpr();
    }
  }

  // 4096 A DEFAULT specification is allowed only when simply contained
  //	  in the VALUES list of an INSERT.
  *CmpCommon::diags() << DgSqlCode(-4096);
  bindWA->setErrStatus();
  return NULL;

} // DefaultSpecification::bindNode()

// -----------------------------------------------------------------------
// member functions for class SleepFunction 
// -----------------------------------------------------------------------

ItemExpr *SleepFunction::bindNode(BindWA *bindWA)
{

  if (bindWA->inDDL() && (bindWA->inCheckConstraintDefinition()))
  {
	StmtDDLAddConstraintCheck *pCkC = bindWA->getUsageParseNodePtr()
                                    ->castToElemDDLNode()
                                    ->castToStmtDDLAddConstraintCheck();
    *CmpCommon::diags() << DgSqlCode(-4131);
    bindWA->setErrStatus();
    return this;
  }

  if (nodeIsBound())
    return getValueId().getItemExpr();
  const NAType *type = synthTypeWithCollateClause(bindWA);
  if (!type) return this;

  ItemExpr * ie = ItemExpr::bindUserInput(bindWA,type,getText());
  if (bindWA->errStatus())
    return this;

  // add this value id to BindWA's input function list.
  bindWA->inputFunction().insert(getValueId());

  return ie;
} // SleepFunction::bindNode()

// -----------------------------------------------------------------------
// member functions for class UnixTimestamp
// -----------------------------------------------------------------------

ItemExpr *UnixTimestamp::bindNode(BindWA *bindWA)
{

  if (bindWA->inDDL() && (bindWA->inCheckConstraintDefinition()))
  {
	StmtDDLAddConstraintCheck *pCkC = bindWA->getUsageParseNodePtr()
                                    ->castToElemDDLNode()
                                    ->castToStmtDDLAddConstraintCheck();
    *CmpCommon::diags() << DgSqlCode(-4131);
    bindWA->setErrStatus();
    return this;
  }

  if (nodeIsBound())
    return getValueId().getItemExpr();
  const NAType *type = synthTypeWithCollateClause(bindWA);
  if (!type) return this;

  ItemExpr * ie = ItemExpr::bindUserInput(bindWA,type,getText());
  if (bindWA->errStatus())
    return this;

  // add this value id to BindWA's input function list.
  bindWA->inputFunction().insert(getValueId());

  return ie;
} // UnixTimestamp::bindNode()

// -----------------------------------------------------------------------
// member functions for class CurrentTimestamp
// -----------------------------------------------------------------------

ItemExpr *CurrentTimestamp::bindNode(BindWA *bindWA)
{

  if (bindWA->inDDL() && (bindWA->inCheckConstraintDefinition()))
  {
	StmtDDLAddConstraintCheck *pCkC = bindWA->getUsageParseNodePtr()
                                    ->castToElemDDLNode()
                                    ->castToStmtDDLAddConstraintCheck();
    *CmpCommon::diags() << DgSqlCode(-4131);
    bindWA->setErrStatus();
    return this;
  }

  if (nodeIsBound())
    return getValueId().getItemExpr();
  const NAType *type = synthTypeWithCollateClause(bindWA);
  if (!type) return this;
  //
  // ANSI requires that multiple references to CURRENT_DATE, CURRENT_TIME,
  // or CURRENT_TIMESTAMP in the same SQL statement be effectively evaluated
  // simultaneously, so all CurrentTimestamp functions are treated as input
  // values and are given the same value id.
  //
  ItemExpr * ie = ItemExpr::bindUserInput(bindWA,type,getText());
  if (bindWA->errStatus())
    return this;

  // add this value id to BindWA's input function list.
  bindWA->inputFunction().insert(getValueId());

  return ie;
} // CurrentTimestamp::bindNode()


//++Triggers

// -----------------------------------------------------------------------
// member functions for class UniqueExecuteId
// -----------------------------------------------------------------------
ItemExpr *UniqueExecuteId::bindNode(BindWA *bindWA)
{
  if (nodeIsBound())
    return getValueId().getItemExpr();
  const NAType *type = synthesizeType();
  if (!type) {
    bindWA->setErrStatus();
    return this;
  }

  //
  // functions of this type are treated as input
  // values and are given the same value id.
  //
  ItemExpr * ie = ItemExpr::bindUserInput(bindWA,type,getText());
  if (bindWA->errStatus())
    return this;

  // add this value id to BindWA's input function list.
  bindWA->inputFunction().insert(getValueId());

  return ie;
} // UniqueExecuteId::bindNode()

// -----------------------------------------------------------------------
// member functions for class GetTriggersStatus
// -----------------------------------------------------------------------
ItemExpr *GetTriggersStatus::bindNode(BindWA *bindWA)
{
  if (nodeIsBound())
    return getValueId().getItemExpr();
  const NAType *type = synthesizeType();
  if (!type) {
    bindWA->setErrStatus();
    return this;
  }

  //
  // functions of this type are treated as input
  // values and are given the same value id.
  //
  ItemExpr * ie = ItemExpr::bindUserInput(bindWA,type,getText());
  if (bindWA->errStatus())
    return this;

  // add this value id to BindWA's input function list.
  bindWA->inputFunction().insert(getValueId());

  return ie;
} // GetTriggersStatus::bindNode()

//--Triggers

// -----------------------------------------------------------------------
// member functions for class CurrentTimestampRunning
// -----------------------------------------------------------------------

ItemExpr *CurrentTimestampRunning::bindNode(BindWA *bindWA)
{
  if (nodeIsBound())
    return getValueId().getItemExpr();
  const NAType *type = synthTypeWithCollateClause(bindWA);
  if (!type) return this;

  ItemExpr *boundExpr = ItemExpr::bindNode(bindWA);
  return boundExpr;
} // CurrentTimestampRunning::bindNode()

// -----------------------------------------------------------------------
// member functions for class Parameter
// -----------------------------------------------------------------------

ItemExpr *Parameter::bindNode(BindWA *bindWA)
{
  if (nodeIsBound())
  {
    OperatorTypeEnum opTyp = getOperatorType();
    // All user inputs are treated as outer references in the current scope.
    bindWA->getCurrentScope()->addOuterRef(getValueId());
    return getValueId().getItemExpr();
  }
  if (bindWA->getCurrentScope()->context()->inTDFunction())
  {
    //Paramaters and outer references are not supported with rank function.
    *CmpCommon::diags() << DgSqlCode(-4369);
    bindWA->setErrStatus();
    return this;
  }
  if (bindWA->getCurrentScope()->context()->inOlapOrderBy() ||
      bindWA->getCurrentScope()->context()->inOlapPartitionBy())
  {
    //Paramaters and outer references in the PARTITION BY or ORDER BY clause of a window function are not supported.
    *CmpCommon::diags() << DgSqlCode(-4391);
    bindWA->setErrStatus();
    return this;
  }

  if ( bindWA->bindingCall () && ITM_DYN_PARAM == getOperatorType ())
  {
    // Are we in a trigger?
    // This needs to be ahead of trying access host areas
    if (bindWA->isInTrigger()) {
      *CmpCommon::diags() <<  DgSqlCode(-11046);
      bindWA->setErrStatus ();
      return this;
    }

    // We do not allow Rowsets in CALL yet.
    if ( bindWA->getHostArraysArea()->hasDynamicRowsets() )
    {
      *CmpCommon::diags() <<
      DgSqlCode(-UDR_BINDER_NO_ROWSET_IN_CALL);
      bindWA->setErrStatus ();
      return this;
    }

    setPMOrdPosAndIndex(bindWA->getCurrParamMode(),
                        (Int32) bindWA->getCurrOrdinalPosition(),
                        getHVorDPIndex());
    bindWA->addHVorDPToSPDups(this);

    if (!bindWA->getDupWarning() && bindWA->checkMultiOutSPParams(this))
    {
      *CmpCommon::diags()
        << DgSqlCode(UDR_BINDER_MULTI_HOSTVAR_OR_DP_IN_PARAMS)
        << DgString0(((DynamicParam *) this)->getName())
        << DgTableName(bindWA->getCurrSPName().getQualifiedNameAsString());

      bindWA->setDupWarning (TRUE);
    }

    // CLI support for CALL stmt OUT params
    if ( COM_INPUT_COLUMN == bindWA->getCurrParamMode () ||
         COM_INOUT_COLUMN == bindWA->getCurrParamMode () )
    {
      bindWA->getSpInParams().insert ( this );
    } // if INPUT or INOUT
    if ( COM_OUTPUT_COLUMN == bindWA->getCurrParamMode () ||
         COM_INOUT_COLUMN == bindWA->getCurrParamMode () )
    {
      // OUT param suppport, CLI will use this
      // During RelRoot::bindNode this is copied into the RelRoot's
      // private area
      bindWA->getSpOutParams().insert( this );
    } // if OUTPUT or INOUT
  } // binding a CALL statement

  const NAType *type = synthTypeWithCollateClause(bindWA);
  if (!type) return this;

  if(getOperatorType() == ITM_ROUTINE_PARAM) 
  {
      // Don't want to send the ROUTINE_PARAMs through bindUserInput
      // as they are used as fake inputs, but real outputs. Thus they
      // cannot be a UserInput
    setValueId(createValueDesc(bindWA, this, type));
    bindSelf(bindWA);
    if (bindWA->errStatus()) return this;
    return getValueId().getItemExpr();
  } else
    return ItemExpr::bindUserInput(bindWA,type,getText());
} // Parameter::bindNode()

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

ItemExpr *HostVar::bindNode(BindWA *bindWA)
{
  if (nodeIsBound())
    return getValueId().getItemExpr();

  const NAType *type = synthTypeWithCollateClause(bindWA);
  if (!type) return this;

  if ( bindWA->bindingCall ())
  {
    // Are we in a trigger
    if (bindWA->isInTrigger()) {
      *CmpCommon::diags() <<  DgSqlCode(-11046);
      bindWA->setErrStatus ();
      return this;
    }

    // No rowsets as CALL parameters yet
    if ( NA_ROWSET_TYPE == getType()->getTypeQualifier() )
    {
      *CmpCommon::diags() <<
      DgSqlCode(-UDR_BINDER_NO_ROWSET_IN_CALL);
      bindWA->setErrStatus ();
      return this;
    }

    setPMOrdPosAndIndex(bindWA->getCurrParamMode(),
                        (Int32) bindWA->getCurrOrdinalPosition(),
                        hvIndex_);
    bindWA->addHVorDPToSPDups(this);

    if (!bindWA->getDupWarning() && bindWA->checkMultiOutSPParams(this))
    {
      *CmpCommon::diags()
        << DgSqlCode(UDR_BINDER_MULTI_HOSTVAR_OR_DP_IN_PARAMS)
        << DgString0(getName())
        << DgTableName(bindWA->getCurrSPName().getQualifiedNameAsString());

      bindWA->setDupWarning(TRUE);
    }

    // CLI support for CALL stmt OUT params
    if ( COM_INPUT_COLUMN == bindWA->getCurrParamMode () ||
         COM_INOUT_COLUMN == bindWA->getCurrParamMode () )
    {
      bindWA->getSpInParams().insert ( this );
    } // if INPUT or INOUT

    if ( COM_OUTPUT_COLUMN == bindWA->getCurrParamMode () ||
         COM_INOUT_COLUMN == bindWA->getCurrParamMode () )
    {
      // OUT param suppport, CLI will use this
      // During RelRoot::bindNode this is copied into the RelRoot's
      // private area
      bindWA->getSpOutParams().insert( this );
    } // if OUTPUT or INOUT
  } // if bindingCall
  else
  {
    // We can be here during RelRoot::bindNode also. At this point
    // bindingCall () will be FALSE, but we still need to set
    // the variable's PMOrdPos etc.
    // Also, if we come here during a post-bind phase
    // and the bindWA's HVorDP list is empty, 'h' below will be NULL
    HostVar *h = (HostVar *) bindWA->getHVorDPFromSPDups (this);
    if (h)
    {
      setPMOrdPosAndIndex (h->getParamMode (),
                           h->getOrdinalPosition (),
                           h->getHVorDPIndex ());
    }
  }

  ItemExpr * ie = ItemExpr::bindUserInput(bindWA, type, getText());

  return ie;
} // HostVar::bindNode()

// -----------------------------------------------------------------------
// member functions for class RenameCol
// -----------------------------------------------------------------------

ItemExpr *RenameCol::bindNode(BindWA *bindWA)
{
  if (nodeIsBound())
    return getValueId().getItemExpr();
  //
  // Bind the child nodes.
  //
  bindSelf(bindWA);
  if (bindWA->errStatus()) return this;
 
  // We don't allow rename of MVF or Subq by default
  // If the CQD is turned on, we will allow a query like this
  // 
  // select mvf() as x from t1;
  //
  // and we will silently pick the first output from the mvf() to be
  // associated with x. Any other outputs from the mvf() will be ingored.
  //
  // similarly for a subquery:
  // 
  // select (select a,b from t1) as x, b from t2;
  //
  // will associate the a from the subquery's select list with x, and b will
  // quitely be ignored.


  if ( CmpCommon::getDefault(ALLOW_RENAME_OF_MVF_OR_SUBQ) == DF_OFF )
  {

    // Since UDFs can return more than one output, we have to check for that
    // here, and if it does, disallow it. 
    if (child(0)->getOperatorType() == ITM_USER_DEF_FUNCTION)
    {
      UDFunction *udf = (UDFunction *) child(0)->castToItemExpr();
      if (udf->getRoutineDesc() && 
          udf->getRoutineDesc()->getOutputColumnList().entries() > 1)
      {
        *CmpCommon::diags() << DgSqlCode(-4478);
        bindWA->setErrStatus();
        return this;
      }
    
    } 
    // Since we now allow Subqueries to return multiple columns, 
    // we have to check for that here, and if it does, disallow it. 
    else if (child(0)->getOperatorType() == ITM_ROW_SUBQUERY)
    {
  
      Subquery *subq = (Subquery *) child(0)->castToItemExpr();
      if (subq->getSubquery()->getDegree() > 1)
      {
        *CmpCommon::diags() << DgSqlCode(-4477);
        bindWA->setErrStatus();
        return this;
      }
    }
  }

  setValueId(child(0)->getValueId());
  return getValueId().getItemExpr();
}

// -----------------------------------------------------------------------
// member functions for class PositionFunc
// -----------------------------------------------------------------------

ItemExpr *PositionFunc::bindNode(BindWA *bindWA)
{
  if (nodeIsBound())
    return getValueId().getItemExpr();

  // this will bind/type-propagate all children.
  bindChildren(bindWA);
  if (bindWA->errStatus()) 
    return this;

  // update both operands if case insensitive comparions
  // are to be done.
  const NAType &type1 = 
    child(0)->castToItemExpr()->getValueId().getType();
  const NAType &type2 = 
    child(1)->castToItemExpr()->getValueId().getType();
  
  if ((type1.getTypeQualifier() == NA_CHARACTER_TYPE) &&
      (type2.getTypeQualifier() == NA_CHARACTER_TYPE))
    {
      const CharType &cType1 = (CharType&)type1;
      const CharType &cType2 = (CharType&)type2;
      
      NABoolean doCIcomp = 
	((cType1.isCaseinsensitive()) && (cType2.isCaseinsensitive()));
      
      ItemExpr * newChild = NULL;
      if ((doCIcomp) &&
	  (NOT cType1.isUpshifted()))
	{
	  newChild = new (bindWA->wHeap()) Upper(child(0));
	  setChild(0, newChild);
	}
      
      if ((doCIcomp) &&
	  (NOT cType2.isUpshifted()))
	{
	  newChild = new (bindWA->wHeap()) Upper(child(1));
	  setChild(1, newChild);
	}
    }

  // if third(start position) and fourth(occurence) child operands are
  // specified, then convert them to INT.
  if (child(2))
    {
      ValueId vid3 = child(2)->getValueId();
      SQLInt si(NULL);

      vid3.coerceType(si, NA_NUMERIC_TYPE);

      const NAType &type3 = vid3.getType();

      if (type3.getTypeQualifier() != NA_NUMERIC_TYPE) {
        // 4053 The third operand of a POSITION function must be numeric.
        *CmpCommon::diags() << DgSqlCode(-4053) << DgString0(getTextUpper());
        bindWA->setErrStatus();
        return NULL;
      }
      
      if (((NumericType&)type3).getScale() != 0) {
        // 4047 The third operand of a POSITION function must have a scale of 0.
        *CmpCommon::diags() << DgSqlCode(-4047) << DgString0(getTextUpper());
        bindWA->setErrStatus();
        return NULL;
      }

      if (type3.getFSDatatype() != REC_BIN32_SIGNED)
        {
          ItemExpr * newChild =
            new (bindWA->wHeap())
            Cast(child(2), 
                 new (bindWA->wHeap())
                 SQLInt(bindWA->wHeap(), TRUE, type3.supportsSQLnull()));
          newChild = newChild->bindNode(bindWA);
          setChild(2, newChild);
        }
    }

  if (child(3))
    {
      ValueId vid4 = child(3)->getValueId();
      SQLInt si(NULL);

      vid4.coerceType(si, NA_NUMERIC_TYPE);

      const NAType &type4 = vid4.getType();

      if (type4.getTypeQualifier() != NA_NUMERIC_TYPE) {
        // 4053 The third operand of a POSITION function must be numeric.
        *CmpCommon::diags() << DgSqlCode(-4053) << DgString0(getTextUpper());
        bindWA->setErrStatus();
        return NULL;
      }
      
      if (((NumericType&)type4).getScale() != 0) {
        // 4047 The third operand of a POSITION function must have a scale of 0.
        *CmpCommon::diags() << DgSqlCode(-4047) << DgString0(getTextUpper());
        bindWA->setErrStatus();
        return NULL;
      }

      if (type4.getFSDatatype() != REC_BIN32_SIGNED)
        {
          ItemExpr * newChild =
            new (bindWA->wHeap())
            Cast(child(3), 
                 new (bindWA->wHeap())
                 SQLInt(bindWA->wHeap(), TRUE, type4.supportsSQLnull()));
          newChild = newChild->bindNode(bindWA);
          setChild(3, newChild);
        }
    }

  BuiltinFunction::bindNode(bindWA);
  if (bindWA->errStatus()) 
    return this;

  return getValueId().getItemExpr();
} // PositionFunc::bindNode()

// -----------------------------------------------------------------------
// member functions for class Replace
// -----------------------------------------------------------------------

ItemExpr *Replace::bindNode(BindWA *bindWA)
{
  if (nodeIsBound())
    return getValueId().getItemExpr();

  // this will bind/type-propagate all children.
  bindChildren(bindWA);
  if (bindWA->errStatus()) 
    return this;

  // update both operands if case insensitive comparions
  // are to be done.
  const NAType &type1 = 
    child(0)->castToItemExpr()->getValueId().getType();
  const NAType &type2 = 
    child(1)->castToItemExpr()->getValueId().getType();
  
  if ((type1.getTypeQualifier() == NA_CHARACTER_TYPE) &&
      (type2.getTypeQualifier() == NA_CHARACTER_TYPE))
    {
      const CharType &cType1 = (CharType&)type1;
      const CharType &cType2 = (CharType&)type2;
      
      NABoolean doCIcomp = 
	((cType1.isCaseinsensitive()) && (cType2.isCaseinsensitive()));
      
      ItemExpr * newChild = NULL;
      /*      if ((doCIcomp) &&
	  (NOT cType1.isUpshifted()))
	{
	  newChild = new (bindWA->wHeap()) Upper(child(0));
	  setChild(0, newChild);
	}
	*/

      if ((doCIcomp) &&
	  (NOT cType2.isUpshifted()))
	{
	  newChild = new (bindWA->wHeap()) Upper(child(1));
	  setChild(1, newChild);
	  
	}
    }

  BuiltinFunction::bindNode(bindWA);
  if (bindWA->errStatus()) 
    return this;

  return getValueId().getItemExpr();
} // Replace::bindNode()

// -----------------------------------------------------------------------
// member functions for class CharLength
// -----------------------------------------------------------------------

ItemExpr *CharLength::bindNode(BindWA *bindWA)
{
  if (nodeIsBound())
    return getValueId().getItemExpr();

  // this will bind/type-propagate all children.
  bindChildren(bindWA);
  if (bindWA->errStatus()) 
    return this;

  const NAType &type1 = 
    child(0)->castToItemExpr()->getValueId().getType();
  
  if (type1.getTypeQualifier() == NA_NUMERIC_TYPE)
    {
      ItemExpr * newChild = new (bindWA->wHeap()) 
        Trim((Int32)Trim::TRAILING,
             new (PARSERHEAP()) SystemLiteral(" ", WIDE_(" ")), child(0));

      setChild(0, newChild);
    }

  BuiltinFunction::bindNode(bindWA);
  if (bindWA->errStatus()) 
    return this;
  
  return getValueId().getItemExpr();
} // CharLength::bindNode()

// -----------------------------------------------------------------------
// member functions for class OctetLength
// -----------------------------------------------------------------------

ItemExpr *OctetLength::bindNode(BindWA *bindWA)
{
  if (nodeIsBound())
    return getValueId().getItemExpr();

  // this will bind/type-propagate all children.
  bindChildren(bindWA);
  if (bindWA->errStatus()) 
    return this;

  const NAType &type1 = 
    child(0)->castToItemExpr()->getValueId().getType();
  
  if (type1.getTypeQualifier() == NA_NUMERIC_TYPE)
    {
      ItemExpr * newChild = new (bindWA->wHeap()) 
        Trim((Int32)Trim::TRAILING,
             new (PARSERHEAP()) SystemLiteral(" ", WIDE_(" ")), child(0));

      setChild(0, newChild);
    }

  BuiltinFunction::bindNode(bindWA);
  if (bindWA->errStatus()) 
    return this;
  
  return getValueId().getItemExpr();
} // OctetLength::bindNode()

// -----------------------------------------------------------------------
// member functions for class SelIndex
// -----------------------------------------------------------------------

ItemExpr *SelIndex::bindNode(BindWA *bindWA)
{
  if (nodeIsBound())
    return getValueId().getItemExpr();
  //
  // Bind the child nodes.
  //
  bindSelf(bindWA);
  if (bindWA->errStatus())
    return this;

  BindScope * currScope = bindWA->getCurrentScope();
  if ((currScope->context()->inGroupByClause()) ||
      (currScope->context()->inHavingClause()))
    {
      // the real value id pointing to the select list element
      // will be set during phase2 of groupby ordinal transformation.
      // See RelRoot::transformGroupByWithOrdinalPhase2().

      // create a dummy type of type unknown.
      NAType * type = new(bindWA->wHeap()) SQLUnknown(bindWA->wHeap());
      setValueId(createValueDesc(bindWA, this, type));

      if ((bindWA->inViewDefinition()) &&
	  (getExprInGrbyClause()))
	{
	  // this will expand names used in the groupby clause
	  // so they could be used during view create processing.
	  getExprInGrbyClause()->bindNode(bindWA);
	}

      return this;
    }

  //
  // Check that the select list index is within the allowable range.
  //
  const CollIndex i = getSelIndex();
  RETDesc *resultTable = bindWA->getCurrentScope()->getRETDesc();
  if (i < 1 || i > resultTable->getDegree())
  {
    // 4007: select list index out of range.
    *CmpCommon::diags() << DgSqlCode(-4007) << DgInt0(i) << DgInt1(resultTable->getDegree());
    bindWA->setErrStatus();
    return this;
  }
  setValueId(resultTable->getValueId(i - 1));
  return getValueId().getItemExpr();
}

// -----------------------------------------------------------------------
// member functions for class Subquery
// -----------------------------------------------------------------------

ItemExpr *Subquery::bindNode(BindWA *bindWA)
{
  if (nodeIsBound())
    return getValueId().getItemExpr();

  BindContext *context = bindWA->getCurrentScope()->context();

  // See if UDF_SUBQ_IN_AGGS_AND_GBYS is enabled. It is enabled if the
  // default is ON, or if the default is SYSTEM and ALLOW_UDF is ON.
  NABoolean udfSubqInAggGrby_Enabled = FALSE;
  DefaultToken udfSubqTok = CmpCommon::getDefault(UDF_SUBQ_IN_AGGS_AND_GBYS);
  if ((udfSubqTok == DF_ON) ||
      (udfSubqTok == DF_SYSTEM))
    udfSubqInAggGrby_Enabled = TRUE;
  
  if (!udfSubqInAggGrby_Enabled)
  {

    if (context->inAggregate()) {
      // 4008: A subquery is not allowed inside an aggregate.
      *CmpCommon::diags() << DgSqlCode(-4008);
      bindWA->setErrStatus();
      return this;
    }
  
    // a subquery is not allowed to be referenced as a group by ordinal.
    if (context->inGroupByOrdinal()) {
      *CmpCommon::diags() << DgSqlCode(-4185);
      bindWA->setErrStatus();
      return NULL;
    }
  }

  // subquery is not allowed in the join predicate of Full Outer Join.
  if (context->inJoinPred() &&
      (context->inJoin()->getOperatorType() == REL_FULL_JOIN))
    {
      *CmpCommon::diags() << DgSqlCode(-4339);
      bindWA->setErrStatus();
      return NULL;
    }

  if (getArity() && checkForSQLnullChild(bindWA, this)) return this;

  // Bind the child nodes.
  //
  bindSelf(bindWA);
  if (bindWA->errStatus())
    return this;

  //
  // Bind the subquery tree
  //
  context = bindWA->getCurrentScope()->context();
  NABoolean orig = context->inSubquery();
  NABoolean origRow = context->inRowSubquery();
  context->inSubquery() = TRUE;
  context->inRowSubquery() = (isARowSubquery());

  tableExpr_ = getSubquery()->bindNode(bindWA);

  context->inSubquery() = orig;
  context->inRowSubquery() = origRow;
  if (bindWA->errStatus())
    return this;
  
  // QSTUFF
  // we don't allow streams in subqueries.
  if (tableExpr_->getGroupAttr()->isStream()){
    *CmpCommon::diags() << DgSqlCode(-4168);
    bindWA->setErrStatus();
    return this;
  }
  
  // we don't allow destructive selects or embedded inserts in subqueries.
  // The SeqGenSubquery updating the SG Table and returning the
  // next value is an exception. 
  if (1 && 
      ((tableExpr_->getGroupAttr()->isEmbeddedUpdateOrDelete()) 
       || (tableExpr_->getGroupAttr()->isEmbeddedInsert())         
       || (bindWA->isEmbeddedIUDStatement()))
      )
    {
      NAString type;
      if (tableExpr_->getGroupAttr()->isEmbeddedUpdate())
	type = "UPDATE";
      else
	{
	  if (tableExpr_->getGroupAttr()->isEmbeddedInsert())
	    type = "INSERT";
	  else
	    type = "DELETE";
	}
      
      *CmpCommon::diags()
	<< DgSqlCode(-4167)
	<< DgString0(type);
      bindWA->setErrStatus();
      return this;
    }
  // QSTUFF
  
  // Create a ValueDesc for this ItemExpr.
  //
  const NAType *type = synthTypeWithCollateClause(bindWA);
  if (!type) return this;
  setValueId(createValueDesc(bindWA, this, type));
  return getValueId().getItemExpr();
} // Subquery::bindNode()

ItemExpr *QuantifiedComp::bindNode(BindWA *bindWA)
{
  if (nodeIsBound())
    return getValueId().getItemExpr();

  ItemExpr *boundExpr = Subquery::bindNode(bindWA);
  if (bindWA->errStatus()) 
    return this;

  // if left child is incompatible with right child, insert a node
  // to convert left to right.
  if ((CmpCommon::getDefault(ALLOW_INCOMPATIBLE_OPERATIONS) == DF_ON) &&
      (createdFromINlist()))
    {
      const NAType &type1 = 
	child(0)->castToItemExpr()->getValueId().getType();
      const NAType &type2 = 
	getSubquery()->selectList()->castToItemExpr()->getValueId().getType();

      if (type1.getTypeQualifier() != type2.getTypeQualifier())
	{
	  if ((type1.getTypeQualifier() == NA_CHARACTER_TYPE) &&
	      (type2.getTypeQualifier() == NA_NUMERIC_TYPE))
	    {
	      // only supporting char lhs at this time. Add more later.
	      ItemExpr * newChild =
		new (bindWA->wHeap())
		Cast(child(0),
		     new (bindWA->wHeap())
		     SQLDoublePrecision(bindWA->wHeap(),
			  child(0)->castToItemExpr()->getValueId().
			  getType().supportsSQLnull()));
	      newChild = newChild->bindNode(bindWA);
	      if(bindWA->errStatus()) 
		return NULL;
	      
	      if(newChild)
		setChild(0, newChild);
	    }
	  else
	    {
	      emitDyadicTypeSQLnameMsg(-4041, type1, type2);
	      bindWA->setErrStatus();
	      return NULL;
	    }
	}
    }  

  return boundExpr;
}

ItemExpr *Substring::bindNode(BindWA *bindWA)
{
  if (nodeIsBound())
    return getValueId().getItemExpr();

  // this will bind/type-propagate all children.
  bindChildren(bindWA);
  if (bindWA->errStatus()) 
    return this;

  if (CmpCommon::getDefault(MODE_SPECIAL_1) == DF_ON)
    {
      // allow substring on exact, binary numeric operand with scale of zero.
      const NAType &type1 = 
	child(0)->castToItemExpr()->getValueId().getType();

      if (type1.getTypeQualifier() == NA_NUMERIC_TYPE)
	{
	  NumericType &nType = (NumericType&)type1;
	  if ((nType.isExact()) &&
	      (nType.getScale() == 0) &&
	      (nType.isSimpleType()))
	    {
	      Parser parser(bindWA->currentCmpContext());
	      char buf[1000];
	      
	      Lng32 dlen =
		nType.getDisplayLength(nType.getFSDatatype(),
				       nType.getNominalSize(),
				       nType.getPrecision(),
				       nType.getScale(),
				       0);
	      ItemExpr * parseTree ;
	      // right justify the string representation of numeric operand 
	      // and then do substring.
	      if (getNumChildren() == 2)
	      {
		sprintf(buf, "SUBSTRING(SPACE(%d - CHAR_LENGTH(CAST(@A1 AS VARCHAR(%d)))) || CAST(@A1 AS VARCHAR(%d)), @A2)",
		      dlen, dlen, dlen);
		parseTree = parser.getItemExprTree(buf, strlen(buf), BINDITEMEXPR_STMTCHARSET, 2, child(0), child(1));
	      }
	      else
	      {
		CMPASSERT(getNumChildren() == 3);
		sprintf(buf, "SUBSTRING(SPACE(%d - CHAR_LENGTH(CAST(@A1 AS VARCHAR(%d)))) || CAST(@A1 AS VARCHAR(%d)), @A2, @A3)",
			dlen, dlen, dlen);
		parseTree = parser.getItemExprTree(buf, strlen(buf), BINDITEMEXPR_STMTCHARSET, 3, child(0), child(1), child(2));
	      }
	      
	      parseTree = parseTree->bindNode(bindWA);
	      if (bindWA->errStatus()) 
		return NULL;
	      else
		return parseTree;
	    }
	}
      else if (type1.getTypeQualifier() == NA_DATETIME_TYPE)
	{
	  // Convert stored date to numeric and then substring.
	  // Numeric value of a date is: (YYYY-1900)*10000 + (MM*100) + DD
	  // Then cast this numeric value as CHAR(7) before doing 
	  // the substring.
	  DatetimeType &dtType = (DatetimeType&)type1;
	  if (dtType.getPrecision() == SQLDTCODE_DATE)
	    {
	      // Cast DATE to INT
	      ItemExpr * newChild =
		new (bindWA->wHeap())
		Cast(child(0), 
		     new (bindWA->wHeap())
		     SQLInt(bindWA->wHeap(), TRUE, type1.supportsSQLnull()));
	      newChild = newChild->bindNode(bindWA);

	      // Cast INT to CHAR(7).
	      newChild =
		new (bindWA->wHeap())
		Cast(newChild,
		     new (bindWA->wHeap())
		     SQLChar(bindWA->wHeap(), 7, type1.supportsSQLnull()));
	      newChild = newChild->bindNode(bindWA);
	      setChild(0, newChild);
	    }
	}
    }

  // Substring inherits from BuiltinFunction .. Function .. ItemExpr.
  BuiltinFunction::bindNode(bindWA);
  if (bindWA->errStatus()) 
    return this;

  return getValueId().getItemExpr();
}

// -----------------------------------------------------------------------
// member functions for class Exists
// -----------------------------------------------------------------------

ItemExpr *Exists::bindNode(BindWA *bindWA)
{
  BindContext *context = bindWA->getCurrentScope()->context();
  NABoolean orig = context->inExistsPredicate();
  context->inExistsPredicate() = TRUE;
  ItemExpr *boundExpr = Subquery::bindNode(bindWA);
  context->inExistsPredicate() = orig;
  return boundExpr;
} // Exists::bindNode()



// -----------------------------------------------------------------------
// member functions for class UDFunction
// -----------------------------------------------------------------------
ItemExpr *UDFunction::bindNode(BindWA *bindWA)
{
  NARoutine *udf = 0, *udfAction = 0;

  if (nodeIsBound())
    return getValueId().getItemExpr();

  ItemExpr *boundExpr = NULL;

  // IS req 8: Check if UDF is in certain query contexts.
  // No error check on return, these use NAList/NACollection and NAAbort if out of range.
  BindScope *curScope = bindWA->getCurrentScope();
  BindContext *curContext = bindWA->getCurrentScope()->context();
  curContext->inUDFunction() = TRUE;

  // UDFs not allowed in argument list of a sequence function.
  if (curContext->inSequenceFunction())
  {
    *CmpCommon::diags() << DgSqlCode(-4461)
                        << DgString0(functionName_.getExternalName());
    bindWA->setErrStatus();
    return this;
  }

  // UDFs not allowed in ORDER BY clause of OLAP window function.
  if (((curScope->getSequenceNode() &&
         ((RelRoot *)curScope->getSequenceNode())->getHasOlapFunctions()) ||
       (curScope->getSequenceNode() &&
         ((RelSequence *)curScope->getSequenceNode())->getHasOlapFunctions()) ||
       (curContext->inOtherSequenceFunction())) &&
      curContext->inOrderBy())
  {
    *CmpCommon::diags() << DgSqlCode(-4462)
                        << DgString0(functionName_.getExternalName());
    bindWA->setErrStatus();
    return this;
  }
  // UDFs not allowed in ON clause of a full outer join.
  if (curContext->inJoin() &&
      curContext->inJoin()->isFullOuterJoin() &&
      curContext->inJoinPred())
  {
    *CmpCommon::diags() << DgSqlCode(-4463)
                        << DgString0(functionName_.getExternalName());
    bindWA->setErrStatus();
    return this;
  }
  // UDFs not allowed in WHEN clause of an AFTER trigger.
  if (bindWA->getUsageParseNodePtr() &&
      bindWA->getUsageParseNodePtr()->getOperatorType() == DDL_CREATE_TRIGGER)
  {
    StmtDDLCreateTrigger *trigger = (StmtDDLCreateTrigger *) bindWA->getUsageParseNodePtr();
    if (trigger->isAfter() && 
        (curContext->inPredicate() || curContext->inRangePred()))
    {
      *CmpCommon::diags() << DgSqlCode(-4464)
                        << DgString0(functionName_.getExternalName());
      bindWA->setErrStatus();
      return this;
    }
  }
  // UDFs not allowed in WHERE clause of an DELETE [FIRST N] query.
  if (curContext->deleteNode() && curContext->inWhereClause() && curContext->firstN())
  {
    *CmpCommon::diags() << DgSqlCode(-4465)
                        << DgString0(functionName_.getExternalName());
    bindWA->setErrStatus();
    return this;
  }
  // UDFs not allowed in WHERE clause of an UPDATE [FIRST N] query.
  if (curContext->inUpdate() && curContext->inWhereClause() && curContext->firstN())
  {
    *CmpCommon::diags() << DgSqlCode(-4466)
                        << DgString0(functionName_.getExternalName());
    bindWA->setErrStatus();
    return this;
  }
  // UDFs not allowed in WHERE clause of an INSERT .. SELECT [FIRST N] query.
  if (bindWA->isInsertSelectStatement()) 
  {
    BindScope *prevScope = bindWA->getPreviousScope(curScope);  
    if (prevScope) // Must use previous scope for insert/select.
    {
      BindContext *prevContext = prevScope->context();
      if (prevContext && 
          curContext->inWhereClause() && prevContext->firstN())
      {
        *CmpCommon::diags() << DgSqlCode(-4473)
                            << DgString0(functionName_.getExternalName());
        bindWA->setErrStatus();
        return this;
      }
    }
  }
  // UDFs not allowed in check constraint.
  if (curContext->inCheckConstraint())
  {
    *CmpCommon::diags() << DgSqlCode(-4470)
                        << DgString0(functionName_.getExternalName());
    bindWA->setErrStatus();
    return this;
  }
  
  // Check for NARoutine for this UDF in cache (NARoutineDB)
  NAString func = functionName_.getExternalName();
  NAString action = "";
  NAHeap *heap = CmpCommon::statementHeap();

  NAString dftUdfLoc = ActiveSchemaDB()->getDefaults().getValue(UDF_METADATA_SCHEMA);
  NAString dftUdfCat, dftUdfSch;

  ComObjectName functionName1(functionName_);
  ComObjectName functionName2(functionName_);

  size_t index = dftUdfLoc.first('.');
  if (index > 1 && index < dftUdfLoc.length()) {
    dftUdfCat = dftUdfLoc(0, index);
    dftUdfSch = dftUdfLoc(index+1, dftUdfLoc.length()-index-1);
    if (dftUdfSch.first('.') != NA_NPOS) // A delimited name was used, such that
    {                                     // we can't be sure assign was correct.
       dftUdfCat = CmpSeabaseDDL::getSystemCatalogStatic().data(); 
       dftUdfSch = SEABASE_UDF_SCHEMA; // If there is a '.' in Sch, set to well known cat.sch
                                       // Without this the QualifiedName creation in NARoutineDBKey
    }                                  // below may assert.
  }


  // Find UDF in cache or metadata
  TrafDesc *udfMetadata = NULL;
  TrafDesc *oldUdfMetadata = NULL; // not used, just to get code to compile
  CmpSeabaseDDL cmpSBD(heap);

  try 
  {
    if (CmpCommon::getDefault(COMP_BOOL_191) == DF_OFF) // temporary switch for
    {                                                   // real and old metadata.
      Int32 catSchNameChosen = 1; // Will be set to 1 or 2 based on
                                // which cat.sch action is found in.


      // Set functionName1 to current cat.sch - unless cat.sch specified.
      // If catalog not specified, add current catalog to name.
      if (functionName1.getCatalogNamePartAsAnsiString() == "")
        functionName1.setCatalogNamePart(
          bindWA->getDefaultSchema().getCatalogName());
      // If schema not specified, add current schema to name.
      if (functionName1.getSchemaNamePartAsAnsiString() == "")
        functionName1.setSchemaNamePart(
          bindWA->getDefaultSchema().getSchemaName());
       // Set functionName2 to default UDF cat.sch.
      functionName2.setCatalogNamePart(dftUdfCat);
      functionName2.setSchemaNamePart(dftUdfSch);

      QualifiedName functionName1AsQualName(functionName1, heap);
      QualifiedName functionName2AsQualName(functionName2, heap);
    // in open source, only the SEABASE catalog is allowed.
    // Return an error if some other catalog is being used.
    if ((NOT functionName1AsQualName.isSeabase()) && (NOT functionName1AsQualName.isHive()))
      {
	*CmpCommon::diags()
	  << DgSqlCode(-1002)
	  << DgCatalogName(functionName1AsQualName.getCatalogName());
	
	bindWA->setErrStatus();
	return NULL;
      }

      // Check the NARoutine cache for NARoutine first.
      // 1. Look for UDF in current or specified cat/schema.
      
      NARoutineDBKey functionKey1(functionName1, heap);
      udf = bindWA->getSchemaDB()->getNARoutineDB()->get(bindWA, &functionKey1);
      catSchNameChosen = 1;

      // 2. If UDF not found in cache w/ current or spec'd cat.sch AND
      //    cat.sch NOT specified in query, look in cache for default cat.sch.
      if (NULL == udf && 
          functionName_.getSchemaNamePartAsAnsiString() == "")
      {
        // Look in NARoutine cache with default cat.sch.
        NARoutineDBKey functionKey2(functionName2, heap);
        udf = bindWA->getSchemaDB()->getNARoutineDB()->get(bindWA, &functionKey2);
        catSchNameChosen = 2;
      }
      
      // 3. If UDF not found in NARoutine cache, look up in metadata.
      if (NULL == udf)
      {
        udfMetadata =  cmpSBD.getSeabaseRoutineDesc(
				       functionName1AsQualName.getCatalogName(),
				       functionName1AsQualName.getSchemaName(),
				       functionName1AsQualName.getObjectName());
        catSchNameChosen = 1;
      }
      // 4. If UDF not found in current or specified cat.sch AND
      //    cat.sch NOT specified in query, look up in metadata with
      //    default cat.sch.
      if (NULL == udf && NULL == udfMetadata && 
          functionName_.getSchemaNamePartAsAnsiString() == "")
      {
        // Look for UDF in default cat.schema if cat.sch not 
        // spec'd on command line.
        udfMetadata =  cmpSBD.getSeabaseRoutineDesc(
				       functionName2AsQualName.getCatalogName(),
				       functionName2AsQualName.getSchemaName(),
				       functionName2AsQualName.getObjectName());

        catSchNameChosen = 2;
      }
      if (catSchNameChosen == 1) 
      { 

        functionName_.setCatalogNamePart(functionName1.getCatalogNamePartAsAnsiString());
        functionName_.setSchemaNamePart(functionName1.getSchemaNamePartAsAnsiString());
      }
      else
      { 
        functionName_.setCatalogNamePart(functionName2.getCatalogNamePartAsAnsiString());
        functionName_.setSchemaNamePart(functionName2.getSchemaNamePartAsAnsiString());
      }
      // Remove -1001 through -1004 (not found errors) - the binder reports these.
      CollIndex i;
      for (Int32 err=-1004; err<=-1001; err++)
        while ((i=CmpCommon::diags()->returnIndex(err)) != NULL_COLL_INDEX)
          CmpCommon::diags()->deleteError(i);
      // Remove -1389 (not found error) 
      while ((i=CmpCommon::diags()->returnIndex(-1389)) != NULL_COLL_INDEX)
        CmpCommon::diags()->deleteError(i);
     }
    else 
    {
        *CmpCommon::diags() << DgSqlCode(-4222)
                      << DgString0("UDF");
        bindWA->setErrStatus();
        return this;
        // we are now guaranteed that COMP_BOOL_191 is OFF for closed source
    }
  }
  catch ( ... )
  {
    // Print out something??
    //CatExceptionTypeEnum eType = e.getExceptionType();
    *CmpCommon::diags() << DgSqlCode(-4457)
                        << DgString0(functionName_.getExternalName())
                        << DgString1("Exception occurred during UDF lookup");
  }
  // Set expanded UDF name for triggers, MVs, ...
  ParNameLocList *pNameLocList = bindWA->getNameLocListPtr();
  if (pNameLocList)
  {
    ParNameLoc *pNameLoc
      = pNameLocList->getNameLocPtr(getNamePosOfUdfInQuery());
    if (pNameLoc)
      pNameLoc->setExpandedName(functionName_.getExternalName());
  }

  if (NULL == udf) // UDF/UUDF not found in NARoutine cache.
  {
    // IS req 5: Check if UDF/UUDF name found in metadata, if not output error(s).
    if ((CmpCommon::getDefault(COMP_BOOL_191) == DF_OFF &&
         NULL == udfMetadata)                              ||
        (CmpCommon::getDefault(COMP_BOOL_191) == DF_ON &&
         (NULL == oldUdfMetadata 
          ) ))
    {
      *CmpCommon::diags() << DgSqlCode(-4450)
                          << DgString0(functionName_.getExternalName());
      bindWA->setErrStatus();
      return this;
    }

    // IS req 6: Check ROUTINE_TYPE column of ROUTINES table.
    // Emit error if invalid type.
    ComRoutineType udrType = COM_UNKNOWN_ROUTINE_TYPE;
    if (CmpCommon::getDefault(COMP_BOOL_191) == DF_OFF)
      {
        udrType = udfMetadata->routineDesc()->UDRType ;
      }

    if (udrType != COM_SCALAR_UDF_TYPE &&
        udrType != COM_UNIVERSAL_UDF_TYPE)
    {
      *CmpCommon::diags() << DgSqlCode(-4457)
                          << DgString0(functionName_.getExternalName())
                          << DgString1("Only scalar or universal user-defined functions are supported");
      bindWA->setErrStatus();
      return this;
    }

    NAHeap *routineHeap;
    if (bindWA->getSchemaDB()->getNARoutineDB()->cachingMetaData()) 
    {
      // Create new heap for this NARoutine.  The reason for this is to be able to
      // track the size of this object.  Otherwise we might use the context heap.
      const Lng32 size = 16 * 1024;  // The initial size
      routineHeap = new CTXTHEAP NAHeap("NARoutine Heap", (NAHeap *)CTXTHEAP, size);
    }
    // If not caching, put NARoutine on statement heap.
    else routineHeap=CmpCommon::statementHeap(); 

    // IS req 3, 7.3. Instantiate NARoutine object.  
    // NARoutine data members will be assigned from udfMetadata.
    Int32 errors=0;
    NAString empty="";
    if (CmpCommon::getDefault(COMP_BOOL_191) == DF_OFF)
      udf = new (routineHeap)
                   NARoutine(functionName_,
                             udfMetadata, 
                             bindWA,
                             errors,
                             routineHeap);
    if ( NULL == udf || errors != 0)
    {
      bindWA->setErrStatus();
      return this;
    }

    // Add NARoutine to the NARoutineDB cache.
    if (bindWA->getSchemaDB()->getNARoutineDB()->cachingMetaData()) 
      bindWA->getSchemaDB()->getNARoutineDB()->put(udf);
  } // if (NULL == udf ) -- NARoutine not in cache.

  // Create the routineDesc and initialize it with the NARoutine for the
  // UDF. Action proceesing handled later.  See below.
  RoutineDesc *rdesc = new (bindWA->wHeap()) RoutineDesc(bindWA, udf); 
  if (rdesc == NULL)
  {
     *CmpCommon::diags() << DgSqlCode(-4457)
                         << DgString0(functionName_.getExternalName())
                         << DgString1("Internal Error creating the RoutineDesc");
     bindWA->setErrStatus();
     return this;
  }
  setRoutineDesc(rdesc); // Assign the RoutineDesc pointer in UDFunction.

  // Ideally it would be nice to call Function::bindNode() right here
  // to bind the children (inputs) to the function, but that would 
  // invoke UDFunction::synthType() which requires the outputs to be
  // setup. Instead we will make sure the inputs are bound by the call
  // to setInOrOutParam()

  // Create item list for input arguments to be stored.
  // In the Action case we might need more, but they will be 
  // allocated when we insert into the List.
  ItemExprList * inParams = new(CmpCommon::statementHeap())
                                ItemExprList(udf->getInParamCount(), 
                                             CmpCommon::statementHeap());
    Int32 minUdfInputs = 0;
    Int32 maxUdfInputs = udf->getInParamCount();
    // Check input and output arguments from the ROUTINE_PARAMS table.
    // Get expected num of inputs by checking if an argument is optional.
    // If inputs from ROUTINE_PARAMS do not match input arguments from 
    // function, emit error.
    //
    NABoolean foundOptional = FALSE;
    for (Int32 i=0; i<maxUdfInputs; i++)
    {
      // Check if parameter specified as optional.  'i' should never
      // be out of range - based on assignment, however if it is, getColumn()
      // via NAList::operator[] will issue NAAbort().
      if (udf->getInParams()[i]->isOptional())
        foundOptional = TRUE;
      else if (foundOptional == TRUE)
      {
        // An optional argument cannot be followed by a required argument.
        *CmpCommon::diags() << DgSqlCode(-4457)
                            << DgString0(functionName_.getExternalName())
                            << DgString1("User-defined functions cannot have an optional argument followed by a required argument");
        bindWA->setErrStatus();
        return this;
      }
      // If input not optional, then it is required, so increment minimum expected inputs.
      else
        minUdfInputs++;
    }

    // Make sure that outputs are not optional.
    for (Int32 i=0; i<udf->getOutParamCount(); i++)
    {
      // Check to make sure output not spec'd as optional.  'i' should never
      // be out of range - based on assignment, however if it is, getColumn()
      // via NAList::operator[] will issue NAAbort().
      if (udf->getOutParams()[i]->isOptional())
      {
        // An optional argument MUST be an input.
        *CmpCommon::diags() << DgSqlCode(-4457)
                            << DgString0(functionName_.getExternalName())
                            << DgString1("User-defined functions cannot have an optional argument defined as an output");
        bindWA->setErrStatus();
        return this;
      }
    }

  // IS req 7.2. If this is not a UUDR, then check that inputs = expected.
  // Cannot use the rdesc to check for UUDF as the action hasn't been 
  // created yet.  For universal functions, do not check inputs/outputs
  // from the metadata - we rely only on action metadata info.
  if (!udf->isUniversal())
  {
    // Non-deterministic UDFs not allowed in the query expression of a 
    // CREATE VIEW statement with CHECK OPTION.  Note that this check is 
    // somewhat redundant since a CHECK OPTION must be used with an updatable
    // view, but a UDF cannot be part of an updatable view.  However, this
    // latter condition is only found at execution time.  Action determinism
    // is checked later.
    if (!udf->isDeterministic() &&
        bindWA->getUsageParseNodePtr() &&
        bindWA->getUsageParseNodePtr()->getOperatorType() == DDL_CREATE_VIEW)
    {
      StmtDDLCreateView *view = (StmtDDLCreateView *) bindWA->getUsageParseNodePtr();
      if (view->isWithCheckOptionSpecified())
      {
        *CmpCommon::diags() << DgSqlCode(-4467)
                            << DgString0(functionName_.getExternalName());
        bindWA->setErrStatus();
        return this;
      }
    }

    // IS req 8: Multi-valued (MV) UDFs are not allowed in TRANSPOSE clause.
    if (curContext->inTransposeClause() &&  
        udf->getOutParamCount() > 1 )
    {
      *CmpCommon::diags() << DgSqlCode(-4468)
                          << DgString0(functionName_.getExternalName());
      bindWA->setErrStatus();
      return this;
    }

    // IS req 7: Process information from the ROUTINE_PARAMS, 
    // REPLICAS, and TEXT metadata tables.

    // Set up routine params in routine descriptor.
    for (Int32 i=0; i<udf->getInParamCount(); i++)
    {
      // This will update the input params lists in the rdesc to 
      // reflect those of the UDF.
      if (rdesc->createRoutineParam(bindWA, i, udf, 
                                    &(rdesc->getUDFInParamColumnList()), 
                                    &(rdesc->getUDFOutputColumnList()) ) == FALSE)
      {
        bindWA->setErrStatus();
        return FALSE;
      }
    }

    // Bind all the children, so we will know their output degree.
    for (Int32 i=0; i<getNumChildren(); i++)
    {
      child(i).getPtr()->bindNode(bindWA);  // If 'i' out of range, will CMPASSERT.
      if (bindWA->errStatus()) return FALSE;
    }
    // Process UDF input arguments.  If an input argument is a subquery or UDF,
    // it may have multiple outputs.  In that case, we add to the inputs of the
    // UDF here by creating ValueIdProxy class for each added argument.
    Int32 numInputs = 0;
    for (Int32 i=0; i<getNumChildren(); i++)
    {
      ItemExpr *cmdArg = child(i).getPtr(); // If 'i' out of range, will CMPASSERT.

      // Function arguments are in descending order.
      Int32 childOutputDegree = child(i).getPtr()->getOutputDegree();
      for (Int32 j=0; j<childOutputDegree; j++)
      {
        if (childOutputDegree == 1) // The argument only represents one input.
          //setInOrOutParam(rdesc, cmdArg, numInputs, COM_INPUT_COLUMN, bindWA); 
          setInOrOutParam(rdesc, cmdArg, numInputs, COM_INPUT_COLUMN, inParams, bindWA); 
        else
        {
          // We create a ValueIdProxy for each element in the subquery's
          // select list or for each output parameter of a multi-valued UDF. 
          // The first one of these will be marked to be transformed. This 
          // allows us to get the correct degree of statements containing 
          // MV UDFs or subqueries with degree > 1 at bind time. 
          ValueIdProxy *proxyOutput = 
            new (CmpCommon::statementHeap())
                 ValueIdProxy(cmdArg->getValueId(), 
                              cmdArg->getOutputItem(j)->getValueId(),
                              j, j==0 /* transform first derived child */ );
          //setInOrOutParam(rdesc, proxyOutput, numInputs+j,
          setInOrOutParam(rdesc, proxyOutput, numInputs+j,
                          COM_INPUT_COLUMN, inParams, bindWA);
        }
        
        if (bindWA->errStatus()) return this;
      }
      numInputs += childOutputDegree;
    }

    // Check that number of inputs to UDF is correct.
    if (numInputs < minUdfInputs || 
        numInputs > maxUdfInputs)
    {
      *CmpCommon::diags() << DgSqlCode(-4452)
                          << DgString0(functionName_.getExternalName())
                          << DgInt0(minUdfInputs)
                          << DgInt1(getNumChildren());
      bindWA->setErrStatus();
      return this;
    }

    // IS req 7.2. Check that there is at least one output parameter
    // specified by metadata.
    if (udf->getOutParamCount() == 0)
    {
      *CmpCommon::diags() << DgSqlCode(-4457)
                          << DgString0(functionName_.getExternalName())
                          << DgString1("User-defined functions must have at least one registered output value");
      bindWA->setErrStatus();
      return this;
    }
    else 
    {
        // Check output arguments against information in the COLS table.
       for (Int32 i=0; i<udf->getOutParamCount(); i++)
       {   
         // This will update the output params lists in the rdesc to 
         // reflect those of the UDF.
         if (rdesc->createRoutineParam(bindWA, i+maxUdfInputs, udf, 
                                       &(rdesc->getUDFInParamColumnList()), 
                                       &(rdesc->getUDFOutputColumnList())) == FALSE)
         {
           bindWA->setErrStatus();
           return this;
         }
         // Function arguments are in descending order.
         setInOrOutParam(rdesc, rdesc->getOutputColumnList()[i].getItemExpr(), 
                         i, COM_OUTPUT_COLUMN, inParams, bindWA); 
         if (bindWA->errStatus()) return this;
       }
    }
  } // end if (!udf->isUniversal() 


  //
  // Proceed to save the UDF referenced name.
  // Obtain the UDF usages list.
  // But, first check to see if this UDF reference already exists in the UDF Info List.
  //
 
  if (bindWA->getUsageParseNodePtr())
  {
    LIST(OptUDFInfo *) *udfList = NULL;
    
    switch (bindWA->getUsageParseNodePtr()->getOperatorType())
    {
      case DDL_CREATE_TRIGGER:
      {
        udfList = &bindWA->getUDFList();
    	break;
      }
      case DDL_CREATE_VIEW:
      {
        // Set the UDF list for view processing
        StmtDDLCreateView *view = (StmtDDLCreateView *) bindWA->getUsageParseNodePtr();
        CMPASSERT(view);
        udfList = &view->getUDFList();
    	break;
      }
      case DDL_CREATE_MV:
      {
        // Set the UDF list for materialized view processing
        StmtDDLCreateMV *mv = (StmtDDLCreateMV *) bindWA->getUsageParseNodePtr();
        CMPASSERT(mv);
        udfList = &mv->getUDFList();
    	break;
      }
      default:
    	break;
    }
    
    if (udfList != NULL)
    {
      OptUDFInfo *udfInfo = NULL;
      bool isUDFReferenced = false;
      ULng32 numUdfs = udfList->entries();
      
      for (ULng32 udfIndex = 0; udfIndex < numUdfs; udfIndex++)
        if ((*udfList)[udfIndex]->getUDFExternalName().compareTo(functionName_.getExternalName()) == 0)
        {
          isUDFReferenced = true;
          break;
        }

      // If this is a new UDF reference, create and save on list
      if (!isUDFReferenced)
      {
        OptUDFInfo *udfInfo = new (bindWA->wHeap()) OptUDFInfo(udf->getRoutineID(), 
                                                               functionName_, 
                                                               bindWA->wHeap());
        udfList->insert(udfInfo);
      }
    }  
  }

  // Since our inParams list now accurately reflects our real inputs,
  // we need to update the children's array as it no longer reflects 
  // reality. For example a UDF with a T.* input, would at this point
  // have the real columns that will be passed to the UDF at runtime in
  // the inParams list, but the children array only contains the T.* entry.
  // Since T.* never gets bound, it causes trouble if anyone tries to get 
  // the valueId or type from that child later on, so we get rid of it.

  // At this point the children represents the parameters that will
  // be passed to the actual function during execution.
  // inputVars_ contains the uncasted inputs that nodes above us in 
  // the tree can produce..

  children().clear();


  for (UInt32 paramPos=0; paramPos<inParams->entries(); paramPos++)
    {
  
      children().insertAt(paramPos, inParams->at(paramPos));
    }

  // Save off a copy of the chilren array 
  ARRAY(ExprValueId) copyOfChildren(HEAP);
  for (Int32 i=0; i< getArity(); i++)
    copyOfChildren.insertAt(i, child(i));

  ItemExpr *retExpr = Function::bindNode(bindWA);

  // Now check to see if Function::bindNode() made any changes to the children
  // if so we need to update our inputVars array.

  // Make sure the number of parameters didn't change
  CCMPASSERT( copyOfChildren.entries() == getArity() );

  for (Int32 i=0; i < getArity(); i++)
  {
    // If Function::bindNode() changed the child, update our inputVars 
    if (child(i)->castToItemExpr() != copyOfChildren[i]->castToItemExpr())
    {
      // If the new child still contains the old valueId, we don't need to
      // do anything, else we have to remove the original child value from
      // the inputVars and add in the new one. If the new one is a  CAST,
      // we are going to use the child of the CAST as the input value that
      // will be used as characteristic input for the IsolatedScalarUDF.
      if (! child(i)->castToItemExpr()->referencesTheGivenValue(
                    copyOfChildren[i]->getValueId()), TRUE)
      {
        if (inputVars_.contains(copyOfChildren[i]->getValueId()))
          inputVars_ -= copyOfChildren[i]->getValueId();
        else if ((copyOfChildren[i]->getOperatorType() == ITM_CAST) &&
                 (inputVars_.contains(copyOfChildren[i]->child(0)->getValueId())))
          inputVars_ -= copyOfChildren[i]->child(0)->getValueId();
        else
          CCMPASSERT(0); // do we have a multilevel CAST??

        if ((child(i)->getOperatorType() == ITM_CAST) ) 
          inputVars_ +=  child(i)->child(0)->getValueId();
        else
          inputVars_ +=  child(i)->getValueId();
      }
    }
  }
    
  curContext->inUDFunction() = FALSE;
 
  // add the routine to the UdrStoiList.  The UdrStoi list is used
  // to check valid privileges
  LIST(OptUdrOpenInfo *) udrList = bindWA->getUdrStoiList ();

  // See if UDF already exists
  NABoolean udrReferenced = FALSE;
  for (ULng32 stoiIndex = 0; stoiIndex < udrList.entries(); stoiIndex++)
  {
    if ( 0 ==
         udrList[stoiIndex]->getUdrName().compareTo(
                           udf->getSqlName().getQualifiedNameAsAnsiString()
                                                  )
       )
    {
      udrReferenced = TRUE;
      break;
    }
  }

  // UDF has not been defined, go ahead an add one
  if ( FALSE == udrReferenced )
  {
    SqlTableOpenInfo *udrStoi = new (bindWA->wHeap ())SqlTableOpenInfo ();
    udrStoi->setAnsiName ( convertNAString(
                           udf->getSqlName().getQualifiedNameAsAnsiString(),
                           bindWA->wHeap ())
                         );

    OptUdrOpenInfo *udrOpenInfo = new (bindWA->wHeap ())
      OptUdrOpenInfo( udrStoi
                    , udf->getSqlName().getQualifiedNameAsAnsiString()
                    , udf
                    );
    bindWA->getUdrStoiList().insert(udrOpenInfo);
  }

  delete inParams; // clean up the memory used 

  return retExpr;
} // UDFunction::bindNode()

void
UDFunction::setInOrOutParam (RoutineDesc *routine,
                             ItemExpr *argument,
                             Int32 position,
                             ComColumnDirection paramMode,
                             ItemExprList *inParams,
                             BindWA *bindWA)
{
  // This function is based on CallSP::setInOrOutParam().
  CollIndex ordinalPosition = position;

  if (argument == NULL)
  {
     *CmpCommon::diags() << DgSqlCode(-4457)
                         << DgString0(functionName_.getExternalName())
                         << DgString1("Internal error in setInOrOutParam()");
      bindWA->setErrStatus();
      return;
  } // if argument == NULL


  // Obtain the type of the function argument by binding it.
  ItemExpr *boundExpr = argument->bindNode(bindWA);
  if (bindWA->errStatus()) return;

  // If this is supposed to be an input, make checks.
  if (COM_INPUT_COLUMN == paramMode)
  {
     if (routine == NULL)
     {
       *CmpCommon::diags() << DgSqlCode(-4457)
                           << DgString0(functionName_.getExternalName())
                           << DgString1("Internal error in setInOrOutParam(): routine is NULL.");
        bindWA->setErrStatus();
        return;
     } // if routine == NULL

     const ValueIdList &formalParams = routine->getInParamColumnList();
     if (ordinalPosition >= formalParams.entries())
     {
       *CmpCommon::diags() << DgSqlCode(-4457)
                           << DgString0(functionName_.getExternalName())
                           << DgString1("Internal error in setInOrOutParam(): index position out of range.");
        bindWA->setErrStatus();
        return;
     } // if routine == NULL

     // Obtain the type that was read from metadata.
     const ValueId column = formalParams[ordinalPosition];
     const NAType &paramType = column.getType();

     ValueId inputTypeId = boundExpr->getValueId();

     // If function argument is character type, get detailed info.
     if (inputTypeId.getType().getTypeQualifier() == NA_CHARACTER_TYPE)
     {
       const CharType* stringLiteral = (CharType*)&(inputTypeId.getType());

       if(CmpCommon::wantCharSetInference())
       {
         const CharType* desiredType =
           CharType::findPushDownCharType(((CharType&)paramType).getCharSet(),
                                       stringLiteral, 0);
         if ( desiredType )
           inputTypeId.coerceType((NAType&)*desiredType, NA_CHARACTER_TYPE);
       }
     }
     // Get final type of function argument.
     const NAType &inputType = inputTypeId.getType();

   
    // Do type checking,
    // If it is not a compatible type report an error
    if (!( NA_UNKNOWN_TYPE == inputType.getTypeQualifier() ||
           paramType.isCompatible(inputType) ||
           boundExpr->getOperatorType() == ITM_DYN_PARAM
          )
      )
    {
      // Error, data types dont match
      if (!routine->isUUDFRoutine())
        // Create error for user-defined function.
        *CmpCommon::diags() << DgSqlCode(-4455)
                            << DgInt0((Lng32) ordinalPosition+1)
                            << DgString0(functionName_.getExternalName())
                            << DgString1(inputType.getTypeSQLname(TRUE))
                            << DgString2(paramType.getTypeSQLname(TRUE));
      else
      {
        // Create error for action.
        NAString actionName = "UNKNOWN";
        if (routine->getActionNARoutine() &&
            routine->getActionNARoutine()->getActionName())
          actionName = routine->getActionNARoutine()->getActionName()->data();
        *CmpCommon::diags() << DgSqlCode(-4456)
                            << DgInt0((Lng32) ordinalPosition+1)
                            << DgString0(actionName.data())
                            << DgString1(functionName_.getExternalName())
                            << DgString2(inputType.getTypeSQLname(TRUE))
                            << DgString3(paramType.getTypeSQLname(TRUE));
      }
      bindWA->setErrStatus();
      return;
    } // if NOT isCompatible

    // Store valueId in list.
    inputVars_ += boundExpr->getValueId();

    if (!hasSubquery_)
      hasSubquery_ = boundExpr->containsSubquery();
    
    if ( ! ( paramType == inputType) )
    {
      // Create a Cast node to cast the argument from the function call
      // to the type specified by the metadata (if the two are compatible.)
      Cast *castExpr = new (bindWA->wHeap()) Cast(boundExpr, &paramType,
                                                ITM_CAST, TRUE);
      ItemExpr *boundCast = castExpr->bindNode(bindWA);
      if (bindWA->errStatus()) return;
      // Add to input ItemExpr list.
      inParams->insert(boundCast);
    } 
    else
    {
      // Add to input ItemExpr list.
      inParams->insert(boundExpr);
    }

  } else if (COM_OUTPUT_COLUMN == paramMode)
  {
    outputVars_.insert (boundExpr->getValueId ());
  } // if OUTPUT

} // UDFunction::setInOrOutParam()

// -----------------------------------------------------------------------
// member functions for class ValueIdUnion
// -----------------------------------------------------------------------

ItemExpr *ValueIdUnion::bindNode(BindWA *bindWA)
{
  if (nodeIsBound())
    return getValueId().getItemExpr();

  if ((CmpCommon::getDefault(ALLOW_INCOMPATIBLE_OPERATIONS) == DF_ON) &&
      (isTrueUnion()) &&
      (entries() == 2))
    {
      // allow CHAR || NUMERIC, NUMERIC || CHAR
      const NAType &type1 = getLeftSource().getType();
      const NAType &type2 = getRightSource().getType();

      Int32 srcChildIndex = -1;
      Int32 otherChildIndex = -1;
      Int32 convType = -1;
      if ((type1.getTypeQualifier() == NA_NUMERIC_TYPE) &&
	  (type2.getTypeQualifier() == NA_CHARACTER_TYPE))
	{
	  // convert leftSource(NUMERIC) to char type
	  srcChildIndex = 0;
	  otherChildIndex = 1;
	  if ((getSource(otherChildIndex).getItemExpr()->getOperatorType() == 
	       ITM_DATEFORMAT) &&
	      (((DateFormat*)(getSource(otherChildIndex).getItemExpr()))->getDateFormat() ==
	       DateFormat::TIME_FORMAT_STR))
	    {
	      // in special1 mode, if one side of a union is numeric and
	      // other side is FORMAT clause, then the numeric needs to
	      // be formatted as well.
	      convType = 1;
	    }
	  else
	    convType = 2;
	}
      else if ((type1.getTypeQualifier() == NA_CHARACTER_TYPE) &&
	       (type2.getTypeQualifier() == NA_NUMERIC_TYPE))
	{
	  // convert rightSource(NUMERIC) to char type
	  srcChildIndex = 1;
	  otherChildIndex = 0;

	  if ((getSource(otherChildIndex).getItemExpr()->getOperatorType() == 
	       ITM_DATEFORMAT) &&
	      (((DateFormat*)(getSource(otherChildIndex).getItemExpr()))->getDateFormat() ==
	       DateFormat::TIME_FORMAT_STR))
	    {
	      // in special1 mode, if one side of a union is numeric and
	      // other side is FORMAT clause, then the numeric needs to
	      // be formatted as well.
	      convType = 1;
	    }
	  else
	    convType = 2;
	}
      
      if (srcChildIndex >= 0)
	{
	  ItemExpr * newChild = NULL;
	  if (convType == 1)
	    {
	      DateFormat * df =
		((DateFormat*)getSource(otherChildIndex).getItemExpr());
	      ConstValue * cv = (ConstValue*)(df->child(1)->castToItemExpr());
	      newChild =
		new (bindWA->wHeap())
		Format(getSource(srcChildIndex).getItemExpr(),
		       NAString((char*)(cv->getConstValue()), 
				cv->getStorageSize()),
		       FALSE);
	      
	    }
	  else if (convType == 2)
	    {
	      Lng32 dLen = 0;

	      NumericType &nType = (NumericType&)
		getSource(srcChildIndex).getType();
	      dLen =
		nType.getDisplayLength(nType.getFSDatatype(),
				       nType.getNominalSize(),
				       nType.getPrecision(),
				       nType.getScale(),
				       0);
	      
	      newChild =
		new (bindWA->wHeap())
		Cast(getSource(srcChildIndex).getItemExpr(),
		     new (bindWA->wHeap())
		     SQLChar(bindWA->wHeap(), dLen,
			     getSource(srcChildIndex).getType().
			     supportsSQLnull()));
	    }

	  newChild = newChild->bindNode(bindWA);
	  if (bindWA->errStatus())
	    return this;

	  setSource(srcChildIndex, newChild->getValueId());
	}
    }

  // ValueIdUnion is a direct derived subclass of ItemExpr; 
  // safe to invoke this
  ItemExpr *boundExpr = ItemExpr::bindNode(bindWA);
  if (bindWA->errStatus())
    return boundExpr;
  setResult(getValueId());
  return getValueId().getItemExpr();
} // ValueIdUnion::bindNode()

//
// This method is part of the Implicit Casting And Translation feature
// which allows the user to UNION a
// column of any supported character set with a column of any other 
// supported character set, providing that one CS can be translated
// to the other without errors by throwing in a Translate node to
// translate to the most general character set.
//
ItemExpr * ValueIdUnion::tryToDoImplicitCasting( BindWA *bindWA )
{
  const NAType *entryType ;
  CharInfo::CharSet savedMostGeneral_CS = CharInfo::UnknownCharSet;
  Int32 savedMaxLen = 0;
  NABoolean savedAllowNull = FALSE;
  NABoolean savedUpShifted = TRUE;
  NABoolean savedCaseInsensitive = TRUE;
  CharInfo::Collation savedCollation = CharInfo::DefaultCollation;

  enum {iUCS2 = 0, iISO = 1, iUTF8 = 2, iSJIS = 3, iUNK = 4};
  Int32 charsets_involved[5] = { 0, 0, 0, 0, 0 };
  CollIndex i = 0;

  //
  // Count the number of entries for each supported character set.
  // If we don't have at least two different ones, we just return.
  //
  for (i = 0; i < entries(); i++) {
     entryType = &getSource(i).getType();
     if (entryType->getTypeQualifier() == NA_CHARACTER_TYPE)
     {
        const CharType * ctI = (CharType *) entryType;
        Int16 cur_chld_cs_ndx = iUNK;

        Int16 maxLen = ctI->getMaxLenInBytesOrNAWChars();
        if ( savedMaxLen < maxLen )
             savedMaxLen = maxLen ;
        if ( ctI->supportsSQLnullLogical() )
           savedAllowNull = TRUE;
        if ( ! ctI->isUpshifted() )
           savedUpShifted = FALSE;
        if ( ! ctI->isCaseinsensitive() )
           savedCaseInsensitive = FALSE;

        switch ( ctI->getCharSet() )
        {
         case CharInfo::UNICODE :
           cur_chld_cs_ndx = iUCS2;
           if ( savedMostGeneral_CS != CharInfo::UNICODE )
           {
                savedMostGeneral_CS = CharInfo::UCS2;
                savedCollation      = ctI->getCollation();
           }
           break;
         case CharInfo::UTF8:
           cur_chld_cs_ndx = iUTF8;
           if ( ( savedMostGeneral_CS == CharInfo::UnknownCharSet ) ||
                ( savedMostGeneral_CS == CharInfo::SJIS           ) ||
                ( savedMostGeneral_CS == CharInfo::ISO88591       ) )
           {
                savedMostGeneral_CS = CharInfo::UTF8;
                savedCollation      = ctI->getCollation();
           }
           break;
         case CharInfo::SJIS:
           cur_chld_cs_ndx = iSJIS;
           if ( ( savedMostGeneral_CS == CharInfo::UnknownCharSet ) ||
                ( savedMostGeneral_CS == CharInfo::ISO88591 ) )
           {
                savedMostGeneral_CS = CharInfo::SJIS;
                savedCollation      = ctI->getCollation();
           }
           break;
         case CharInfo::ISO88591:
           cur_chld_cs_ndx = iISO;
           if ( savedMostGeneral_CS == CharInfo::UnknownCharSet )
           {
                savedMostGeneral_CS = CharInfo::ISO88591;
                savedCollation      = ctI->getCollation();
           }
           break;
         //case CharInfo::KANJI_MP:
         //case CharInfo::KSC5601_MP:
         default:
           break; // Can not translate these currently.
        }
        charsets_involved[cur_chld_cs_ndx]++;
     }
  }

  Int32 charsetsCount = 0;
  for (Int32 j = 0; j < iUNK; j++)
    if (charsets_involved[j] > 0)
      charsetsCount++;
  if ( charsetsCount <= 1) return this;
  CMPASSERT( savedMostGeneral_CS != CharInfo::UnknownCharSet ); // Shouldn't happen since charsetsCount > 1
  CMPASSERT( getValueId() == NULL_VALUE_ID ); // call this before assigning a value id

  CharType * MostGeneralType = new( bindWA->wHeap() )
                                   SQLVarChar(bindWA->wHeap(), savedMaxLen,
                                              savedAllowNull,
                                              savedUpShifted,
                                              savedCaseInsensitive,
                                              savedMostGeneral_CS,
                                              savedCollation,
                                              CharInfo::COERCIBLE,
                                              savedMostGeneral_CS
                                             );
  //
  // OK, we have entries for at least two different character sets.
  // So, we must insert some Translate nodes.  Just to keep it
  // simple, we always translate to the Most General charset
  //
  for (i = 0; i < entries(); i++) {
    entryType = &getSource(i).getType();
    if ( entryType->getTypeQualifier() == NA_CHARACTER_TYPE )
    {
        const CharType* ctI = (CharType *) entryType;
        if ( ctI->getCharSet() != savedMostGeneral_CS )
        {
           // Do Implicit Cast to the Most General Character Set
           //
           Int32 iTranslateFromTo = find_translate_type( ctI->getCharSet(),
                                                         savedMostGeneral_CS );
           if ( iTranslateFromTo == Translate::UNKNOWN_TRANSLATION )
              continue; // Just skip this entry!

           ValueId vidi = getSource(i);
           ItemExpr * newTranslateChild = NULL;
           ItemExpr * ieChild = vidi.getItemExpr();

           if ( (ieChild->getOperatorType() == ITM_CONSTANT)  &&
                ((ConstValue *)ieChild)->isNull() )  // If NULL, create new child with needed charset
           {   
              newTranslateChild = new(bindWA->wHeap()) ConstValue();
              newTranslateChild->bindNode(bindWA);
              (newTranslateChild->getValueId()).changeType(MostGeneralType);
           }   
           else // Must insert a Translate node
           {   
              newTranslateChild =
                 new (bindWA->wHeap()) Translate(vidi.getItemExpr(), iTranslateFromTo );

              newTranslateChild = newTranslateChild->bindNode(bindWA);
              if (bindWA->errStatus())
                 return this;
           }   

           changeSource(i, ValueDesc::create(newTranslateChild,
                                             MostGeneralType, bindWA->wHeap()) );
        }
     }
  }

  return this;
}

// This method returns the length of the padding string (the third argument to
// an LPAD or RPAD function, for e.g. the '00' in LPAD(<colname>, max-len, '00'))
// if the padding string is not a varchar. The method returns -2 is there is an error
// and -1 if the length is a varchar or for some other reason the length cannot
// be determined.
Int32 ZZZBinderFunction::getPadStringLength (ItemExpr* padExpr, BindWA* bindWA)
{
  Int32 padStringLength = -1;
  if (padExpr)
  {
    ItemExpr * tempPadString =
      padExpr->castToItemExpr()->bindNode(bindWA);
    if (bindWA->errStatus()) return -2;

    const NAType &typ1 = tempPadString->getValueId().getType();
    if ((typ1.getTypeQualifier() == NA_CHARACTER_TYPE) &&
        (!typ1.isVaryingLen())) {
          const CharType &ctyp1 = (CharType &) typ1;
          padStringLength = typ1.getNominalSize()/ctyp1.getBytesPerChar() ;
        }
  }
  return padStringLength ;
}

// This method returns the maximum length (the second argument to
// an LPAD or RPAD function, for e.g. the <max-len> in LPAD(<colname>, <max-len>, '00'))
// if the second argument is a constant that is not null. 
// The method returns -2 is there is an error
// and -1 if max-len is an expression or null.
Int32 ZZZBinderFunction::getPadLength (ItemExpr* padLengthExpr, BindWA* bindWA)
{
  Int32 padLengthMax = -1;
  if (padLengthExpr)
  {
    ItemExpr * tempPadLength = padLengthExpr->bindNode(bindWA);
    if (bindWA->errStatus()) return -2;

    NumericType &tempType = (NumericType&)tempPadLength->getValueId().getType();
    if(! (tempType.isExact() && tempType.getScale() <=0 ))
      {
	*CmpCommon::diags() << DgSqlCode(-4047);
	bindWA->setErrStatus();
	return -2;
      }

     NABoolean negate;
    if ((tempPadLength->getOperatorType() == ITM_CONSTANT) &&
        (tempPadLength->castToConstValue(negate)))
    {
      ConstValue * cv = tempPadLength->castToConstValue(negate);
      if (! cv->isNull())
      {
	if (cv->canGetExactNumericValue())
	{ 
	   padLengthMax = (Int32) cv->getExactNumericValue();
           if ( padLengthMax > CmpCommon::getDefaultNumeric(TRAF_MAX_CHARACTER_COL_LENGTH))
             {
               *CmpCommon::diags() << DgSqlCode(-4129)
                                   << DgString0(getTextUpper());
               bindWA->setErrStatus();
               return -2;
             } 
        }
      }
    }  // padLength is a constant
  }
  return padLengthMax ;
}

NABoolean ZZZBinderFunction::isPadWithSpace (ExprValueId& padExpr, CharInfo::CharSet cs)
{

  if ((cs != CharInfo::UNICODE)&&(cs != CharInfo::ISO88591))
  {
    return FALSE;  // the optimization to use CAST for RPAD is done
    // only for these two charsets.
  }

  if (padExpr == NULL) // if this expression is null then we pad with blank space
    return TRUE ;

  CharInfo::CharSet padExprCS = CharInfo::UnknownCharSet;
  if(!padExpr->castToItemExpr()->nodeIsBound())
  {
    CCMPASSERT(FALSE);
    return FALSE;
  }
  const NAType& padExprType = padExpr->castToItemExpr()->getValueId().getType();
  if ( padExprType.getTypeQualifier() == NA_CHARACTER_TYPE )
    padExprCS = ((CharType&) padExprType).getCharSet();
  if (padExprCS != cs)
  {
    if ( CmpCommon::getDefault(ALLOW_IMPLICIT_CHAR_CASTING) == DF_OFF )
      return FALSE; // if charset of arg1 and arg3 are different then do not
      // the RPAD to CAST optimization. We let existing code handle the error path.
  }

  if ((padExpr->castToItemExpr()->getOperatorType() == ITM_CONSTANT) &&
      (!((ConstValue *)padExpr->castToItemExpr())->getText().isNull()))
  {
     NAString padString(
       ((ConstValue *)padExpr->castToItemExpr())->getConstStr(FALSE));
     Int32 i = 0;
     NABoolean foundSingleQuote = FALSE;
     for (const char *s = padString.data(); *s; s++)
     {
       i++;
       if ((!foundSingleQuote)&&(*s != '\'')) // loop through 
         continue;  // the prefix _UCS2 or _ISO88591
       else if ((!foundSingleQuote))
       {
        foundSingleQuote = TRUE; // found the leading single quote.
        continue;
       }
       if ((i == (padString.length())) && (*s == '\'')) // trailing single quote
         continue;
       if (*s != ' ')
         return FALSE;
     }
     return foundSingleQuote;
  }
  return FALSE ;

}

// -----------------------------------------------------------------------
// member functions for class ZZZBinderFunction
// -----------------------------------------------------------------------

ItemExpr *ZZZBinderFunction::bindNode(BindWA *bindWA)
{
  Parser parser(bindWA->currentCmpContext());
  char buf[2500];
  buf[0] = 0;
  NABoolean resetRealBigNum = FALSE;

  ItemExpr *parseTree = NULL, *boundTree = NULL;

    // Need to check to see if we have any parameters that are MVFs or 
    // subqueries of degree > 1.
    // 
    // Some functions like LPAD and RPAD can take 2 or 3 parameters.
    // Here we can choose to if we are given the 2 parameter version, but
    // one of those parameters is a subquer of degree 2 or an MVF that returns
    // 2 outputs.
    
    Lng32 childDegree  = 0;
    Lng32 origArity = getArity();
    
    for (Lng32 idx = 0; idx < origArity; idx++) 
    {
      // Break when we have no more parameters
      // This can happen since we have some function with optional params.
      // getArity() may sometime return the maximum allowed, instead of actual
      // This code will also only allow that expansion to happen if the
      // subquery or MVF is the last given parameter.
      if (child(idx) == NULL) break;
      
      ItemExpr *chldExpr = child(idx)->castToItemExpr();
      switch (chldExpr->getOperatorType()) 
      {
        case ITM_ROW_SUBQUERY:
        case ITM_USER_DEF_FUNCTION:
        {
          // Need to bind the subquery to find its degree
          child(idx) = child(idx)->castToItemExpr()->bindNode(bindWA);
          if (bindWA->errStatus()) return this;
          
          Subquery *subq = (Subquery *) child(idx)->castToItemExpr();
          UDFunction * udf = (UDFunction *) child(idx)->castToItemExpr();
          Lng32 myDegree = (chldExpr->getOperatorType() == ITM_ROW_SUBQUERY) ? 
            subq->getSubquery()->getDegree() :
            udf->getRoutineDesc()->getOutputColumnList().entries(); 
          
          childDegree += myDegree;
          
          // Only allow expansion for LPAD/RPAD
          // for the two parameter case
          if ( myDegree > 1 && 
               ((getOperatorType() == ITM_LPAD) || 
                (getOperatorType() == ITM_RPAD)) &&
               origArity == 2)
          {
            // Expand the child() array
            // First shift any existing ones over
            for (Lng32 shiftIdx = origArity-1; shiftIdx > idx; shiftIdx--)
            {
              child(shiftIdx+myDegree) = child(shiftIdx);
            }
            
            ItemExprList *mDegreeList = (ItemExprList *) new(bindWA->wHeap())
              ItemExprList(child(idx)->castToItemExpr()
                           ,bindWA->wHeap());
            
            ItemExpr * ie = mDegreeList->convertToItemExpr();
            ie->bindNode(bindWA);
            if (bindWA->errStatus()) return this;
            
            ValueIdList mDegreeVlist;
            ie->convertToValueIdList(mDegreeVlist, bindWA, ITM_ITEM_LIST);
            
            for (Lng32 expIdx = 0; expIdx < myDegree; expIdx++)
            {
              
              child(idx + expIdx) = mDegreeVlist[expIdx].getItemExpr(); 
            }
            
            // bump the index to point to the next non processed param
            idx += myDegree-1;
            // We don't need to anything special to increase the arity
            // since the assignment inside the for loop above does it for
            // us. The BuiltinFunction::getArity() method looks at the number
            // of children in its child array.
            
          }
        }
        break;
        default:
          childDegree += 1;
          break;
      }
    }
    
    if ((childDegree > origArity ) && 
        (! ( childDegree == 3 && origArity == 2 && 
             ((getOperatorType() == ITM_LPAD) || 
              (getOperatorType() == ITM_RPAD))))
        )
    {
      // Error
      NAString upperFunc(getText(), bindWA->wHeap());
      
      upperFunc.toUpper();
      *CmpCommon::diags() << DgSqlCode(-4479) << DgString0(upperFunc) 
                          << DgInt1(origArity) << DgInt2(childDegree);
      bindWA->setErrStatus();
      return this;
    }

  // fix 10-040621-7164. Make sure that the child expression is not dynamic param
  // before verifying the type of the child. Otherwise, the verification may fail
  // prematually.
  //
  // This is because bindNode() is called before ::synthesizeType() and the
  // dynamic parameter's type will not be set until ::synthesizType() is called.
  // If we emit error here, then we miss the chance to assign a solid type to the
  // dynamic parameter child.

  //
  // We do not have to apply the "is dynamic param" check if only the nullness
  // We do not have to apply the "is dynamic param" check if only the nullness
  // attribute of the actual type is checked, since a dynamic paramete is
  // always nullable.
  //
  // This fix applies the "is dynamic param" check to the implementation of SQL function
  // LEFT() and RIGHT(). We do not do this for QUARTER() because a cast is needed
  // if a dynamic param is involved (see R2.0 Ref. Manual on MXCI, section Type
  // Assignment for Parameters).
  switch (getOperatorType())
    {
    case ITM_DATE_TRUNC_YEAR:
      {
        if (enforceDateOrTimestampDatatype(bindWA,0,2))
          return this;

        //Cast to DATETIME YEAR first to pick up only the year.
        strcpy(buf, "CAST(CAST(@A1 AS DATETIME YEAR) AS TIMESTAMP) ;");
      }
      break;

    case ITM_DATE_TRUNC_MONTH:
      {
        if (enforceDateOrTimestampDatatype(bindWA,0,2))
          return this;

        //Get first day of year and then add in the months.
        strcpy(buf, "CAST(CAST(@A1 AS DATETIME YEAR) AS TIMESTAMP) + "
                    "CAST(MONTH(@A1)-1 AS INTERVAL MONTH);");
      }
      break;

    case ITM_DATE_TRUNC_DAY:
      {
        if (enforceDateOrTimestampDatatype(bindWA,0,2))
          return this;

        //Note: Cast to DATE first to zero out all time fields
        strcpy(buf, "CAST(CAST(@A1 AS DATE) AS TIMESTAMP);");
      }
      break;

    case ITM_DATE_TRUNC_HOUR:
      {
        if (enforceDateOrTimestampDatatype(bindWA,0,2))
          return this;

        //Note: Cast to DATE to zero out all time fields.  Cast to TIMESTAMP in case DATE was supplied.
        strcpy(buf,
               "CAST( CAST(@A1 AS DATE) AS TIMESTAMP) + "
               "CAST( HOUR( CAST(@A1 AS TIMESTAMP) ) AS INTERVAL HOUR);");
      }
      break;

    case ITM_DATE_TRUNC_MINUTE:
      {
        if (enforceDateOrTimestampDatatype(bindWA,0,2))
          return this;

        strcpy(buf, "DATE_TRUNC('HOUR',@A1) + "
                    "CAST(MINUTE(CAST(@A1 AS TIMESTAMP)) AS INTERVAL MINUTE);");
      }
      break;

    case ITM_DATE_TRUNC_SECOND:
      {
        if (enforceDateOrTimestampDatatype(bindWA,0,2))
          return this;

        strcpy(buf, "DATE_TRUNC('MINUTE',@A1) + "
                    "CAST( CAST( SECOND(CAST(@A1 AS TIMESTAMP)) AS SMALLINT) "
                    "AS INTERVAL SECOND);");
      }
      break;

    case ITM_DATE_TRUNC_CENTURY:
      {
        if (enforceDateOrTimestampDatatype(bindWA,0,2)) 
          return this;

        strcpy(buf, "CAST( CAST(@A1 AS DATETIME YEAR) AS TIMESTAMP ) - "
                    "CAST( MOD(YEAR(@A1),100) AS INTERVAL YEAR(4)  );");
      }
      break;

    case ITM_DATE_TRUNC_DECADE:
      {
        if (enforceDateOrTimestampDatatype(bindWA,0,2)) 
          return this;

        strcpy(buf, "CAST( CAST(@A1 AS DATETIME YEAR) AS TIMESTAMP ) - "
                    "CAST( MOD(YEAR(@A1),10) AS INTERVAL YEAR(4)   );");
      }
      break;

    case ITM_DATEDIFF_YEAR:
    case ITM_TSI_YEAR:
      {
        if (enforceDateOrTimestampDatatype(bindWA,0,2))
          return this;
        if (enforceDateOrTimestampDatatype(bindWA,1,3))
          return this;
        strcpy(buf, "CAST( YEAR(@A2) - YEAR(@A1) AS INT) ;");
      }
      break;

    case ITM_DATEDIFF_MONTH:
    case ITM_TSI_MONTH:
      {
        if (enforceDateOrTimestampDatatype(bindWA,0,2))
          return this;
        if (enforceDateOrTimestampDatatype(bindWA,1,3))
          return this;
        strcpy(buf, "CAST( (YEAR(@A2)*12 + MONTH(@A2)) - "
                          "(YEAR(@A1)*12 + MONTH(@A1)) AS INT) ;");
      }
      break;

    case ITM_MONTHS_BETWEEN:
      {
        if (enforceDateOrTimestampDatatype(bindWA,0,1))
          return this;
        if (enforceDateOrTimestampDatatype(bindWA,1,2))
          return this;
	strcpy(buf, "CASE WHEN DAY (@A1) = DAY (@A2) THEN (YEAR(@A1)*12 + MONTH(@A1) - (YEAR(@A2)*12 + MONTH(@A2))) ELSE CAST((CAST(@A1 AS DATE) - CAST(@A2 AS DATE)) AS NUMERIC(18,6))/31 END");
      }
      break;

    case ITM_DATEDIFF_DAY:
    case ITM_TSI_DAY:
      {
        if (enforceDateOrTimestampDatatype(bindWA,0,2))
          return this;
        if (enforceDateOrTimestampDatatype(bindWA,1,3))
          return this;
        strcpy(buf, "CAST( CAST(@A2 AS DATE) - CAST(@A1 AS DATE) AS INT );");
      }
      break;

    case ITM_DATEDIFF_HOUR:
    case ITM_TSI_HOUR:
      {
        if (enforceDateOrTimestampDatatype(bindWA,0,2))
          return this;
        if (enforceDateOrTimestampDatatype(bindWA,1,3))
          return this;
        strcpy(buf,
              "CAST( (JULIANTIMESTAMP(DATE_TRUNC('HOUR',@A2)) - "
                    " JULIANTIMESTAMP(DATE_TRUNC('HOUR',@A1))) / (1000000*3600) "
                    " AS INT);");
      }
      break;

    case ITM_DATEDIFF_MINUTE:
    case ITM_TSI_MINUTE:
      {
        if (enforceDateOrTimestampDatatype(bindWA,0,2))
          return this;
        if (enforceDateOrTimestampDatatype(bindWA,1,3))
          return this;
        strcpy(buf,
               "CAST( (JULIANTIMESTAMP(DATE_TRUNC('MINUTE',@A2)) - "
                     " JULIANTIMESTAMP(DATE_TRUNC('MINUTE',@A1))) / (1000000*60)"
                     " AS INT);");
      }
      break;

    case ITM_DATEDIFF_SECOND:
    case ITM_TSI_SECOND:
      {
        if (enforceDateOrTimestampDatatype(bindWA,0,2))
          return this;
        if (enforceDateOrTimestampDatatype(bindWA,1,3))
          return this;
        strcpy(buf, "CAST( "
                    "(JULIANTIMESTAMP(DATE_TRUNC('SECOND',@A2)) - "
                    " JULIANTIMESTAMP(DATE_TRUNC('SECOND',@A1))) / 1000000"
                    " AS INT);");
      }
      break;

    case ITM_DATEDIFF_QUARTER:
    case ITM_TSI_QUARTER:
      {
        if (enforceDateOrTimestampDatatype(bindWA,0,2))
          return this;
        if (enforceDateOrTimestampDatatype(bindWA,1,3))
          return this;
        strcpy(buf, "CAST( ("
                    "((YEAR(@A2)*12) + ((QUARTER(@A2)-1)*3)) - "
                    "((YEAR(@A1)*12) + ((QUARTER(@A1)-1)*3)) ) / 3 AS INT);");
      }
      break;

    case ITM_DATEDIFF_WEEK:
    case ITM_TSI_WEEK:
      {
        if (enforceDateOrTimestampDatatype(bindWA,0,2))
          return this;
        if (enforceDateOrTimestampDatatype(bindWA,1,3))
          return this;
        strcpy(buf, "CAST(("
                    "(CAST(@A2 AS DATE) - CAST(DAYOFWEEK(@A2)-1 AS INTERVAL DAY)) - "
                    "(CAST(@A1 AS DATE) - CAST(DAYOFWEEK(@A1)-1 AS INTERVAL DAY))"
                    ") / 7 AS INT);");
      }
      break;

    case ITM_LAST_DAY:
      {
        if (enforceDateOrTimestampDatatype(bindWA,0,1))
          return this;

        strcpy(buf, "@A1 - CAST( DAY(@A1) -1 AS INTERVAL DAY) + INTERVAL '1' MONTH - INTERVAL '1' DAY;");
      }
      break;

    case ITM_NEXT_DAY:
      {
	// Make sure that child(0) is of date or timestamp datatype.
        if (enforceDateOrTimestampDatatype(bindWA,0,1))
          return this;

	// make sure child(1) is of string type
	ItemExpr * tempBoundTree =
	  child(1)->castToItemExpr()->bindNode(bindWA);
	if (bindWA->errStatus()) 
	  return this;

	if (tempBoundTree->getValueId().getType().getTypeQualifier() !=
	    NA_CHARACTER_TYPE)
	  {
	    *CmpCommon::diags() << DgSqlCode(-4116) << DgString0(getTextUpper());
	    bindWA->setErrStatus();
	    return NULL;
	  }

	strcpy(buf, "@A1 + CAST( MOD( CASE WHEN UPPER(@A2) = 'MONDAY' THEN -5 WHEN UPPER(@A2) = 'TUESDAY' THEN -4 WHEN UPPER(@A2) = 'WEDNESDAY' THEN -3 WHEN UPPER(@A2) = 'THURSDAY' THEN -2 WHEN UPPER(@A2) = 'FRIDAY' THEN -1 WHEN UPPER(@A2) = 'SATURDAY' THEN  0 WHEN UPPER(@A2) = 'SUNDAY' THEN  1 ELSE NULL END -  DAYOFWEEK(@A1), 7) + 7 AS INTERVAL DAY);");
      }
      break;

    case ITM_YEARWEEK:
      {
        // human-readable week format, 100*year + week
        strcpy(buf, "CAST( (YEAR(@A1) * 100 + WEEK(@A1)) AS NUMERIC(6,0));");
      }
      break;

    case ITM_YEARWEEKD:
      {
        // dense week format, 54*year + 0-based week
        // (see week function documentation, week value can range from 1 to 54)
        strcpy(buf, "CAST( (YEAR(@A1) * 54 + (WEEK(@A1) - 1)) AS NUMERIC(6,0));");
      }
      break;

    case ITM_COALESCE:
      {
	bindChildren(bindWA);
	if (bindWA->errStatus()) 
	  return this;

	ExprValueId eVid(child(0)->castToItemExpr());
	ItemExprTreeAsList coalesceList(&eVid, ITM_ITEM_LIST);
	
	IfThenElse * firstITE = NULL;
	IfThenElse * currITE = NULL;
	for (CollIndex i = 0; i < (CollIndex)coalesceList.entries(); i++) 
	  {
	    // Specifically prohibit the last operand from being explicit NULL
	    if ( (i+1) == (CollIndex)coalesceList.entries() ) {
	        if ( (coalesceList[i])->getOperatorType() == ITM_CONSTANT ) {
	           if ( ((ConstValue *)coalesceList[i])->isNull() ) {
	              *CmpCommon::diags() << DgSqlCode(-3416) << DgString0("COALESCE");
	              bindWA->setErrStatus();
	              return this;
	           }
	        }
	    }
	    ItemExpr * v = 
	      new(bindWA->wHeap()) UnLogic(ITM_IS_NOT_NULL, coalesceList[i]);
	    IfThenElse * ite = new(bindWA->wHeap()) IfThenElse(v, coalesceList[i], NULL);
	    if (firstITE == NULL)
	      firstITE = ite;
	    if (currITE != NULL)
	      {
		currITE->setElse(ite);
	      }
	    currITE = ite;
	  }
	currITE->setElse(new(bindWA->wHeap()) SystemLiteral());
	parseTree = new(bindWA->wHeap()) Case(NULL, firstITE);
      }
    break;

    case ITM_DAYNAME:
      {
	// find the nullability of child
	//coverity[returned_pointer]
	ItemExpr * tempBoundTree =
	  child(0)->castToItemExpr()->bindNode(bindWA);
	if (bindWA->errStatus()) return this;

	NABoolean childIsNullable = FALSE;
	if (tempBoundTree->getValueId().getType().supportsSQLnull())
	  {
	    childIsNullable = TRUE;
	  }

	if (childIsNullable)
	  strcpy(buf, "CASE WHEN @A1 IS NULL THEN NULL ELSE ");
	else
	  strcpy(buf, "");

	strcat (buf, "CASE DAYOFWEEK(@A1) WHEN 1 THEN 'Sunday' WHEN 2 THEN 'Monday' WHEN 3 THEN 'Tuesday' WHEN 4 THEN 'Wednesday' WHEN 5 THEN 'Thursday' WHEN 6 THEN 'Friday' WHEN 7 THEN 'Saturday' ELSE 'ERROR' END");

	if (childIsNullable)
	  strcat(buf, " END;");
	else
	  strcat(buf, ";");
      }
    break;

    case ITM_DECODE:
      {
	Int32 savedCurrChildNo = currChildNo();
	
	for (Int32 i = 0; i < getArity(); i++, currChildNo()++) 
	{
	  ItemExpr *boundExpr = child(i)->bindNode(bindWA);
	  child(i) = boundExpr;
	}
	
	currChildNo() = savedCurrChildNo;

	if (bindWA->errStatus()) 
	  return this;

	ExprValueId eVid(child(0)->castToItemExpr());
	ItemExprTreeAsList decodeList(&eVid, ITM_ITEM_LIST);
	
	const NAType &typ1 = eVid->getValueId().getType();
	NABoolean noNulls = FALSE;
	
	if ((getArity() == 1) && (NOT typ1.supportsSQLnull()))  {
	  noNulls = true;  // main expression cannot be null so a simplier expression can be built
	}

	IfThenElse * firstITE = NULL;
	IfThenElse * currITE = NULL;

	Int32 numExprs = decodeList.entries();
        
	if (numExprs < 3) {
	  *CmpCommon::diags() << DgSqlCode(-15001) << DgString0(")");
	  bindWA->setErrStatus();
	  return this;
	} 

	BiRelat *v;
	for (CollIndex i = 1; i < (CollIndex)numExprs-1; i++) 
	{
	  v = new(bindWA->wHeap())BiRelat(ITM_EQUAL,decodeList[0] ,decodeList[i]);
	  v->setSpecialNulls(TRUE);
	  IfThenElse * ite = new(bindWA->wHeap()) IfThenElse(v, decodeList[i+1], NULL);
	  if (firstITE == NULL)
	    firstITE = ite;
	  
	  if (currITE != NULL)
	  {
	    currITE->setElse(ite);
	  }
	  
	  currITE = ite;
	  i++;  // must increment two each loop
	}
	
	if (numExprs % 2 == 0 )		 // even number.  final argument is an else
	  currITE->setElse( decodeList[numExprs-1]);
	else
	  currITE->setElse(new(bindWA->wHeap()) SystemLiteral());
	
	parseTree = new(bindWA->wHeap()) Case(NULL, firstITE);
	parseTree->setOrigOpType(getOperatorType());
      }
    break;

    case ITM_DAYOFYEAR:
      {
	strcpy(buf, "CAST(CAST(@A1 AS DATE) - FIRSTDAYOFYEAR(@A1) AS INT) + 1;");
      }
    break;

    case ITM_FIRSTDAYOFYEAR:
      {
	strcpy(buf, "CAST(CAST(@A1 AS DATETIME YEAR) AS DATE);");
      }
    break;

    case ITM_DAYOFMONTH:
      {
	// Make sure that the child is of date datatype.
	ItemExpr * tempBoundTree =
	  child(0)->castToItemExpr()->bindNode(bindWA);
	if (bindWA->errStatus()) 
          return this;

	if (tempBoundTree->getValueId().getType().getTypeQualifier() !=
	    NA_DATETIME_TYPE)
	  {
	    // 4071 The operand of a DAYOFMONTH function must be a datetime.
	    *CmpCommon::diags() << DgSqlCode(-4071) << DgString0(getTextUpper());
	    bindWA->setErrStatus();
	    return this;
	  }

        parseTree = new(bindWA->wHeap()) 
          ExtractOdbc(REC_DATE_DAY, child(0), TRUE);
      }
      break;

    case ITM_GREATEST:
      {
	strcpy(buf, "CASE WHEN @A1 is NULL or @A2 is null then NULL WHEN @A1 > @A2 then @A1 else @A2 END;");
      }
    break;

   case ITM_LEAST:
      {
	strcpy(buf, "CASE WHEN @A1 is NULL or @A2 is null then NULL WHEN @A1 < @A2 then @A1 else @A2 END;");
      }
    break;

    case ITM_INSERT_STR:
      {
	// Make sure that the third child(length) is of unsigned numeric with
	// scale of zero.
	ItemExpr * tempBoundTree =
	  child(2)->castToItemExpr()->bindNode(bindWA);
	if (bindWA->errStatus()) return this;
        
        // fix case 10-031103-2610, soln 10-031103-0997: make sure length arg
        // in function "INSERT(s1, start, length, s2)" is not null.
        if (tempBoundTree->getOperatorType() == ITM_CONSTANT &&
            ((ConstValue *)tempBoundTree)->isNull()) {
          *CmpCommon::diags() << DgSqlCode(-4097) << DgString0("INSERT");
          bindWA->setErrStatus();
          return this;
        }
        
	//
	// Type cast any param.
	//
	SQLInt nType(FALSE);
	ValueId vid = child(2)->getValueId();
	vid.coerceType(nType, NA_NUMERIC_TYPE);

	NABoolean errorLength = FALSE;
	if (tempBoundTree->getValueId().getType().getTypeQualifier() !=
	    NA_NUMERIC_TYPE)
	  {
	    errorLength = TRUE;
	  }

	const NumericType &ntyp =
	  (NumericType &) tempBoundTree->getValueId().getType();

	if ((NOT ntyp.isExact()) || (ntyp.getScale() != 0))
	  errorLength = TRUE;

	if (errorLength)
	  {
	    *CmpCommon::diags() << DgSqlCode(-4053) << DgString0(getTextUpper());
	    bindWA->setErrStatus();
	    return this;
	  }

	// INSERT (str1(@A1), start(@A2), length(@A3), str2(@A4))
	// Returns a string where <length> characters have been deleted from
	// <str1> beginning at <start> and where <str2> has been inserted
	// into <str1>, beginning at <start>

        // make sure replacement expression handles any null args correctly
        strcpy(buf, "CASE WHEN @A1 IS NULL THEN NULL"
               " WHEN @A2 IS NULL THEN NULL"
               " WHEN @A3 IS NULL THEN NULL"
               " WHEN @A4 IS NULL THEN NULL ELSE ");

	// Get the characters before <start>
	strcat(buf, "(LEFT(@A1, CAST(@A2 AS INT UNSIGNED) - 1)");

	// append <str2>
	strcat(buf, "|| @A4 ");

	// and finally append the 'rightmost' characters from str1 after
	// skipping (start + length) characters.
	// If the number of 'rightmost' characters is a negative,
	// then insert '0' characters.
        strcat(buf, "|| CASE WHEN (CHAR_LENGTH(@A1) - (@A2 + CAST(@A3 AS INT UNSIGNED)) + 1) > 0 THEN RIGHT(@A1, CHAR_LENGTH(@A1) - (@A2 + CAST(@A3 AS INT UNSIGNED)) + 1) ELSE RIGHT(@A1, 0) END) END;");
      }
    break;

    case ITM_LPAD:
      {
        Int32 padStringLength = 0;
        if (child(2))
        {
          padStringLength = getPadStringLength(child(2)->castToItemExpr(), bindWA);
          if (bindWA->errStatus()) return this;
        }

        if (child(2) == NULL)
          {
            // pad with spaces
            // NOTE: The outer SUBSTRING operation would seem to be unnecessary
            // in some cases, but it ensures the SQL compiler always knows that
            // the maximum length of the return string is the user-specified value.

            strcpy(buf,
                  "SUBSTRING( "
                  "CASE WHEN @A1 IS NULL THEN NULL "
                  "WHEN CHAR_LENGTH(@A1) >= @A2 THEN @A1 "
                  "ELSE SUBSTRING( SPACE(@A2, _UNKNOWN_), 1, "
                                  " @A2 - CHAR_LENGTH(@A1) ) || @A1 "
                  "END, 1, @A2 ) ;");
          }
        else if (padStringLength == 1)
        {
          // when the third param has a length = 1 then the we do not need to
          // use the complicated case expression in the else branch a few lines 
          // below. When the padding string length is known to be 1 we can use
          // an case expression very similar to the situation when child(2) is null.

          strcpy(buf,
                  "SUBSTRING( "
                  "CASE WHEN @A1 IS NULL THEN NULL "
                  "WHEN CHAR_LENGTH(@A1) >= @A2 THEN @A1 "
                  "ELSE SUBSTRING( "
                    "REPEAT(@A3, @A2), 1, @A2 - CHAR_LENGTH(@A1)) || @A1 "
                  "END, 1, @A2 ) ;");
        }
        else 
        {
          // pad with the third param.
          Int32 lpadLength = getPadLength(child(1)->castToItemExpr(), bindWA);
          if (bindWA->errStatus()) return this;

          // If result size needed is less than some threshold, use fast path
          if ((lpadLength > 0) && (lpadLength <= 1024)) {
            strcpy(buf,
                  "SUBSTRING( "
                  "CASE WHEN @A1 IS NULL OR @A3 IS NULL THEN NULL "
                  "WHEN CHAR_LENGTH(@A1) >= @A2 THEN @A1 "
                  "ELSE SUBSTRING( REPEAT(@A3, @A2), 1, "
                    "@A2 - CHAR_LENGTH(@A1)) || @A1 "
                  "END, 1, @A2 );");
          }
          else
          {
            // NOTES:
            // (1) The outer SUBSTRING operation would seem to be unnecessary
            //     in some cases, but it ensures the SQL compiler always knows
            //     that the maximum length of the return string is the
            //     user-specified value (if the user specified a constant.)
            // (2) The 2nd WHEN prevents a negative REPEAT count and is
            //     also required by definition of this padding function.
            // (3) The 3rd WHEN prevents division by 0 later on and also
            //     ensures we catch overly large count (@A2) values at compile
            //     time if possible ... by sending @A2 directly to REPEAT
            //     without doing any CASTing or arithmetic on it (because
            //     doing those causes the value of @A2 to be resolved at
            //     runtime instead of compile time.)

            strcpy(buf,
                  "SUBSTRING( "
                  "CASE WHEN @A1 IS NULL OR @A3 IS NULL THEN NULL "
                  "WHEN CHAR_LENGTH(@A1) >= @A2 THEN @A1 "
                  "WHEN CHAR_LENGTH(@A3) <= 1 THEN "
                  "SUBSTRING( REPEAT(@A3, @A2), 1, "
                    "@A2 - CHAR_LENGTH(@A1)) || @A1 "
                  "ELSE SUBSTRING( "
                        "REPEAT(@A3,"
                              "CAST((@A2 - CHAR_LENGTH(@A1))/CHAR_LENGTH(@A3) "
                                "+ 1 AS INT)"
                              "), "
                        " 1, "
                        " @A2 - CHAR_LENGTH(@A1) ) || @A1 "
                  "END, 1, @A2 );");

            if (lpadLength > -1)
            {
              parseTree = parser.getItemExprTree(buf, strlen(buf), BINDITEMEXPR_STMTCHARSET, 3, child(0), child(1), child(2));
              buf[0] = 0;

              // The max length of repeat is "length of lpad" * "padding string
              // length" * "bytes per char".  The "length of lpad" is stored,
              // and when the type is synthesized, the length will be multiplied
              // by the nominal size of the pattern string.  Also note, both the
              // pattern string and the column must be the same type - an error
              // would occur otherwise at compile-time.

              Int32 maxRepeatLength = lpadLength;

              if (parseTree && parseTree->getOperatorType() == ITM_SUBSTR)
              {
                NAList<Lng32> childNumList(CmpCommon::statementHeap(),7);
                NAList<OperatorTypeEnum>
                  opTypeList(CmpCommon::statementHeap(),7);

                childNumList.insertAt(0,0);
                opTypeList.insertAt(0,ITM_CASE);

                childNumList.insertAt(1,0);
                opTypeList.insertAt(1,ITM_IF_THEN_ELSE);

                childNumList.insertAt(2,2);
                opTypeList.insertAt(2,ITM_IF_THEN_ELSE);

                childNumList.insertAt(3,2);
                opTypeList.insertAt(3,ITM_IF_THEN_ELSE);

                childNumList.insertAt(4,2); opTypeList.insertAt(4,ITM_CONCAT);
                childNumList.insertAt(5,0); opTypeList.insertAt(5,ITM_SUBSTR);
                childNumList.insertAt(6,0); opTypeList.insertAt(6,ITM_REPEAT);

                Repeat*  repNode =
                  (Repeat *) parseTree->getParticularItemExprFromTree(
                                                childNumList, opTypeList) ;
                if (repNode && (maxRepeatLength > 1))
                   repNode->setMaxLength(maxRepeatLength);

              } // end of block that is looking for the problematic Repeat node
              else
              {
                bindWA->setErrStatus();  // couldn't parse lpad replacement str
                return this;
              }
            }  // lpad has a fixed max length
          }
        } // third param is has more than one character or is a varchar
      }  // end of LPAD case
    break;

    case ITM_MONTHNAME:
      {
	// find the nullability of child
	ItemExpr * tempBoundTree =
	  child(0)->castToItemExpr()->bindNode(bindWA);
	if (bindWA->errStatus()) return this;

	NABoolean childIsNullable = FALSE;
	if (tempBoundTree->getValueId().getType().supportsSQLnull())
	  {
	    childIsNullable = TRUE;
	  }

	if (childIsNullable)
	  strcpy(buf, "CASE WHEN @A1 IS NULL THEN NULL ELSE ");
	else
	  strcpy(buf, "");

	strcat (buf, "CASE MONTH(@A1) WHEN 1 THEN 'January' WHEN 2 THEN 'February' WHEN 3 THEN 'March' WHEN 4 THEN 'April' WHEN 5 THEN 'May' WHEN 6 THEN 'June' WHEN 7 THEN 'July' WHEN 8 THEN 'August' WHEN 9 THEN 'September' WHEN 10 THEN 'October' WHEN 11 THEN 'November' WHEN 12 THEN 'December' ELSE 'Error' END");

	if (childIsNullable)
	  strcat(buf, " END;");
	else
	  strcat(buf, ";");
      }
    break;

    case ITM_ODBC_LENGTH:
      {
	strcpy(buf, "CHAR_LENGTH(RTRIM(@A1));");
      }
    break;

    case ITM_QUARTER:
      {
	// Make sure that the child is of datetime datatype.
	ItemExpr * tempBoundTree =
	  child(0)->castToItemExpr()->bindNode(bindWA);
	if (bindWA->errStatus()) return this;

	if (tempBoundTree->getValueId().getType().getTypeQualifier() !=
	    NA_DATETIME_TYPE)
	  {
	    // 4071 The operand of a QUARTER function must be a datetime.
	    *CmpCommon::diags() << DgSqlCode(-4071) << DgString0(getTextUpper());
	    bindWA->setErrStatus();
	    return this;
	  }

	NABoolean childIsNullable = FALSE;
	if (tempBoundTree->getValueId().getType().supportsSQLnull())
	  {
	    childIsNullable = TRUE;
	  }

	if (childIsNullable)
	  strcpy(buf, "CASE WHEN @A1 IS NULL THEN NULL ELSE ");
	else
	  strcpy(buf, "");

	strcat (buf, "CASE WHEN MONTH(@A1) >= 1 AND MONTH(@A1) <= 3 THEN 1 WHEN MONTH(@A1) >= 4 AND MONTH(@A1) <= 6 THEN 2 WHEN MONTH(@A1) >= 7 AND MONTH(@A1) <= 9 THEN 3 WHEN MONTH(@A1) >= 10 AND MONTH(@A1) <= 12 THEN 4 ELSE 0 END");

	if (childIsNullable)
	  strcat(buf, " END;");
	else
	  strcat(buf, ";");

      }
    break;

    case ITM_RIGHT:
    case ITM_LEFT:

      {
	// LEFT(<str>(@A1), <count>(A2))
	// RIGHT(<str>(@A1), <count>(A2))

	// verify that the COUNT is specified as an INT with no scale.
	ItemExpr * tempBoundTree =
	  child(1)->castToItemExpr()->bindNode(bindWA);
	if (bindWA->errStatus()) return this;

	const NAType &typ1 = tempBoundTree->getValueId().getType();

        if ( tempBoundTree->getOperatorType() != ITM_DYN_PARAM ) {
           const NumericType &ntyp1 = (NumericType &) typ1;
           if ((typ1.getTypeQualifier() != NA_NUMERIC_TYPE) ||
               (NOT ntyp1.isExact()))
             {
               // 4046 Count must be exact numeric.
               *CmpCommon::diags() << DgSqlCode(-4046) << DgString0(getTextUpper());
               bindWA->setErrStatus();
               return this;
             }

           if (ntyp1.getScale() != 0)
             {
               // 4047 Count must have a scale of 0.
               *CmpCommon::diags() << DgSqlCode(-4047) << DgString0(getTextUpper());
               bindWA->setErrStatus();
               return this;
             }
        }

        if ( getOperatorType() == ITM_RIGHT )
	  // The case expression is needed for cases where the length supplied
          // exceeds the length of the string; in this case we want to return 
          // the whole string. SUBSTR of a 0 or negative value doesn't do that.
          strcpy(buf, "SUBSTRING(@A1 FROM "
                      "CASE WHEN(CHAR_LENGTH(@A1) - CAST(@A2 AS INT UNSIGNED) + 1) > 1 "
                      "THEN (CHAR_LENGTH(@A1) - CAST(@A2 AS INT UNSIGNED) + 1) ELSE 1 END);");
        else
	  strcpy(buf, "SUBSTRING(@A1 FROM 1 FOR @A2);"); // LEFT()

      }
    break;

    case ITM_RPAD:
      {
        Int32 padStringLength = 0;
        Int32 rpadLength = -3;  // -2, -1 and 0 have a distinct meaning, see 
        // comment near function definition.

        if (child(2))
        {
          child(2) = child(2)->castToItemExpr()->bindNode(bindWA);
          if (bindWA->errStatus()) return this;
          padStringLength = getPadStringLength(child(2)->castToItemExpr(), bindWA);
          if (bindWA->errStatus()) return this;
        }

        if (child(1))
        {
          rpadLength = getPadLength(child(1)->castToItemExpr(), bindWA);
          if (bindWA->errStatus()) return this;
        }

        ItemExpr * tempBoundTree =
	  child(0)->castToItemExpr()->bindNode(bindWA);
	if (bindWA->errStatus()) return this;
        CharInfo::CharSet cs = CharInfo::UnknownCharSet;
        const NAType& type = tempBoundTree->getValueId().getType();
        if ( type.getTypeQualifier() == NA_CHARACTER_TYPE )
	  cs = ((CharType&)type).getCharSet();

        NABoolean padWithSpace = FALSE;

        // If the character set is ISO88591, ISO mapping is checked 
        // to get the correct character set in the current configuration
        if (cs == CharInfo::ISO88591)
        {	
          CharInfo::CharSet isoMappingCS = (CharInfo::CharSet)SqlParser_ISO_MAPPING;
          padWithSpace = isPadWithSpace(child(2),isoMappingCS);
        }
        else
          padWithSpace = isPadWithSpace(child(2),cs);

        if ((rpadLength > 0) && padWithSpace)
        {
          // use CAST to implement RPAD of blank space
          // remember to turn off string trunc. warnings.
          if (cs == CharInfo::ISO88591)
            sprintf(buf, "CAST(@A1 AS CHAR(%d) CHARACTER SET ISO88591) ;", rpadLength);
          else if (cs == CharInfo::UTF8)
            sprintf(buf, "CAST(@A1 AS CHAR(%d BYTES) CHARACTER SET UTF8) ;", rpadLength);
          else if (cs == CharInfo::SJIS /* && encodingCharSet == CharInfo::SJIS */)
            sprintf(buf, "CAST(@A1 AS CHAR(%d BYTES) CHARACTER SET SJIS) ;", rpadLength);
          else 
          {
            sprintf(buf, "CAST(@A1 AS CHAR(%d) CHARACTER SET UCS2) ;", rpadLength);
          }

          if ( rpadLength > CmpCommon::getDefaultNumeric(TRAF_MAX_CHARACTER_COL_LENGTH))
          {
             //Note: We claim error occurred in "REPEAT" here just so we get a consistent
             //error message regardless of whether or not the CAST optimization is used.
            *CmpCommon::diags() << DgSqlCode(-4129) << DgString0("REPEAT");
             *CmpCommon::diags() << DgSqlCode(-4062) << DgString0("RPAD");
             bindWA->setErrStatus();
             return this;
          }

          parseTree = parser.getItemExprTree(buf, strlen(buf), BINDITEMEXPR_STMTCHARSET, 1, child(0));
          buf[0] = 0;
          if (parseTree && parseTree->getOperatorType() == ITM_CAST)
          {
            ((Cast*) parseTree)->setNoStringTruncationWarnings(TRUE);
          }
        }
	else if (child(2) == NULL)
	{
	  // pad with spaces
	  // NOTE: The outer SUBSTRING operation would seem to be unnecessary
	  // in some cases, but it ensures the SQL compiler always knows that
	  // the max length of the return string is the user-specified value.

	  strcpy(buf, 
                "SUBSTRING( "
                "CASE WHEN @A1 IS NULL THEN NULL "
                "WHEN CHAR_LENGTH(@A1) >= @A2 THEN @A1 "
                "ELSE @A1 || SUBSTRING( SPACE(@A2, _UNKNOWN_), 1, "
                                " @A2 - CHAR_LENGTH(@A1) ) "
                "END, 1, @A2 ) ;");
	}
        else if (padStringLength == 1)
        {
          // when the third param has a length = 1 then the we do not need to
          // use the complicated case expression in the else branch a few lines 
          // below. When the padding string length is known to be 1 we can use
          // a case expression very similar to that used when child(2) is null.
            strcpy(buf,
                    "SUBSTRING( "
                    "CASE WHEN @A1 IS NULL THEN NULL "
                    "WHEN CHAR_LENGTH(@A1) >= @A2 THEN @A1 "
                    "ELSE @A1 || REPEAT(@A3, @A2) "
                    "END, 1, @A2 ) ;");

        }
	else
	{
          // pad with the third param.

          Int32 rpadLength = getPadLength(child(1)->castToItemExpr(), bindWA);
          if (bindWA->errStatus()) return this;

          // If result size needed is less than some threshold, use fast path
          if ((rpadLength > 0) && (rpadLength <= 1024)) {
            strcpy(buf,
                  "SUBSTRING( "
                  "CASE WHEN @A1 IS NULL OR @A3 IS NULL THEN NULL "
                  "WHEN CHAR_LENGTH(@A1) >= @A2 THEN @A1 "
                  "ELSE @A1 || REPEAT(@A3, @A2) "
                  "END, 1, @A2 );");
          }
          else
          {
            // NOTES:
            // (1) The outer SUBSTRING operation would seem to be unnecessary
            //     in some cases, but it ensures the SQL compiler always knows
            //     that the maximum length of the return string is the
            //     user-specified value (if the user specified a constant.)
            // (2) The 2nd WHEN prevents division by 0 later on and also
            //     ensures we catch overly large count (@A2) values at compile
            //     time if possible ... by sending @A2 directly to REPEAT
            //     without doing any CASTing or arithmetic on it (because
            //     doing those causes the value of @A2 to be resolved at
            //     runtime instead of compile time.)
            // (3) The 3rd WHEN prevents a negative REPEAT count and is
            //     also required by definition of this padding function.

            strcpy(buf,
                  "SUBSTRING( "
                  "CASE WHEN @A1 IS NULL OR @A3 IS NULL THEN NULL "
                  "WHEN CHAR_LENGTH(@A3) <= 1 THEN @A1 || REPEAT(@A3, @A2) "
                  "WHEN CHAR_LENGTH(@A1) >= @A2 THEN @A1 "
                  "ELSE @A1 || REPEAT(@A3, CAST(( "
                    "@A2 - CHAR_LENGTH(@A1))/CHAR_LENGTH(@A3) + 1 AS INT)) "
                  "END, 1, @A2 );");

            if (rpadLength > -1)
            {
              parseTree = parser.getItemExprTree(buf, strlen(buf), BINDITEMEXPR_STMTCHARSET, 3, child(0), child(1), child(2));
              buf[0] = 0;

              // The max length of repeat is "length of rpad" * "padding string
              // length" * "bytes per char".  The "length of rpad" is stored,
              // and when the type is synthesized, the length will be multiplied
              // by the nominal size of the pattern string.  Also note, both the
              // pattern string and the column must be the same type - an error
              // would occur otherwise at compile-time.

              Int32 maxRepeatLength = rpadLength;

              if (parseTree && parseTree->getOperatorType() == ITM_SUBSTR)
              {
                NAList<Lng32> childNumList(CmpCommon::statementHeap(),6);
                NAList<OperatorTypeEnum>
                  opTypeList(CmpCommon::statementHeap(),6);

                childNumList.insertAt(0,0);
                opTypeList.insertAt(0,ITM_CASE);

                childNumList.insertAt(1,0);
                opTypeList.insertAt(1,ITM_IF_THEN_ELSE);

                childNumList.insertAt(2,2);
                opTypeList.insertAt(2,ITM_IF_THEN_ELSE);

                childNumList.insertAt(3,2);
                opTypeList.insertAt(3,ITM_IF_THEN_ELSE);

                childNumList.insertAt(4,2); opTypeList.insertAt(4,ITM_CONCAT);
                childNumList.insertAt(5,1); opTypeList.insertAt(5,ITM_REPEAT);

                Repeat*  repNode =
                  (Repeat *) parseTree->getParticularItemExprFromTree(
                                                childNumList, opTypeList) ;
                if (repNode && (maxRepeatLength > 1))
                 repNode->setMaxLength(maxRepeatLength);

              } // end of block that is looking for the problematic Repeat node
              else
              {
                bindWA->setErrStatus();  // couldn't parse rpad replacement str
                return this;
              }
            }  // rpad has a fixed max length
	  }  // padding string of rpad has more than 1 character 
        }
      }
    break;

    case ITM_SIGN:
      {
	ItemExpr * tempBoundTree =
	  child(0)->castToItemExpr()->bindNode(bindWA);
	if (bindWA->errStatus()) return this;

	//
	// Type cast any param.
	//
	SQLInt nType(FALSE);
	ValueId vid = tempBoundTree->castToItemExpr()->getValueId();
	vid.coerceType(nType, NA_NUMERIC_TYPE);

	const NAType &typ1 = vid.getType();
        if (typ1.getTypeQualifier() != NA_NUMERIC_TYPE)
          {
            // 4045 Operand must be numeric.
            *CmpCommon::diags() << DgSqlCode(-4045) << DgString0(getTextUpper());
            bindWA->setErrStatus();
            return this;
          }

	// find the nullability of child
	NABoolean childIsNullable = FALSE;
	if (tempBoundTree->getValueId().getType().supportsSQLnull())
	  {
	    childIsNullable = TRUE;
	  }

	if (childIsNullable)
	  strcpy(buf, "CASE WHEN @A1 IS NULL THEN NULL ELSE ");
	else
	  strcpy(buf, "");

	strcat(buf, "CASE WHEN @A1 < 0 THEN -1 WHEN @A1 = 0 THEN 0 ELSE 1 END");

	if (childIsNullable)
	  strcat(buf, " END;");
	else
	  strcat(buf, ";");
      }
    break;

    case ITM_SPACE:
      {
	strcpy(buf, "REPEAT ( @A1 , @A2 );");
      }
    break;

    case ITM_USER:
    case ITM_AUTHNAME:
    case ITM_AUTHTYPE:
    {
	ItemExpr * tempBoundTree =
	  child(0)->castToItemExpr()->bindNode(bindWA);
	if (bindWA->errStatus())
	  return this;

	if (tempBoundTree->getValueId().getType().getTypeQualifier() !=
		NA_NUMERIC_TYPE)
	{
		strcpy(buf,
		       "cast(substring(@A1, 1, position(',' in @A1)-1) as smallint) * 256 + cast(substring(@A1, position(',' in @A1)+1, char_length(@A1) - position(',' in @A1)) as smallint)");
	}
	else
	{
		buf[0] = 0;
		parseTree = child(0);
	}
	
    }
    break;

    case ITM_WEEK:
      {
        // Essentially we need to process the following case statement to
        // achieve WEEK functionality. However, the case statement is split
        // into pieces to access the divide operator node.
        // "CAST((DAYOFYEAR(@A1) - 1 + DAYOFWEEK(FIRSTDAYOFYEAR(@A1)) - 1)/7 
        //  AS INT) + 1;"
        strcpy(buf, "(DAYOFYEAR(@A1) - 1 + DAYOFWEEK(FIRSTDAYOFYEAR(@A1)) - 1)/7");        
        
        ItemExpr *tempExpr = NULL;
	if (strlen(buf) > 0)
	  {
	    tempExpr = parser.getItemExprTree(buf, strlen(buf), BINDITEMEXPR_STMTCHARSET, 1, child(0));
	    if (! tempExpr)
	      {
		bindWA->setErrStatus();
		return this;
	      }

	    // Disable rounding for DATE TIME type of operations.
	    if (tempExpr->getOperatorType() == ITM_DIVIDE)
	      {
		((BiArith*)tempExpr)->setIgnoreSpecialRounding();
	      }
            
            strcpy(buf, "CAST(@A1 AS INT) + 1;");
            
            parseTree = parser.getItemExprTree(buf, strlen(buf), BINDITEMEXPR_STMTCHARSET, 1, tempExpr);

	    parseTree->setOrigOpType(getOperatorType());
	
	    buf[0] = 0;
	  }
      }
    break;

    case ITM_NULLIF:
      {
        strcpy(buf, "CASE WHEN @A1 = @A2 THEN NULL ELSE @A1 END;");
      }
    break;

    case ITM_ZEROIFNULL:
      {
	// find the nullability of child
	ItemExpr * tempBoundTree =
	  child(0)->castToItemExpr()->bindNode(bindWA);
	if (bindWA->errStatus()) return this;

	//
	// Type cast any param.
	//
	SQLInt nType(FALSE);
	ValueId vid = tempBoundTree->castToItemExpr()->getValueId();
	vid.coerceType(nType, NA_NUMERIC_TYPE);

	if (tempBoundTree->getValueId().getType().getTypeQualifier() != NA_NUMERIC_TYPE)
	  {
	    // 4045 must be numeric.
	    *CmpCommon::diags() << DgSqlCode(-4045) << DgString0(getTextUpper());
	    bindWA->setErrStatus();
	    return this;
	  }

	if ((tempBoundTree->getValueId().getType().supportsSQLnull()) ||
	    (tempBoundTree->isASubquery()))
	  {
	    strcpy(buf, "CASE WHEN @A1 IS NULL then 0 ELSE @A1 END;");
	  }
	else
	  {
	    // if child is not nullable, then no need to do zeroifnull.
	    // Point to child.
	    parseTree = child(0)->castToItemExpr();
	  }
      }
    break;
    case ITM_SUBSTR:
      {
          //
          // Perhaps someone, someday, will figure out how to make
          // sqlparser.y invoke the Substring() constructor and pass
          // it a constant of 1 for the start argument...without
          // causing crashes of mxcmp.  Until then, we will
          // translate it to old SUBSTRING syntax here.
          //
          strcpy(buf, "SUBSTRING(@A1 FROM 1 FOR @A2);");
      }
    break;

    case ITM_ROUND:
      {
	//Do initial argument validations. 
	// First operand is the value to be rounded. Cannot be float or
	// bignums.
	// 
	// Second operand is the number of digits after decimal point to be
	// rounded to.
	// Third operand is the rounding mode. Must be a constant.
	//

	NABoolean useOptimizedRound = TRUE;

	//Processing of first operand.
	ItemExpr * tempBoundTree = child(0)->castToItemExpr()->bindNode(bindWA);
	if (bindWA->errStatus()) return this;

	if (tempBoundTree->getValueId().getType().getTypeQualifier() == NA_UNKNOWN_TYPE)
	  child(0)->getValueId().coerceType(NA_NUMERIC_TYPE);
	
	if (tempBoundTree->getValueId().getType().getTypeQualifier() != NA_NUMERIC_TYPE)
	  {
	    // 4059 The first operand must be numeric.
	    *CmpCommon::diags() << DgSqlCode(-4059) << DgString0("ROUND");
	    bindWA->setErrStatus();
	    return this;
	  }
	
	NumericType &type_op1 =
	  (NumericType&)tempBoundTree->getValueId().getType();
	if ((NOT type_op1.isExact()) ||
	    (type_op1.isComplexType()))
	  {
	    useOptimizedRound = FALSE;
	    // Only supporting ROUND of exact numerics with max precision
	    // of MAX_NUMERIC_PRECISION (no floats or bignums).
	    //
	    // 4059 The first operand must be numeric.
	    //	    *CmpCommon::diags() << DgSqlCode(-4070) << DgString0("ROUND");
	    //bindWA->setErrStatus();
	    //return this;
	  }

	//second operand.
 Lng32 roundTo = -1;
	if (child(1) == NULL)
	  {
	    // round all digits after the decimal point
	    roundTo = 0;
	  }
	else
	  {
	    //argument validation for second argument.
	    ItemExpr *secondOpExpr = child(1)->castToItemExpr(); 
	    secondOpExpr->bindNode(bindWA);
	    if (bindWA->errStatus()) 
	      return this;
	    
	    if (secondOpExpr->getValueId().getType().getTypeQualifier() != NA_NUMERIC_TYPE)
	      {
		*CmpCommon::diags() << DgSqlCode(-4052) << DgString0("ROUND");
		bindWA->setErrStatus();
		return this;
	      }
	    
	    NumericType &tempType = (NumericType&)secondOpExpr->getValueId().getType();
	    if(! (tempType.isExact() && tempType.getScale() <=0 ))
	      {
		*CmpCommon::diags() << DgSqlCode(-4047) << DgString0("ROUND");
		bindWA->setErrStatus();
		return this;
	      }

	    if (secondOpExpr->getOperatorType() == ITM_CONSTANT)
	      {
		roundTo = 
		  (Lng32)((ConstValue*)secondOpExpr)->getExactNumericValue();

		if (roundTo > MAX_NUMERIC_PRECISION)
		  {
		    *CmpCommon::diags() << DgSqlCode(-4052) << DgString0("ROUND");
		    bindWA->setErrStatus();
		    return this;
		  }
	      }
	    else
	      {
		useOptimizedRound = FALSE;
		//		*CmpCommon::diags() << DgSqlCode(-4052) << DgString0("ROUND");
		//		bindWA->setErrStatus();
		//		return this;
	      }
	  }

	short roundingMode = 1;
	if( child(2) != NULL )
	  {
	    //argument validation for second argument.
	    ItemExpr *thirdOpExpr = child(2)->castToItemExpr(); 
	    thirdOpExpr->bindNode(bindWA);
	    if (bindWA->errStatus()) 
	      return this;
	    
	    if ((thirdOpExpr->getOperatorType() != ITM_CONSTANT) ||
		(thirdOpExpr->getValueId().getType().getTypeQualifier() != NA_NUMERIC_TYPE) ||
		(useOptimizedRound == FALSE))
	      {
		*CmpCommon::diags() << DgSqlCode(-4053) << DgString0("ROUND");
		bindWA->setErrStatus();
		return this;
	      }
	    
	    NumericType &tempType = (NumericType&)thirdOpExpr->getValueId().getType();
	    if(! (tempType.isExact() && tempType.getScale() <=0 ))
	      {
		*CmpCommon::diags() << DgSqlCode(-4047) << DgString0("ROUND");
		bindWA->setErrStatus();
		return this;
	      }

	    roundingMode = 
	      (short)((ConstValue*)thirdOpExpr)->getExactNumericValue();
	    if ((roundingMode < 0) ||
		(roundingMode > 2))
	      {
		*CmpCommon::diags() << DgSqlCode(-4053) << DgString0("ROUND");
		bindWA->setErrStatus();
		return this;
	      }
	  }
        
	if (useOptimizedRound)
	  {
	    // divide the value by 10 raised to the power of the number of
	    // digits to be rounded off.
	    // If roundTo(second) param is a const, create a literal instead
	    // of an expression.
	    ItemExpr * divExpr = NULL;
	    Int64 denom = 0;
	    buf[0] = 0;
	    if ((roundTo >= 0) &&
		(type_op1.getScale() > roundTo))
	      {
		denom = 1;
	 Int32 i = (type_op1.getScale() - roundTo);
		while (i > 0)
		  {
		    denom = denom * 10;
		    i--;
		  }
		
		str_sprintf(buf, "@A1 / %ld", denom);
	      }
	    
	    if (strlen(buf) > 0)
	      {
		divExpr = parser.getItemExprTree(buf, strlen(buf), BINDITEMEXPR_STMTCHARSET, 2, child(0), child(1));
		if (! divExpr)
		  {
		    bindWA->setErrStatus();
		    return this;
		  }
		
		// indicate that this division need to do rounding.
		if (divExpr->getOperatorType() == ITM_DIVIDE)
		  {
		    ((BiArith*)divExpr)->setRoundingMode(roundingMode);
		    ((BiArith*)divExpr)->setDivToDownscale(TRUE);
		  }
		
		// multiply by 10 ** (number of digits rounded off) to
		// get back to the original scale.
		str_sprintf(buf, "cast(@A1 * %ld as numeric(%d,%d))", 
                  denom, MAX_NUMERIC_PRECISION, MAXOF(type_op1.getScale(), roundTo));
		parseTree = parser.getItemExprTree(buf, strlen(buf), BINDITEMEXPR_STMTCHARSET, 2, divExpr, child(1));
		if (! parseTree)
		  {
		    bindWA->setErrStatus();
		    return this;
		  }
		buf[0] = 0;
	      }
	    else
	      parseTree = child(0)->castToItemExpr();
	  }
	else
	  {
	    //The round function is implemented using other existing math functions.
	    //Typically ROUND(expr,num) will involve the following:Ex: ROUND(34.58,1)
	    //1. Move the decimal point num+1 places by multiplying by num+1.
	    //   Example: 34.58 * power(10,num+1) = 3458.00
	    //2. MOD(result,10)=x determines if round-up is required. In the case of 
	    //   inexact numbers, round-down or round-even is also performed.
	    //   If x < 5 then no change. if x > 5 then round up.
	    //   if x = 5 then round even.
	    //   Example:MOD(3458.00, 10) = 8 means round up.
	    //3. Based on roundup,round down, round even, round the number at numth
	    //   position.
	    //   Example: floor(34.58 * power(10, num)) = 345.00 + 1 = 346.00
	    //4. Then move the decimal point by multiplying or dividing by
	    //   multiples of 10.
	    //   Example: 346.00 * power(10, -1) = 34.60.
	    //5. In the case of inexact numbers, round even is performed if required.
	    
	    //ROUND processing:              
	    if( type_op1.isExact() )//MOD does not support inexact expressions.
            {
	      if(child(1) == NULL)//In ROUND(expr,num), num is optional, defaults to 0.
              { 
		if(type_op1.getScale() <=0)//no need to perform round in this case.
		  parseTree = child(0)->castToItemExpr();
                else
                {
                  if(type_op1.isBigNum()) 
                    strcpy(buf,"case when SIGN(@A1) < 0 then case when (cast(@A1 * 10 as numeric(128,0))-(10 * cast(cast((@A1 * 10)as numeric(128,0))/10  as numeric(128,0)))) > -5 then cast(@A1 as numeric(128,0)) when (cast(@A1 * 10 as numeric(128,0))-(10 * cast(cast((@A1 * 10)as numeric(128,0))/10  as numeric(128,0)))) <=-5 then cast(@A1 as numeric(128,0)) - 1 END else case when (cast(@A1 * 10 as numeric(128,0))-(10 * cast(cast((@A1 * 10)as numeric(128,0))/10  as numeric(128,0)))) < 5 then cast(@A1 as numeric(128,0)) when (cast(@A1 * 10 as numeric(128,0))-(10 * cast(cast((@A1 * 10)as numeric(128,0))/10  as numeric(128,0)))) >=5 then cast(@A1 as numeric(128,0)) +SIGN(@A1) END END");
                  else
		    strcpy(buf, "case when MOD(cast((abs(@A1) * 10) as largeint), 10) < 5 then cast(@A1 as largeint) when MOD(cast((abs(@A1) * 10) as largeint), 10) >=5 then cast(@A1 as largeint) +SIGN(@A1) END");
                }
	      }
	      else{
                if(type_op1.getScale() <= 0){
                  if(type_op1.isBigNum()) 
                    strcpy(buf, "case SIGN(@A1) when -1 then case SIGN(@A2+1)when 1 then @A1 ELSE case when (cast(@A1/cast(power(10, abs(@A2+1)) as numeric(128,0)) as numeric(128,0))-(10 * cast(cast(@A1/cast(power(10, abs(@A2+1)) as numeric(128,0)) as numeric(128,0))/10 as numeric(128,0)))) > -5 then cast((@A1/cast(power(10,abs(@A2)) as numeric(128,0))) as numeric(128,0))* cast(power(10,abs(@A2)) as numeric(128,0)) ELSE (cast((@A1/cast(power(10,abs(@A2)) as numeric(128,0))) as numeric(128,0)) + SIGN(@A1)) * cast(power(10,abs(@A2)) as numeric(128,0)) END END ELSE case SIGN(@A2+1)when 1 then @A1 ELSE case when (cast(@A1/cast(power(10, abs(@A2+1)) as numeric(128,0)) as numeric(128,0))-(10 * cast(cast(@A1/cast(power(10, abs(@A2+1)) as numeric(128,0)) as numeric(128,0))/10 as numeric(128,0)))) < 5 then cast((@A1/cast(power(10,abs(@A2)) as numeric(128,0))) as numeric(128,0))* cast(power(10,abs(@A2)) as numeric(128,0)) ELSE (cast((@A1/cast(power(10,abs(@A2)) as numeric(128,0))) as numeric(128,0)) + SIGN(@A1)) * cast(power(10,abs(@A2)) as numeric(128,0)) END END END");
                  else
		    strcpy(buf, "case SIGN(@A2+1)when 1 then case when MOD(cast(abs(@A1) * cast(power(10, @A2+1) as largeint) as largeint), 10) < 5 then cast((@A1 * cast(power(10,@A2) as largeint)) as largeint) / cast(power(10,abs(@A2)) as largeint) when MOD(cast(abs(@A1) * cast(power(10, @A2+1) as largeint) as largeint), 10) >=5 then (cast((@A1 * cast(power(10,@A2) as largeint)) as largeint) +SIGN(@A1)) / cast(power(10,@A2) as largeint) END ELSE case when MOD(cast(abs(@A1) /cast(power(10, abs(@A2+1)) as largeint) as largeint), 10) < 5 then cast((@A1/cast(power(10,abs(@A2)) as largeint)) as largeint)* cast(power(10,abs(@A2)) as largeint) when MOD(cast(abs(@A1) /cast(power(10, abs(@A2+1)) as largeint) as largeint), 10) >=5 then (cast((@A1/cast(power(10,abs(@A2)) as largeint)) as largeint)+ SIGN(@A1)) * cast(power(10,abs(@A2)) as largeint) END END");
                }
		else{
                      NumericType *typeTemp;
                      if(type_op1.isBigNum())
                      {
                       // In the below case statement, cast the result to 
                       // resultPrecision + 1. This is done for cases that 
                       // result in consuming additional precision.
                       // For example, round(99.00, -2) = 100.00 
                       const Int16 DisAmbiguate = 0;
                       typeTemp = new(bindWA->wHeap()) SQLNumeric(bindWA->wHeap(), type_op1.isSigned(),
                                                                   MINOF(type_op1.getPrecision()+1,128),
                                                                   type_op1.getScale(),
                                                                   DisAmbiguate // added for 64bit proj.
                                                                  );
                        
                       NAString nstr = "";
		        typeTemp->getMyTypeAsText(&nstr, FALSE);
		        char *text = convertNAString(nstr, bindWA->wHeap()); 
		        sprintf(buf, "cast(case SIGN(@A1) when -1 then case SIGN(@A2+1) when 1 then case when (cast(@A1 * cast(power(10, @A2+1) as numeric(128,0)) as numeric(128,0))-(10 * cast(cast(@A1 * cast(power(10, @A2+1) as numeric(128,0))as numeric(128,0))/10  as numeric(128,0)))) > -5 then cast((@A1 * cast(power(10,@A2) as numeric(128,0))) as numeric(128,0)) / cast(power(10,abs(@A2)) as numeric(128,0)) ELSE (cast((@A1 * cast(power(10,@A2) as numeric(128,0))) as numeric(128,0)) + SIGN(@A1) ) / cast(power(10,@A2) as numeric(128,0)) END ELSE case when (cast(@A1/cast(power(10, abs(@A2+1)) as numeric(128,0)) as numeric(128,0))-(10 * cast(cast(@A1/cast(power(10, abs(@A2+1)) as numeric(128,0)) as numeric(128,0))/10 as numeric(128,0)))) > -5 then cast((@A1/cast(power(10,abs(@A2)) as numeric(128,0))) as numeric(128,0))* cast(power(10,abs(@A2)) as numeric(128,0)) ELSE (cast((@A1/cast(power(10,abs(@A2)) as numeric(128,0))) as numeric(128,0))+ SIGN(@A1)) * cast(power(10,abs(@A2)) as numeric(128,0)) END END ELSE case SIGN(@A2+1) when 1 then case when (cast(@A1 * cast(power(10, @A2+1) as numeric(128,0)) as numeric(128,0))-(10 * cast(cast(@A1 * cast(power(10, @A2+1) as numeric(128,0))as numeric(128,0))/10  as numeric(128,0)))) < 5 then cast((@A1 * cast(power(10,@A2) as numeric(128,0))) as numeric(128,0)) / cast(power(10,abs(@A2)) as numeric(128,0)) ELSE (cast((@A1 * cast(power(10,@A2) as numeric(128,0))) as numeric(128,0)) + SIGN(@A1) ) / cast(power(10,@A2) as numeric(128,0)) END ELSE case when (cast(@A1/cast(power(10, abs(@A2+1)) as numeric(128,0)) as numeric(128,0))-(10 * cast(cast(@A1/cast(power(10, abs(@A2+1)) as numeric(128,0)) as numeric(128,0))/10 as numeric(128,0)))) < 5 then cast((@A1/cast(power(10,abs(@A2)) as numeric(128,0))) as numeric(128,0))* cast(power(10,abs(@A2)) as numeric(128,0)) ELSE (cast((@A1/cast(power(10,abs(@A2)) as numeric(128,0))) as numeric(128,0))+ SIGN(@A1)) * cast(power(10,abs(@A2)) as numeric(128,0)) END END END as %s)", text);
                      }
                      else
                      {
                        if(type_op1.getScale() <=18)
		         {
                          // In the below case statement, cast the result to 
                          // resultPrecision + 1. This is done for cases that 
                          // result in consuming additional precision.
                          // For example, round(99.00, -2) = 100.00
                          typeTemp = (NumericType*)type_op1.newCopy(bindWA->wHeap());
                          typeTemp->setPrecision(MINOF(type_op1.getPrecision()+1,18));
                          typeTemp->setScale(type_op1.getScale());
      		  
		          //precision is 10 or bigger, then UNSIGNED cannot be used for NUMERIC type.
		          if((typeTemp->getPrecision() >= 10 ) &&  typeTemp->isUnsigned())
		            typeTemp->makeSigned();

		          NAString nstr = "";
		          typeTemp->getMyTypeAsText(&nstr, FALSE);
		          char *text = convertNAString(nstr, bindWA->wHeap()); 
		          sprintf(buf, "cast(case SIGN(@A2+1)when 1 then case when MOD(cast(abs(@A1) * cast(power(10, @A2+1) as largeint) as largeint), 10) < 5 then cast((@A1 * cast(power(10,@A2) as largeint)) as largeint) / cast(power(10,abs(@A2)) as largeint) when MOD(cast(abs(@A1) * cast(power(10, @A2+1) as largeint) as largeint), 10) >=5 then (cast((@A1 * cast(power(10,@A2) as largeint)) as largeint) +SIGN(@A1)) / cast(power(10,@A2) as largeint) END ELSE case when MOD(cast(abs(@A1) /cast(power(10, abs(@A2+1)) as largeint) as largeint), 10) < 5 then cast((@A1/cast(power(10,abs(@A2)) as largeint)) as largeint)* cast(power(10,abs(@A2)) as largeint) when MOD(cast(abs(@A1) /cast(power(10, abs(@A2+1)) as largeint) as largeint), 10) >=5 then (cast((@A1/cast(power(10,abs(@A2)) as largeint)) as largeint)+ SIGN(@A1)) * cast(power(10,abs(@A2)) as largeint) END END as %s)", text);
                        }
                        else
                        {
                           //If the scale of type_op1 is greater than 18,
                           //skip the casting of final result expression.
                           sprintf(buf, "case SIGN(@A2+1)when 1 then case when MOD(cast(abs(@A1) * cast(power(10, @A2+1) as largeint) as largeint), 10) < 5 then cast((@A1 * cast(power(10,@A2) as largeint)) as largeint) / cast(power(10,abs(@A2)) as largeint) when MOD(cast(abs(@A1) * cast(power(10, @A2+1) as largeint) as largeint), 10) >=5 then (cast((@A1 * cast(power(10,@A2) as largeint)) as largeint) +SIGN(@A1)) / cast(power(10,@A2) as largeint) END ELSE case when MOD(cast(abs(@A1) /cast(power(10, abs(@A2+1)) as largeint) as largeint), 10) < 5 then cast((@A1/cast(power(10,abs(@A2)) as largeint)) as largeint)* cast(power(10,abs(@A2)) as largeint) when MOD(cast(abs(@A1) /cast(power(10, abs(@A2+1)) as largeint) as largeint), 10) >=5 then (cast((@A1/cast(power(10,abs(@A2)) as largeint)) as largeint)+ SIGN(@A1)) * cast(power(10,abs(@A2)) as largeint) END END");
                        }
                      }
		    }
	      }
             // Once we are done bignum round processing above, we need to 
             // make sure not to introduce realbignum if the type_op1 is not
             // real BigNum. Using CAST(x as numeric(128,0)) will automatically
             // make the operand realbignum. 
             if(type_op1.isBigNum() &&
              (!((SQLBigNum &)type_op1).isARealBigNum()))
             {
                resetRealBigNum = TRUE;
             }
	    }
	    else {
              ItemExpr * v =
                new(bindWA->wHeap()) MathFunc(ITM_ROUND, child(0), child(1));

              boundTree = v->bindNode(bindWA);
              if (bindWA->errStatus())
                return this;
	    } 	
	  }
      }
    
    break;
    case ITM_CURRNT_USER:
      {
	strcpy(buf, "TRANSLATE(CURRNT_USR_INTN USING ISO88591ToUCS2);");
      }
    break;
    case ITM_SESSN_USER:
      {
	strcpy(buf, "TRANSLATE(SESSN_USR_INTN USING ISO88591ToUCS2);");
      }
    break;
    case ITM_CONVERTTOHX:
      {
	strcpy(buf, "TRANSLATE(CONVERTTOHX_INTN(@A1) USING ISO88591ToUCS2);");
      }
    break;

    case ITM_SCALE_TRUNC:
      {
	ItemExpr *tempBoundTree = child(0)->castToItemExpr()->bindNode(bindWA); 
	if (bindWA->errStatus()) 
	  return this;

	if (tempBoundTree->getValueId().getType().getTypeQualifier() == NA_NUMERIC_TYPE)
	  {
	    NumericType &type_op1 =
	      (NumericType&)tempBoundTree->getValueId().getType();
	    
	    if ((NOT type_op1.isExact()) ||
		(type_op1.isComplexType()))
	      {
		// 4059 The first operand must be numeric.
		*CmpCommon::diags() << DgSqlCode(-4070) << DgString0("ROUND");
		bindWA->setErrStatus();
		return this;
	      }
	    
	    Lng32 truncVal = 
	      (Lng32)((ConstValue*)child(1)->castToItemExpr())->getExactNumericValue();
	    
	    str_sprintf(buf, "CAST(@A1 as NUMERIC(%d, %d));",
			type_op1.getPrecision(), truncVal);
	  }
	else if (tempBoundTree->getValueId().getType().getTypeQualifier() == NA_DATETIME_TYPE)
	  {
	    // for now, just return the child.
	    boundTree = tempBoundTree;
	  }
	else
	  {
	    // 4059 The first operand must be numeric.
	    *CmpCommon::diags() << DgSqlCode(-4059) << DgString0("TRUNC");
	    bindWA->setErrStatus();
	    return this;
	  }
      }
    break;

    case ITM_TO_NUMBER:
      {
	ItemExpr *tempBoundTree = child(0)->castToItemExpr()->bindNode(bindWA); 
	if (bindWA->errStatus()) 
	  return this;

        if (CmpCommon::getDefault(MODE_SPECIAL_4) == DF_OFF)
          {
            if (tempBoundTree->getValueId().getType().getTypeQualifier() != NA_CHARACTER_TYPE)
              {
                // 4043 The first operand must be numeric.
                *CmpCommon::diags() << DgSqlCode(-4043) << DgString0("TO_NUMBER");
                bindWA->setErrStatus();
                return this;
              }
          }

	NAType &type_op1 =
	  (NAType&)tempBoundTree->getValueId().getType();
	
	str_sprintf(buf, "CAST(@A1 as NUMERIC(%d));",
		    type_op1.getNominalSize());
      }
    break;

    case ITM_TO_TIMESTAMP:
      {
	ItemExpr *tempBoundTree = child(0)->castToItemExpr()->bindNode(bindWA); 
	if (bindWA->errStatus()) 
	  return this;

	str_sprintf(buf, "CAST(@A1 as TIMESTAMP(6));");
      }
    break;

    case ITM_CURRENT_TIMESTAMP_UTC:
      {
	if (bindWA->currentCmpContext()->gmtDiff() > 0)
	  str_sprintf(buf, "CURRENT_TIMESTAMP + INTERVAL '%4d' MINUTE(4);",
		      bindWA->currentCmpContext()->gmtDiff());
	else if (bindWA->currentCmpContext()->gmtDiff() < 0)
	  str_sprintf(buf, "CURRENT_TIMESTAMP - INTERVAL '%4d' MINUTE(4);",
		      -bindWA->currentCmpContext()->gmtDiff());
	else
	  strcpy(buf, "CURRENT_TIMESTAMP");
      }
    break;

    case ITM_CURRENT_TIME_UTC:
      {
	str_sprintf(buf, "CAST(CURRENT_TIMESTAMP_UTC AS TIME);");
      }
    break;

    case ITM_GROUPING_ID:
      {
        *CmpCommon::diags() << DgSqlCode(-3242)
                            << DgString0("GROUPING_ID function must be specified in the select list of a GROUP BY ROLLUP statement.");
        bindWA->setErrStatus();
        return this;
      }
      break;

    default:
      {
	bindWA->setErrStatus();
	return this;
      }
    }
  
  if (CURRENTSTMT->getItemExprOrigOpTypeCounter() == 0)
    CURRENTSTMT->setItemExprOrigOpTypeBeingBound(getOperatorType());
  
  (CURRENTSTMT->getItemExprOrigOpTypeCounter())++;

  if (strlen(buf) > 0)
    {
      parseTree = parser.getItemExprTree(buf, strlen(buf), BINDITEMEXPR_STMTCHARSET, 5, child(0), child(1), child(2), child(3), child(4));
    }

 if (parseTree) {

    switch (getOperatorType())
      {
      case ITM_UNICODE_CODE_VALUE:
      case ITM_NCHAR_MP_CODE_VALUE:
	{
	  parseTree = new(bindWA->wHeap()) CodeVal(getOperatorType(), parseTree);
	}
	break;

      case ITM_AUTHNAME:
      case ITM_AUTHTYPE:
      case ITM_USER:
	{
	  parseTree = new(bindWA->wHeap()) MonadicUSERFunction(parseTree,getOperatorType());
	}
	break;
      case ITM_ROUND:
       {
         if(resetRealBigNum)
          resetRealBigNumFlag(parseTree);
       }
       break;

      } // switch

    boundTree = parseTree->bindNode(bindWA);
    if (bindWA->errStatus()) boundTree = NULL;
  }

  //origOpTypeCounter()--;
  (CURRENTSTMT->getItemExprOrigOpTypeCounter())--;

  // once out of the scope of any operator set the type to default
  //if (origOpTypeCounter() == 0)
  //  origOpTypeBeingBound() = NO_OPERATOR_TYPE;

  if (CURRENTSTMT->getItemExprOrigOpTypeCounter() == 0)
    CURRENTSTMT->setItemExprOrigOpTypeBeingBound(NO_OPERATOR_TYPE);

  // NOTE: Don't call unparse() below if we don't need to.  It may blow up
  // since getSubquery() could return NULL if the subquery was discarded.
  //
  if ((boundTree == NULL) && (CURRENTSTMT->getItemExprOrigOpTypeCounter() == 0) ) {
    NAString orig(bindWA->wHeap());

    // For functions whose arity is more than 1, am removing
    // the use of unparse since it does not do the right thing.
    //if (parseTree) parseTree->unparse(orig,DEFAULT_PHASE,USER_FORMAT_DELUXE);
    if (getArity() > 1)
      orig = getTextUpper();
    else
      unparse(orig, DEFAULT_PHASE, USER_FORMAT_DELUXE);

    // 4062 The preceding error actually occurred in function $0~String0.
    *CmpCommon::diags() << DgSqlCode(-4062) << DgString0(orig);
    bindWA->setErrStatus();
  }

  return boundTree;
}

ItemExpr *ZZZBinderFunction::tryToUndoBindTransformation(ItemExpr *expr)
{
  // Given as input an expression produced by ZZZBinderFunction::bindNode(),
  // return an equivalent ZZZBinderFunction ItemExpr or NULL for cases
  // that are not yet supported. This is used for a) unparsing such
  // functions, and b) validating some item expressions.

  ItemExpr *result = NULL;
  ItemExpr *op1 = expr;
  ItemExpr *op2 = NULL;

  switch (expr->origOpType())
    {
    case ITM_DATE_TRUNC_SECOND:
      {
        // Form is date_trunc(date_trunc('hour', <arg>) + ...) + ...
        // ==> Remove the top + and fall through to next case
        if (op1 &&
            op1->getOperatorType() == ITM_PLUS)
          op1 = op1->child(0);
        else
          op1 = NULL;
      }
      // fall through to next case

    case ITM_DATE_TRUNC_MINUTE:
      {
        // Form is date_trunc('hour', <arg>) + ...
        // ==> Remove the top + and fall through to next case
        if (op1 &&
            op1->getOperatorType() == ITM_PLUS)
          op1 = op1->child(0);
        else
          op1 = NULL;
      }
      // fall through to next case
      
    case ITM_DATE_TRUNC_MONTH:
    case ITM_DATE_TRUNC_HOUR:
    case ITM_DATE_TRUNC_CENTURY:
    case ITM_DATE_TRUNC_DECADE:
      {
        // form is cast(cast(<arg>)) +/- ...
        // ==> Remove the top + or - and fall through to next case
        if (op1 &&
            (op1->getOperatorType() == ITM_PLUS ||
             op1->getOperatorType() == ITM_MINUS))
          op1 = op1->child(0);
        else
          op1 = NULL;
      }
      // fall through to next case
      
    case ITM_DATE_TRUNC_YEAR:
    case ITM_DATE_TRUNC_DAY:
      {
        // form is cast(cast(<arg>))
        if (op1 &&
            op1->getOperatorType() == ITM_CAST)
          {
            op1 = op1->child(0);
            if (op1->getOperatorType() == ITM_CAST)
              op1 = op1->child(0);
          }
        else
          op1 = NULL;

        if (op1)
          result = new(CmpCommon::statementHeap())
            ZZZBinderFunction(expr->origOpType(),op1);
      }
      break;
      
    case ITM_DATEDIFF_YEAR:
    case ITM_DATEDIFF_QUARTER:
    case ITM_DATEDIFF_MONTH:
      {
        // different forms (in prefix notation) - we find <arg1> and <arg2>
        // and ignore the parts shown as ellipsis
        // year:    cast(-(extract(<arg2>),
        //                 extract(<arg1>)))
        // quarter: cast(/(-(+(*(extract(<arg2>),
        //                       ...),
        //                     ...),
        //                   +(*(extract(<arg1>),
        //                       ...),
        //                     ...))))
        // month:   cast(-(+(*(extract(<arg2>),
        //                     ...),
        //                   ...),
        //                 +(*(extract(<arg1>),
        //                     ...),
        //                   ...)))
        if (op1->getOperatorType() == ITM_CAST)
          {
            if (NULL != expr && expr->origOpType() == ITM_DATEDIFF_QUARTER &&
                op1->child(0)->getOperatorType() == ITM_DIVIDE)
              op1 = op1->child(0)->child(0); // the minus operator
              //    cast   /         -
            else if (op1->child(0)->getOperatorType() == ITM_MINUS)
              op1 = op1->child(0); // the minus operator
              //    cast   -

            if (NULL != expr && expr->origOpType() == ITM_DATEDIFF_YEAR)
              {
                if (op1->child(0)->getOperatorType() == ITM_EXTRACT ||
                    op1->child(0)->getOperatorType() == ITM_EXTRACT_ODBC)
                  {
                    op2 = op1->child(0)->child(0);
                    //     -   extract   <arg2>
                    op1 = op1->child(1)->child(0);
                    //     -   extract   <arg1>
                  }
              }
            else if (op1->child(0)->getOperatorType() == ITM_PLUS &&
                     op1->child(0)->child(0)->getOperatorType() == ITM_TIMES &&
                     (op1->child(0)->child(0)->child(0)->getOperatorType() == ITM_EXTRACT ||
                      op1->child(0)->child(0)->child(0)->getOperatorType() == ITM_EXTRACT_ODBC) &&
                     op1->child(1)->getOperatorType() == ITM_PLUS &&
                     op1->child(1)->child(0)->getOperatorType() == ITM_TIMES &&
                     (op1->child(1)->child(0)->child(0)->getOperatorType() == ITM_EXTRACT ||
                      op1->child(1)->child(0)->child(0)->getOperatorType() == ITM_EXTRACT_ODBC))
              {
                op2 = op1->child(0)->child(0)->child(0)->child(0);
                //     -      +         *      extract   <arg2>
                op1 = op1->child(1)->child(0)->child(0)->child(0);
                //     -      +         *      extract   <arg1>
              }
            else
              op1 = NULL;
          }
        if (op1 && op2)
          result = new(CmpCommon::statementHeap())
            ZZZBinderFunction(expr->origOpType(),op1,op2);
      }
      break;

    case ITM_DATEDIFF_WEEK:
      {
        // form:    cast(/(-(-(cast(<arg2>),...),
        //                   -(cast(<arg1>),...)))))
        if (op1->getOperatorType() == ITM_CAST &&
            op1->child(0)->getOperatorType() == ITM_DIVIDE &&
            op1->child(0)->child(0)->getOperatorType() == ITM_MINUS)
          {
            op1 = op1->child(0)->child(0);
            //    cast   /          -

            if (op1->child(0)->getOperatorType() == ITM_MINUS &&
                op1->child(0)->child(0)->getOperatorType() == ITM_CAST &&
                op1->child(1)->getOperatorType() == ITM_MINUS &&
                op1->child(1)->child(0)->getOperatorType() == ITM_CAST)
              {
                op2 = op1->child(0)->child(0)->child(0);
                //     -     -       cast      <arg2>
                op1 = op1->child(1)->child(0)->child(0);
                //     -     -       cast      <arg1>
              }
          }
        else
          op1 = NULL;
        if (op1 && op2)
          result = new(CmpCommon::statementHeap())
            ZZZBinderFunction(expr->origOpType(),op1,op2);
      }
      break;

    case ITM_YEARWEEK:
    case ITM_YEARWEEKD:
      {
        // form: cast(+(*(extract_odbc(<arg1>),...),...))
        if (op1->getOperatorType() == ITM_CAST &&
            op1->child(0)->getOperatorType() == ITM_PLUS &&
            op1->child(0)->child(0)->getOperatorType() == ITM_TIMES &&
            op1->child(0)->child(0)->child(0)->getOperatorType() == ITM_EXTRACT_ODBC)
          {
            op1 = op1->child(0)->child(0)->child(0)->child(0);
            //    cast   +         *       extract   <arg1>
            result = new(CmpCommon::statementHeap())
              ZZZBinderFunction(expr->origOpType(), op1);
          }
      }
      break;

    default:
      break;
    }

  return result;  
}

// returns true if there is an error
bool ZZZBinderFunction::enforceDateOrTimestampDatatype(BindWA * bindWA, CollIndex childIndex, int operand)
{
  // Make sure that the child is of date or timestamp datatype.
  ItemExpr * tempBoundTree =
    child(childIndex)->castToItemExpr()->bindNode(bindWA);
  if (bindWA->errStatus()) 
    return true;

  bool error = (tempBoundTree->getValueId().getType().getTypeQualifier() !=
                NA_DATETIME_TYPE);
  if (!error)
    {
      DatetimeType *dtOper = 
	  &(DatetimeType&)tempBoundTree->getValueId().getType();
      error = ((dtOper->getPrecision() != SQLDTCODE_TIMESTAMP) &&
	       (dtOper->getPrecision() != SQLDTCODE_DATE));
    }

  if (error)
    {
      // 4182 Function $0~String0 operand $0~Int0 must be of type $1~String1.
      *CmpCommon::diags() << DgSqlCode(-4182) 
                          << DgString0(getTextUpper())
                          << DgInt0(operand)
                          << DgString1("DATE or TIMESTAMP");
      bindWA->setErrStatus();
      return true;
    }

  setChild(childIndex, tempBoundTree);
  return false;  // no error
}

//-------------------------------------------------------------------------
//
// member functions for class ItmSequenceFunction
//
//-------------------------------------------------------------------------
ItemExpr *ItmSequenceFunction::bindNode(BindWA *bindWA)
{
  if (nodeIsBound())
  {
    if (bindWA->getCurrentScope()->getAllSequenceFunctions().contains(getValueId()))
      bindWA->getCurrentScope()->getUnresolvedSequenceFunctions() += getValueId();
    return getValueId().getItemExpr();
  }
  
  if (isOlapFunction())
  {
    ItmSeqOlapFunction * olap = (ItmSeqOlapFunction * )this;
    if ((olap->isFrameStartUnboundedPreceding() && //olap->getframeStart() == -INT_MAX && 
         olap->isFrameEndUnboundedPreceding() ) || //olap->getframeEnd() == -INT_MAX) || 
        (olap->isFrameStartUnboundedFollowing() && //olap->getframeStart() ==  INT_MAX && 
         olap->isFrameEndUnboundedFollowing()) || //olap->getframeEnd() ==  INT_MAX) || 
        (olap->getframeStart() > olap->getframeEnd()))
    {
      //The specified window frame clause is not valid.
      *CmpCommon::diags() << DgSqlCode(-4342);
      bindWA->setErrStatus();
    } 

    if (!olap->isFrameStartUnboundedPreceding() && //olap->getframeStart() != -INT_MAX &&
        !olap->isFrameEndUnboundedFollowing() && //olap->getframeEnd()   != INT_MAX &&
        olap->getframeEnd() - olap->getframeStart() >  
        (Lng32)CmpCommon::getDefaultNumeric(OLAP_MAX_FIXED_WINDOW_FRAME))
    {
      //Maximum Window frame size exceeded.
      *CmpCommon::diags() << DgSqlCode(-4347)
			  << DgInt0((Lng32)CmpCommon::getDefaultNumeric(OLAP_MAX_FIXED_WINDOW_FRAME));
      bindWA->setErrStatus();
    }

    if ( olap->getframeEnd() > 0 &&
        bindWA->getCurrentScope()->context()->inPrecOlapFunction())
    {
      //Nesting Window functions with FOLLOWING clause is not supported.
      *CmpCommon::diags() << DgSqlCode(-4348);
      bindWA->setErrStatus();
    }

    if (olap->getframeStart() <= 0)
    {
      bindWA->getCurrentScope()->context()->inPrecOlapFunction() = TRUE;
    }

  }

  RelSequence * seqNode = 
    (RelSequence *)bindWA->getCurrentScope()->getSequenceNode();

  bindWA->getCurrentScope()->context()->inSequenceFunction() = TRUE;

  if (seqNode && !isOLAP())
  {
    if (isTDFunction() && 
        ((const RelSequence *)seqNode)->requiredOrder().entries() != 0)
    {
      setIsTDFunction(FALSE);
    }

    if(isTDFunction() )
    {
      if (bindWA->getCurrentScope()->context()->inTDFunction() && 
            getOperatorType() == ITM_RUNNING_RANK)
      {//Nesting rank functions is not supported. 
        *CmpCommon::diags() << DgSqlCode(-4368);
        bindWA->setErrStatus();
        return this;
      }

      if  (!bindWA->getCurrentScope()->context()->inSelectList() &&
          !bindWA->getCurrentScope()->context()->inQualifyClause())
      { //Rank can be placed only in the select list or the qualify clause
        *CmpCommon::diags() << DgSqlCode(-4364);
        bindWA->setErrStatus();
        return this;
      }

      if (getOperatorType() == ITM_RUNNING_RANK)
      {
        bindWA->getCurrentScope()->context()->inTDFunction() = TRUE;
      }

      ValueIdList change = seqNode->getPartitionChange();

      if (change.entries() != 0 && getOperatorType() == ITM_RUNNING_RANK)
      {
        setOlapPartitionBy(change.rebuildExprTree(ITM_ITEM_LIST));
        
        CMPASSERT(getOlapPartitionBy());

        ItemExpr * tdSeq = transformTDFunction(bindWA);
        if (! tdSeq)
	    return NULL;

        return tdSeq->bindNode(bindWA);
      }
    }
    else
    {
      if (bindWA->getCurrentScope()->context()->inTDFunction())
      { //Using rank function and sequence functions together in the same query scope is not supported
        *CmpCommon::diags() << DgSqlCode(-4367);
        bindWA->setErrStatus();
        return this;
      }
    }
  }

  BindScope::HasOlapFunctionsEnum olap = isOLAP() ? BindScope::OLAP_: BindScope::NONOLAP_;

  if ( bindWA->getCurrentScope()->getHasOlapSeqFunctions() == BindScope::OLAPUNKNOWN_ )
  {
    bindWA->getCurrentScope()->setHasOlapSeqFunctions(olap);
  } 
  else
  {
    if (bindWA->getCurrentScope()->getHasOlapSeqFunctions() != olap)
    {
       *CmpCommon::diags() << DgSqlCode(-4345);
       bindWA->setErrStatus();
       return NULL;
    }
  }

  if (bindWA->getCurrentScope()->context()->inHavingClause() OR (
      bindWA->getCurrentScope()->context()->inSelectList() AND
      bindWA->getCurrentScope()->getRETDesc()->isGrouped() AND
      ! isOLAP()
     ))  {
       //
       //  4109: We are in a SELECT or HAVING, and the sequence function is not
       //        inside an aggregate (fixes Genesis case 10-990823-0045)
       //
      if (NOT bindWA->getCurrentScope()->context()->inAggregate()) {
        NAString unparsed(bindWA->wHeap());
              unparse(unparsed, DEFAULT_PHASE, USER_FORMAT_DELUXE);
              // 4109: sequence function placed incorrectly
      *CmpCommon::diags() << DgSqlCode(-4109) << DgString0(unparsed);
              bindWA->setErrStatus();
              return this;
      }
  }

  // Capture the current set of sequence functions in this scope.
  // Do not add those sequence functions which are below this node.
  //
  ValueIdSet seqFuncs =
    bindWA->getCurrentScope()->getUnresolvedSequenceFunctions();

 // Check for invalid nesting of the THIS sequence function
 // inside ROWS SINCE and some other sequence function.
 // All other nestings are allowed.
 //
 NABoolean savedRowsSince             = bindWA->getCurrentScope()->context()->inRowsSince();
 NABoolean savedOtherSequenceFunction = bindWA->getCurrentScope()->context()->inOtherSequenceFunction();
 switch (getOperatorType())
 {
   case ITM_ROWS_SINCE:
     bindWA->getCurrentScope()->context()->inRowsSince() = TRUE;
                             // The next line fixes Genesis case 10-990301-0576.
     bindWA->getCurrentScope()->context()->inOtherSequenceFunction() = FALSE;
     break;

   case ITM_THIS:
     if (bindWA->getCurrentScope()->context()->inRowsSince() &&
         bindWA->getCurrentScope()->context()->inOtherSequenceFunction())
     {
       // Inside a ROWS SINCE, the xxx function contained an invalid reference
       // to the THIS function.
       *CmpCommon::diags() << DgSqlCode(-4108);
       bindWA->setErrStatus();
     }
     if (NOT bindWA->getCurrentScope()->context()->inRowsSince())
     {
       // THIS can be used only Inside a ROWS SINCE
       *CmpCommon::diags() << DgSqlCode(-4220);
       bindWA->setErrStatus();
     }
     break;

   default:
     bindWA->getCurrentScope()->context()->inOtherSequenceFunction() = TRUE;
     break;
 }

 // The sequence functions are bound in the environment (RETDesc) of
 // the child of the Sequence
 //

 RelExpr *sequenceNode = bindWA->getCurrentScope()->getSequenceNode();
 RETDesc *currentRETDesc = NULL;

 if (sequenceNode) {

   currentRETDesc = bindWA->getCurrentScope()->getRETDesc();
   
   bindWA->getCurrentScope()->setRETDesc(sequenceNode->child(0)->getRETDesc());
 }


  // ItmSequencefunction is directly derived from BuiltinFunction;
  // safe to invoke this
  //
  BuiltinFunction::bindNode(bindWA);

  if (sequenceNode) {

    bindWA->getCurrentScope()->setRETDesc(currentRETDesc);

  }

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

  bindWA->getCurrentScope()->context()->inTDFunction() = FALSE;

  bindWA->getCurrentScope()->context()->inPrecOlapFunction() = FALSE;
 
  ValueId equivId, finalVid;
  if (CmpCommon::getDefault(COMP_BOOL_203) == DF_ON) {
    equivId = bindWA->getCurrentScope()->getEquivalentItmSequenceFunction(getValueId());
  }

  // Add value id to list of sequence functions in this scope.
  // Ignore those sequence functions which are below this node.
  // We only want the root sequence functions.
  //
  if (CmpCommon::getDefault(COMP_BOOL_203) == DF_ON)
    finalVid = equivId;
  else
    finalVid = getValueId();

  seqFuncs += finalVid ;
  bindWA->getCurrentScope()->getUnresolvedSequenceFunctions() = seqFuncs; 
  bindWA->getCurrentScope()->getAllSequenceFunctions() += finalVid; 


  //
  //  Reset the nesting flags.
  //
  bindWA->getCurrentScope()->context()->inOtherSequenceFunction() = savedOtherSequenceFunction;
  bindWA->getCurrentScope()->context()->inRowsSince()             = savedRowsSince;

  // Reset other context flags.
  bindWA->getCurrentScope()->context()->inSequenceFunction() = FALSE;

  if (CmpCommon::getDefault(COMP_BOOL_203) == DF_ON)
    return equivId.getItemExpr();
  else
    return getValueId().getItemExpr();
}

//---------------------------------------------------------------------------
//
// member functions for class HbaseColumnLookup
//
//---------------------------------------------------------------------------
ItemExpr *HbaseColumnLookup::bindNode(BindWA *bindWA)
{
  ItemExpr * boundExpr = NULL;

  if (nodeIsBound())
    return getValueId().getItemExpr();

  // Binds self; Binds children; ColumnLookup::synthesize();
  boundExpr = Function::bindNode(bindWA);
  if (bindWA->errStatus()) 
    return NULL;

  // Add this hbase column to column usage info of this hbase table.
  ItemExpr * ie = child(0)->castToItemExpr();
  NAColumn * nacol = NULL;
  if (ie->getOperatorType() == ITM_REFERENCE)
    {
      ColReference * colR = (ColReference*)ie;
      nacol = colR->getValueId().getNAColumn(TRUE/*okIfNotColumn*/);
    }
  else if (ie->getOperatorType() == ITM_BASECOLUMN)
    {
      BaseColumn * baseC = (BaseColumn*)ie;
      nacol = baseC->getNAColumn();
    }

  const NATable * naTable = nacol->getNATable();
  bindWA->hbaseColUsageInfo()->insert
    ((QualifiedName*)&naTable->getTableName(), &hbaseCol_);
  
  return boundExpr;
}

//---------------------------------------------------------------------------
//
// member functions for class HbaseColumnsDisplay
//
//---------------------------------------------------------------------------
ItemExpr *HbaseColumnsDisplay::bindNode(BindWA *bindWA)
{
  ItemExpr * boundExpr = NULL;

  if (nodeIsBound())
    return getValueId().getItemExpr();

  // Binds self; Binds children; ColumnDisplay::synthesize();
  boundExpr = Function::bindNode(bindWA);
  if (bindWA->errStatus()) 
    return NULL;

  // Add this hbase column to column usage info of this hbase table.
  ItemExpr * ie = child(0)->castToItemExpr();
  NAColumn * nacol = NULL;
  if (ie->getOperatorType() == ITM_REFERENCE)
    {
      ColReference * colR = (ColReference*)ie;
      nacol = colR->getValueId().getNAColumn(TRUE/*okIfNotColumn*/);
    }
  else if (ie->getOperatorType() == ITM_BASECOLUMN)
    {
      BaseColumn * baseC = (BaseColumn*)ie;
      nacol = baseC->getNAColumn();
    }

  const NATable * naTable = nacol->getNATable();
  if (csl() == NULL)
    {
      NAString nas("*");
      bindWA->hbaseColUsageInfo()->insert
	((QualifiedName*)&naTable->getTableName(), &nas);
    }
  else
    {
      for (Lng32 i = 0; i < csl()->entries(); i++)
	{
	  NAString * nas = (NAString*)(*csl())[i];

	  bindWA->hbaseColUsageInfo()->insert
	    ((QualifiedName*)&naTable->getTableName(), nas);
	}
    }

  return boundExpr;
}

//---------------------------------------------------------------------------
//
// member functions for class HbaseColumnCreate
//
//---------------------------------------------------------------------------
ItemExpr *HbaseColumnCreate::bindNode(BindWA *bindWA)
{
  if (nodeIsBound())
    return getValueId().getItemExpr();

  ItemExpr * boundExpr = NULL;
  short numEntries = hccol_->entries();
  colValMaxLen_ = 0;
  NAType * firstType = NULL;
  NAType * resultType = NULL;
  NABoolean resultNull = FALSE;
  colNameMaxLen_ = 0;
  for (short i = 0; i < numEntries; i++)
    {
      HbaseColumnCreateOptions * hcco = (*hccol_)[i];
      HbaseColumnCreate::HbaseColumnCreateOptions::ConvType co = HbaseColumnCreate::HbaseColumnCreateOptions::NONE;

      ItemExpr * colName = hcco->colName();
      colName = colName->bindNode(bindWA);
      if (bindWA->errStatus()) 
        return NULL;
      
      // type cast any params
      ValueId vid1 = colName->getValueId();
      SQLVarChar c1(NULL, CmpCommon::getDefaultNumeric(HBASE_MAX_COLUMN_NAME_LENGTH));
      vid1.coerceType(c1, NA_CHARACTER_TYPE);
      
      hcco->setColName(colName);

      ItemExpr * colValue = hcco->colVal();
      colValue = colValue->bindNode(bindWA);
      if (bindWA->errStatus()) 
	return NULL;

      // type cast any params
      ValueId vid2 = colValue->getValueId();
      SQLVarChar c2(NULL, CmpCommon::getDefaultNumeric(HBASE_MAX_COLUMN_VAL_LENGTH));
      vid2.coerceType(c2, NA_CHARACTER_TYPE);

      hcco->setColVal(colValue);

      const NAType &typeColName = 
	colName->castToItemExpr()->getValueId().getType();

      const NAType &typeColVal = 
	colValue->castToItemExpr()->getValueId().getType();

      if (colNameMaxLen_ < typeColName.getNominalSize())
	colNameMaxLen_ = typeColName.getNominalSize();

      if (i == 0) // first entry
	{
	  co = hcco->convType();
	  firstType = (NAType*)hcco->naType();
	  if (firstType)
	    resultType = firstType;
	  else
	    resultType = &(NAType&)typeColVal;
	  if (resultType->getTypeQualifier() != NA_CHARACTER_TYPE)
	    {
	      *CmpCommon::diags() << DgSqlCode(-4221)
				  << DgString0("COLUMN_CREATE(list format)")
				  << DgString1("character type");
	      bindWA->setErrStatus();
	      return NULL;
	    }

	  colValMaxLen_ = resultType->getNominalSize();
	  resultNull = resultType->supportsSQLnull();
	} // if first entry
      else
	{
	  if ((co != hcco->convType()) ||
	      (! firstType && hcco->naType()) ||
	      (firstType && ! hcco->naType()) ||
	      (firstType && hcco->naType() && (NOT (*firstType == *hcco->naType()))))
	    {
	      *CmpCommon::diags() << DgSqlCode(-4221)
			       << DgString0("COLUMN_CREATE(list format)")
			       << DgString1("compatible");

	      bindWA->setErrStatus();
	      return NULL;
	    }
	} // else

      if (co == HbaseColumnCreate::HbaseColumnCreateOptions::NONE)
	{
	  if (colValMaxLen_ < typeColVal.getNominalSize())
	    colValMaxLen_ = typeColVal.getNominalSize();

	  if (typeColVal.supportsSQLnull())
	    resultNull = TRUE;
	}
    } // for

  resultNull = TRUE;
  NAType * childResultType = new(bindWA->wHeap()) SQLVarChar(bindWA->wHeap(), colValMaxLen_,
							     resultNull);
  
  Lng32 totalLen = 0;
  totalLen += sizeof(numEntries) + sizeof(colNameMaxLen_) 
    + sizeof(short)/*VCLenIndicatorSize*/ + sizeof(colValMaxLen_);
  
  for (Lng32 i = 0; i < numEntries; i++)
    {
      HbaseColumnCreateOptions * hcco = (*hccol_)[i];

      NAType * cnType = new(bindWA->wHeap()) SQLVarChar(bindWA->wHeap(), colNameMaxLen_, FALSE);
      ItemExpr * cnChild =
	new (bindWA->wHeap()) Cast(hcco->colName(), cnType);
      cnChild = cnChild->bindNode(bindWA);
      hcco->setColName(cnChild);
      totalLen += cnChild->getValueId().getType().getTotalSize();

      ItemExpr * newChild =
	new (bindWA->wHeap()) Cast(hcco->colVal(), childResultType);
      newChild = newChild->bindNode(bindWA);
      hcco->setColVal(newChild);
      totalLen += newChild->getValueId().getType().getTotalSize();      
    }

  resultType_ = new(bindWA->wHeap()) SQLVarChar(bindWA->wHeap(), totalLen, FALSE);
  
  // Binds self; Binds children; ColumnCreate::synthesize();
  boundExpr = Function::bindNode(bindWA);
  if (bindWA->errStatus()) 
    return NULL;

  return boundExpr;
}


// -----------------------------------------------------------------------
// member functions for class Loboper, LOBinsert, LOBselect, LOBdelete
// -----------------------------------------------------------------------

ItemExpr *LOBinsert::bindNode(BindWA *bindWA)
{
  ItemExpr * boundExpr = NULL;

  if (nodeIsBound())
    return getValueId().getItemExpr();

  // Binds self; Binds children; LOBoper::synthesize();
  boundExpr = LOBoper::bindNode(bindWA);
  if (bindWA->errStatus()) return NULL;
 
  return boundExpr;
} // LOBinsert::bindNode()

ItemExpr *LOBselect::bindNode(BindWA *bindWA)
{
  ItemExpr * boundExpr = NULL;

  if (nodeIsBound())
    return getValueId().getItemExpr();


  // For now LOBselect is allowed only in the top most select list
  // check that first, or else give an error


  // Binds self; Binds children; LOBoper::synthesize();
  boundExpr = LOBoper::bindNode(bindWA);
  if (bindWA->errStatus()) return NULL;
 
  return boundExpr;
} // LOBselect::bindNode()



ItemExpr *SequenceValue::bindNode(BindWA *bindWA)
{
  ItemExpr * boundExpr = NULL;

  if (nodeIsBound())
    return getValueId().getItemExpr();

  // Binds self; Binds children; SequenceValue::synthesize();
  boundExpr = Function::bindNode(bindWA);
  if (bindWA->errStatus()) 
    return NULL;

  ULng32 savedParserFlags = Get_SqlParser_Flags (0xFFFFFFFF);
  Set_SqlParser_Flags(ALLOW_VOLATILE_SCHEMA_IN_TABLE_NAME);

  // Obtain the NATable for the seq object.
  naTable_ = bindWA->getNATable(seqCorrName_);
  if (bindWA->errStatus())
    return this;

  // BindWA keeps list of sequence generators used, so privileges can be checked.
  bindWA->insertSeqVal(this);

  Assign_SqlParser_Flags (savedParserFlags);

  return boundExpr;
}

ItemExpr *HbaseTimestamp::bindNode(BindWA *bindWA)
{
  ItemExpr * boundExpr = NULL;

  CMPASSERT(col_);

  if (nodeIsBound())
    return getValueId().getItemExpr();

  col_ = col_->bindNode(bindWA);
  if (! col_ || bindWA->errStatus())
    return NULL;

  CMPASSERT(col_->getOperatorType() == ITM_BASECOLUMN);

  NAColumn * nac = ((BaseColumn*)col_)->getNAColumn();
  if (! nac)
    return NULL;

  colName_ = nac->getColName();

  NAType * tsValsType = 
    new (bindWA->wHeap()) SQLVarChar(bindWA->wHeap(), sizeof(Int64), FALSE);
  tsVals_ = 
    new (bindWA->wHeap()) NATypeToItem(tsValsType);
  
  tsVals_ = tsVals_->bindNode(bindWA);
  if (! tsVals_ || bindWA->errStatus())
    return NULL;

  // Binds self; Binds children; HbaseTimestamp::synthesize();
  boundExpr = Function::bindNode(bindWA);
  if (bindWA->errStatus()) 
    return NULL;
  
  return boundExpr;
}

ItemExpr *HbaseTimestampRef::bindNode(BindWA *bindWA)
{
  ItemExpr * boundExpr = NULL;

  CMPASSERT(col_);

  if (nodeIsBound())
    return getValueId().getItemExpr();

  col_ = col_->bindNode(bindWA);
  if (! col_ || bindWA->errStatus())
    return NULL;

  CMPASSERT(col_->getOperatorType() == ITM_BASECOLUMN);

  BaseColumn * bc = (BaseColumn*)col_;

  if ((bc->getTableDesc()->getNATable()->isHiveTable()) ||
      (bc->getTableDesc()->getNATable()->isSQLMXAlignedTable()))
    {
      if (bc->getTableDesc()->getNATable()->isHiveTable())
        *CmpCommon::diags() << DgSqlCode(-3242)
                            << DgString0("hbase_timestamp or hbase_version cannot be used on a Hive table.");
      else
        *CmpCommon::diags() << DgSqlCode(-3242)
                            << DgString0("hbase_timestamp or hbase_version cannot be used on an aligned format table.");
      
      bindWA->setErrStatus();
      return NULL;
    }

  if (bc->getTableDesc()->hbaseTSList().entries() == 0)
    {
      for (CollIndex i = 0; i < bc->getTableDesc()->getColumnList().entries(); i++) 
        {
          ItemExpr *baseCol = bc->getTableDesc()->getColumnList()[i].getItemExpr();
          HbaseTimestamp * hbtCol = 
            new (bindWA->wHeap()) HbaseTimestamp(baseCol);
          hbtCol->bindNode(bindWA);
          if (bindWA->errStatus()) 
            return NULL;
          bc->getTableDesc()->hbaseTSList().insert(hbtCol->getValueId());
        }
    }

  ValueId valId = bc->getTableDesc()->hbaseTSList()[bc->getColNumber()];
  setValueId(valId);
  
  bindSelf(bindWA);
  if (bindWA->errStatus()) 
    return NULL;
  
  return valId.getItemExpr();
}

ItemExpr *HbaseVersion::bindNode(BindWA *bindWA)
{
  ItemExpr * boundExpr = NULL;

  CMPASSERT(col_);

  if (nodeIsBound())
    return getValueId().getItemExpr();

  col_ = col_->bindNode(bindWA);
  if (! col_ || bindWA->errStatus())
    return NULL;

  CMPASSERT(col_->getOperatorType() == ITM_BASECOLUMN);

  NAColumn * nac = ((BaseColumn*)col_)->getNAColumn();
  if (! nac)
    return NULL;

  colName_ = nac->getColName();

  NAType * tsValsType = 
    new (bindWA->wHeap()) SQLVarChar(bindWA->wHeap(), sizeof(Int64), FALSE);
  tsVals_ = 
    new (bindWA->wHeap()) NATypeToItem(tsValsType);
  
  tsVals_ = tsVals_->bindNode(bindWA);
  if (! tsVals_ || bindWA->errStatus())
    return NULL;

  // Binds self; Binds children; HbaseVersion::synthesize();
  boundExpr = Function::bindNode(bindWA);
  if (bindWA->errStatus()) 
    return NULL;
  
  return boundExpr;
}

ItemExpr *HbaseVersionRef::bindNode(BindWA *bindWA)
{
  ItemExpr * boundExpr = NULL;

  CMPASSERT(col_);

  if (nodeIsBound())
    return getValueId().getItemExpr();

  col_ = col_->bindNode(bindWA);
  if (! col_ || bindWA->errStatus())
    return NULL;

  CMPASSERT(col_->getOperatorType() == ITM_BASECOLUMN);

  BaseColumn * bc = (BaseColumn*)col_;

  if ((bc->getTableDesc()->getNATable()->isHiveTable()) ||
      (bc->getTableDesc()->getNATable()->isSQLMXAlignedTable()))
    {
      if (bc->getTableDesc()->getNATable()->isHiveTable())
        *CmpCommon::diags() << DgSqlCode(-3242)
                            << DgString0("hbase_timestamp or hbase_version cannot be used on a Hive table.");
      else
        *CmpCommon::diags() << DgSqlCode(-3242)
                            << DgString0("hbase_timestamp or hbase_version cannot be used on an aligned format table.");
      
      bindWA->setErrStatus();
      return NULL;
    }

  if (bc->getTableDesc()->hbaseVersionList().entries() == 0)
    {
      for (CollIndex i = 0; i < bc->getTableDesc()->getColumnList().entries(); i++) 
        {
          ItemExpr *baseCol = bc->getTableDesc()->getColumnList()[i].getItemExpr();
          HbaseVersion * hbtCol = 
            new (bindWA->wHeap()) HbaseVersion(baseCol);
          hbtCol->bindNode(bindWA);
          if (bindWA->errStatus()) 
            return NULL;
          bc->getTableDesc()->hbaseVersionList().insert(hbtCol->getValueId());
        }
    }

  ValueId valId = bc->getTableDesc()->hbaseVersionList()[bc->getColNumber()];
  setValueId(valId);
  
  bindSelf(bindWA);
  if (bindWA->errStatus()) 
    return NULL;
  
  return valId.getItemExpr();
}

ItemExpr *RowNumFunc::bindNode(BindWA *bindWA)
{
  if (nodeIsBound())
    return getValueId().getItemExpr();

  // For now user(x) is allowed only in the top most select list
  // check that first, or else give an error

  BindScope * currScope = bindWA->getCurrentScope();
  BindContext *context = currScope->context();

  if (!(context->inSelectList()))
    //      (! context->inWhereClause()))
  {
    *CmpCommon::diags() << DgSqlCode(-4311)
			<< DgString0("ROWNUM");
    bindWA->setErrStatus();
    return NULL;
  }

  // Check for case like select (select user(1) ...).
  // or select * from t1, (select user(x) from t1) t3 etc.
  // Here the user function is in the select list of a
  // sub-query and in join, hence is not allowed.
  // Also it is not allowed at any other place example orderBy
  BindScope *prevScope   = NULL;

  while (currScope)
  {
    BindContext *currContext = currScope->context();
    if (currContext->inSubquery() ||
        currContext->inOrderBy() ||
        currContext->inExistsPredicate() ||
        currContext->inGroupByClause() ||
        currContext->inGroupByOrdinal() ||
        currContext->inWhereClause() ||
        currContext->inHavingClause() ||
        currContext->inUnion() ||
        currContext->inJoin()       )
      {
 	*CmpCommon::diags() << DgSqlCode(-4311)
			    << DgString0("ROWNUM");
	bindWA->setErrStatus();
	return NULL;
      }
    prevScope = currScope;
    currScope = bindWA->getPreviousScope(prevScope);
  }

  return BuiltinFunction::bindNode(bindWA);
} // RowNumFunc::bindNode

NABoolean ItemExpr::canBeUsedInGBorOB(NABoolean setErr)
{
  Int32 arity = getArity();
  for (Int32 i=0; i<arity; i++) 
    {
      ItemExpr *ieChild = child(i);
      if (NOT ieChild->canBeUsedInGBorOB(setErr))
        return FALSE;
    }
  
  return TRUE;
}

NABoolean RowNumFunc::canBeUsedInGBorOB(NABoolean setErr)
{
  // cannot be used in a group by or order by clause.
  if (setErr)
    {
      *CmpCommon::diags() << DgSqlCode(-4311)
                          << DgString0("ROWNUM");
    }

  return FALSE;
}
