/**********************************************************************
// @@@ 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:		BindRelExpr.C
* Description:  Relational expressions (both physical and logical operators)
*               Methods related to the SQL binder
*
* Created:      5/17/94
* Language:     C++
*
*
*
*	It is the secret sympathy,
*	The silver link, the silken tie,
*	Which heart to heart, and mind to mind,
*	In body and in soul can bind.
*		-- Sir Walter Scott,
*		   "The Lay of the Last Minstrel"
*
******************************************************************************
*/


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

#include "Platform.h"
#include "NAWinNT.h"


#include "Sqlcomp.h"
#include "AllItemExpr.h"
#include "AllRelExpr.h"
#include "BindWA.h"
#include "ComOperators.h"
#include "ComTransInfo.h"
#include "ComLocationNames.h"
#include "ControlDB.h"
#include "Debug.h"
#include "ex_error.h"
#include "GroupAttr.h"
#include "ParNameLocList.h"
#include "parser.h"
#include "Rel3GL.h"
#include "RelDCL.h"
#include "RelPackedRows.h"
#include "RelSequence.h"
#include "ShowSchema.h"           // GetControlDefaults class
#include "StmtDDLAddConstraintCheck.h"
#include "StmtDDLCreateView.h"
#include "ElemDDLColRefArray.h"
#include "ElemDDLSaltOptions.h"
#include "TrafDDLdesc.h"
#include "UdrErrors.h"
#include "SequenceGeneratorAttributes.h"

#include "wstr.h"
#include "Inlining.h"
#include "Triggers.h"
#include "TriggerDB.h"
#include "MVInfo.h"
#include "Refresh.h"
#include "ChangesTable.h"
#include "MvRefreshBuilder.h"
#include "OptHints.h"
#include "CmpStatement.h"
#include "OptimizerSimulator.h"
#include "charinfo.h"
#include "UdfDllInteraction.h"
#include "SqlParserGlobals.h"      // must be last #include
#include "ItmFlowControlFunction.h"
#include "ComSchemaName.h" // for ComSchemaName
#include "ItemSample.h"
#include "NAExecTrans.h"
#include "HDFSHook.h"
#include "CmpSeabaseDDL.h"
#include "ComUser.h"
#include "ComSqlId.h"
#include "PrivMgrCommands.h"
#include "PrivMgrComponentPrivileges.h"
#include "PrivMgrDefs.h"
#include "PrivMgrMD.h"

  #define SLASH_C '/'

NAWchar *SQLTEXTW();

// -----------------------------------------------------------------------
// external declarations
// -----------------------------------------------------------------------

// 



// -----------------------------------------------------------------------
// static functions
// -----------------------------------------------------------------------
#ifdef NDEBUG
  THREAD_P NABoolean GU_DEBUG = FALSE;
#else
  THREAD_P NABoolean GU_DEBUG;
#endif

static void GU_DEBUG_Display(BindWA *bindWA, GenericUpdate *gu,
                             const char *text,
                             RelExpr *reDown = NULL,
                             NABoolean preEndl = FALSE,
                             NABoolean postEndl = FALSE)
{
#ifndef NDEBUG
  if (!GU_DEBUG)
    return;

// LCOV_EXCL_START - dpm
  if (preEndl) cerr << endl;
  cerr << "---" << endl;

  if (gu->getTableDesc()) {
    NAString tmp;
    ValueIdList vtmp(gu->getTableDesc()->getColumnList());
    vtmp.unparse(tmp);
    cerr << gu->getUpdTableNameText() << " this>td(" << text << ") "
      << gu->getTableDesc()->getCorrNameObj().getExposedNameAsAnsiString()
      << " " << tmp << endl;
  }

  RETDesc *rd = gu->getRETDesc();
  if (rd) {
    cerr << gu->getUpdTableNameText() << " this>grd(" << text << ") " << flush;
    rd->display();
  }
  if (reDown) RETDesc::displayDown(reDown);

  if (bindWA->getCurrentScope()->getRETDesc() &&
      bindWA->getCurrentScope()->getRETDesc() != rd) {
    cerr << gu->getUpdTableNameText() << " bwa>cs>grd(" << text << ") " <<flush;
    bindWA->getCurrentScope()->getRETDesc()->display();
  }
// LCOV_EXCL_STOP

  if (postEndl) cerr << endl;
#endif
} // GU_DEBUG_Display()

#pragma nowarn(770)   // warning elimination
static RETDesc *bindRowValues(BindWA *bindWA,
                              ItemExpr *exprTree,
                              ValueIdList &vidList,
                              RelExpr *parent,
                              NABoolean inTrueRoot)
{
  // Before we convert the row value expressions into a ValueIdList, save the
  // original value expression root nodes in an ItemExprList.
  //
  ItemExprList exprList(exprTree, bindWA->wHeap());
  //
  // Bind the row value expressions and create a ValueIdList.
  //
  exprTree->convertToValueIdList(vidList, bindWA, ITM_ITEM_LIST, parent);
  if (bindWA->errStatus()) return NULL;

  // Set up context flags.
  // We are in a subquery if the previous scope's flag is set, note.
  //
  BindScope *currScope   = bindWA->getCurrentScope();
  BindScope *prevScope   = bindWA->getPreviousScope(currScope);
  NABoolean inSelectList = currScope->context()->inSelectList();
  NABoolean inInsert     = currScope->context()->inInsert();
  NABoolean inSubquery   = FALSE;
  if (prevScope)
    inSubquery = prevScope->context()->inSubquery();

  // 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;
  
  // See if ALLOW_MULTIDEGREE_SUBQ_IN_SELECTLIST is enabled. It is
  // enabled if the default is ON, or if the default is SYSTEM and
  // ALLOW_UDF is ON.
  NABoolean allowMultiDegSubqInSelect_Enabled = FALSE;
  DefaultToken allowMultiDegreeTok =
    CmpCommon::getDefault(ALLOW_MULTIDEGREE_SUBQ_IN_SELECTLIST);
  if ((allowMultiDegreeTok == DF_ON) ||
      (allowMultiDegreeTok == DF_SYSTEM))
    allowMultiDegSubqInSelect_Enabled = TRUE;
  
  //
  // Create the result table.
  // If a row value expression is not a column reference and does not have
  // a rename AS clause, the column is an unnamed expression.
  //
  RETDesc *resultTable = new (bindWA->wHeap()) RETDesc(bindWA);
  CollIndex j = 0;
  for (CollIndex i = 0; i < exprList.entries(); i++, j++) 
  {
    ItemExpr *itemExpr = (ItemExpr *) exprList[i];
    ValueId valId = itemExpr->getValueId();
    ValueId boundValId = vidList[j];
    CMPASSERT(boundValId != NULL_VALUE_ID);

    if (inSelectList && inTrueRoot &&
        (boundValId.getType().getTypeQualifier() == NA_UNKNOWN_TYPE)&&
        (boundValId.getItemExpr()->getOperatorType() == ITM_CONSTANT))
    {
      ConstValue * constItemExpr = (ConstValue*) boundValId.getItemExpr();
      if (constItemExpr->isNull())
        boundValId.coerceType(NA_NUMERIC_TYPE) ;
    }

    switch (itemExpr->getOperatorType()) 
    {
      case ITM_REFERENCE: {
        ColReference *colRef = (ColReference *) itemExpr;
        const ColRefName &colRefName = colRef->getColRefNameObj();
        CMPASSERT(valId != NULL_VALUE_ID || colRefName.isStar());

        if (colRefName.isStar()) {
          const ColumnDescList *star = colRef->getStarExpansion();
          CMPASSERT(star != NULL);
          const ColumnDescList &starExpansion = *star;
          CMPASSERT(starExpansion.entries() > 0);   // ColRef::bind chked this alrdy
          CMPASSERT(inSelectList);

          resultTable->addColumns(bindWA, starExpansion);

          j += starExpansion.entries() - 1;
        }               // isStar
        else {
          // Do another xcnm lookup so the column we add to our resultTable
          // will have its CorrName object correct
          // (e.g., in "SELECT TL.B,* FROM TA TL,TA TR ORDER BY B;"
          // colref TL.B will resolve to TL.B, not CAT.SCH.TL.B)
          // and its heading (Genesis 10-980126-5495).
          BindScope *bindScope;
          ColumnNameMap *xcnmEntry = bindWA->findColumn(colRefName, bindScope);

          if (NOT xcnmEntry)   // ## I don't recall when this case occurs...
            resultTable->addColumn(bindWA,
                                   colRefName,
                                   boundValId,
                                   colRef->getTargetColumnClass());
          else
            resultTable->addColumn(bindWA,
                                   xcnmEntry->getColRefNameObj(),
                                   boundValId,
                                   colRef->getTargetColumnClass(), // MV --
                                   xcnmEntry->getColumnDesc()->getHeading());
        }
        break;
      }
      case ITM_RENAME_COL: 
      {
        RenameCol *renameCol = (RenameCol *) itemExpr;
        const ColRefName &colRefName = *renameCol->getNewColRefName();
        CMPASSERT(NOT colRefName.isStar());

        const char * heading = NULL;

        // if this rename was for a BLOB/CLOB column from JDBC, return
        // the heading of the child base column. This is needed for JDBC
        // as it uses the heading to figure out if the column is a LOB
        // column.
        if (CmpCommon::getDefault(JDBC_PROCESS) == DF_ON)
          {
            ItemExpr * childExpr = itemExpr->child(0)->castToItemExpr();
            if (childExpr->getOperatorType() == ITM_BASECOLUMN)
              {
                heading = ((BaseColumn *)childExpr)->getNAColumn()->getHeading();

                if (heading)
                  {
                    if ((strcmp(heading, "JDBC_BLOB_COLUMN -") != 0) &&
                        (strcmp(heading, "JDBC_CLOB_COLUMN -") != 0))
                      heading = NULL;
                  }
              }
          }

        // No heading is passed here (whole point of SQL derived-column is rename)
        // unless it is a jdbc blob/clob heading.
        resultTable->addColumn(bindWA,
                               colRefName,
                               boundValId,
                               renameCol->getTargetColumnClass(),
                               heading);
        break;
      }
      case ITM_ROW_SUBQUERY: 
      case ITM_USER_DEF_FUNCTION: {

        // Deal with multi Valued User Defined Functions or Subqueries with
        // degree > 1.
        //
        // In order to have the correct degree during the bind phase,
        // since we don't have all the information until after the transform
        // phase, we need to put entries into the RETDesc early.
        //
        // Say you have a query like this:
        //    select mvf(a,b) from t1;
        // and assume mvf outputs 2 values.
        //
        // at bind time, the select list will only have 1 entry in it, namely
        // the ITM_USER_DEF_FUNCTION.
        // Since we do degree checking at bind time, we need to know now that
        // mvf() actually produces 2 values.
        //
        // So what we do here, is that we substitute the original 
        // ITM_USER_DEF_FUNCTION with ValueIdProxies. One for each output of
        // the original function. The selectList of the RelRoot as well as the
        // retDESC are updated with the additional elements.
        //
        // Similarly if we have a subquery like this:
        //
        //    select (select max(a),max(b) from t2), a from t1;
        //
        // we will wrap the subquery in a ValeIdProxy representing the 
        // subquery from a transformation point of view, but representing
        // max(a) from an output point of view. A second ValueIdProxy will be
        // added for max(b), so the select list of the outer query would look 
        // like this:
        // 
        //     [ ValueIdProxy(Subq:max(a)), ValueIdProxy(Subq:max(b)), a ]
        //
        // instead of just 
        //    
        //     [ Subq, a ]
        //
        // like we are used to.
        //
        // At transform time the valueIdProxies, will disappear and we will
        // transform the UDF/Subquery carried inside the valueIdProxy
        // marked to be transformed. Some might hang around until Normalization.
        // Only the ValueIdProxy representing the first output will be marked
        // to be transformed, so we only transform the UDF/Subquery once.
        //
        // Similarly, we update the outer query's retDESC.


        NABoolean isSubquery = 
                           (itemExpr->getOperatorType() == ITM_ROW_SUBQUERY) ? 
                           TRUE  : FALSE;

        NAColumnArray outCols;
        ValueIdList outColVids;
        CollIndex currIndex = j;

        if (isSubquery)
        {
           Subquery * subq = (Subquery *) itemExpr;
   
           const RETDesc *retDesc = subq->getSubquery()->getRETDesc();

           if( retDesc )
           {
              retDesc->getColumnList()->getValueIdList(outColVids);
           }
        }
        else
        {
           UDFunction * udf = (UDFunction *) itemExpr;
           CMPASSERT(udf->getRoutineDesc());
           const RoutineDesc *rDesc = udf->getRoutineDesc();

          
           // Get the outputs of this UDF, these are as defined in metadata
           // including names etc.
           outCols = rDesc->getEffectiveNARoutine()->getOutParams();
           outColVids = rDesc->getOutputColumnList();
        }
  
        if ( (outColVids.entries() == 1) || 
             ( isSubquery  &&
               (!allowMultiDegSubqInSelect_Enabled)
             ))
        {
           // Do exactly what we used to do if the degree is 1.
           // or we have disallowed subqueries of degree > 1.

           if (isSubquery)
           {
              // ## Here we ought to manufacture a unique name per Ansi 7.9 SR 9c.
              ColRefName colRefName;
              resultTable->addColumn(bindWA, colRefName, boundValId);
           }
           else
           {
              NAColumn *col = outCols[0];
              const char *  heading = col->getHeading();
              ColRefName colRefName( col->getColName());
              ColumnClass colClass( col->getColumnClass());

              resultTable->addColumn(bindWA, 
                                     colRefName, 
                                     boundValId,
                                     colClass,
                                     heading);
           }
           break;
        }

        // Wrap all the outputs with a ValueIdProxy
        // so that we can deal with multiple outputs
        // If we didn't have a RETDesc or a RoutineDesc, outColVids
        // will be empty and we don't do anything.

        // Also we do not need to worry about recursing through the 
        // RETDesc entries as the call to convertToValueIdList() above
        // did that already.
        for (CollIndex idx = 0; idx < outColVids.entries(); idx++)
        {

           NAColumn *col;

           NABoolean isRealOrRenameColumn = 
                 (outColVids[idx].getItemExpr()->getOperatorType() == 
                  ITM_BASECOLUMN) || 
                 (outColVids[idx].getItemExpr()->getOperatorType() == 
                  ITM_RENAME_COL) ||
                  !isSubquery     ? TRUE : FALSE;

           if (isSubquery)
           {
              col = ((NAColumn *) outColVids[idx].getItemExpr());
           }
           else
           {
              col = ((NAColumn *) outCols[idx]);
           }

           const char *  heading  = isRealOrRenameColumn ?  
                                                col->getHeading() : "";
           ColRefName colRefName( isRealOrRenameColumn ? 
                                                col->getColName() : "");
           ColumnClass colClass( isRealOrRenameColumn ? 
                                           col->getColumnClass() : USER_COLUMN);


           // We are wrapping the MVF/Subquery and its additional outputs
           // with a ValueIdProxy. This way we don't end up flattening or
           // expanding the outputs of the MVF multiple times.

           // The valueId of the RoutineParam corresponding to the 
           // metadata column is used for the output valueId.

           // So if you had a query like this:
           //
           // select swap2(a,b) from t1;
           //
           // and swap2() returns 2 outputs (basically the inputs swapped)
           //
           // The new select list for the query would be:
           //
           // 1: ValueIdProxy with the derivedNode being swap2, and output
           //    valueId containing the first output parameter of swap2.
           //    Also the transformDerivedFrom flag would be set
           // 2: ValueIdProxy with the derivedNode being swap2, and output
           //    valueId containing the second output parameter of swap2.
           //
           // These ValueIdProxy nodes will go away at transform time..

           ValueIdProxy *proxyOutput = new (CmpCommon::statementHeap())
                               ValueIdProxy( boundValId, 
                                             outColVids[idx],
                                             idx);


           // The type of the proxy is the same as the output valueId associated
           // with it.
           proxyOutput = (ValueIdProxy *) proxyOutput->bindNode(bindWA);

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

           // Make sure we transform the MVF
           if (idx == 0) proxyOutput->setTransformChild(TRUE);


           if (!isSubquery || isRealOrRenameColumn) 
           {
              resultTable->addColumn(bindWA, 
                                     colRefName, 
                                     proxyOutput->getValueId(), 
                                     colClass,
                                     heading);
   
           }
           else
           {
              resultTable->addColumn(bindWA, colRefName, 
                                     proxyOutput->getValueId());
           }

           if (idx == 0) 
           {
             vidList.removeAt(currIndex); // we need to delete the old valueId
           }
           else
             j++; // The first entry simply replaces the original
           
           // Update the list with the new value.
           // insertAt has the nice feature that it will push 
           // the residual elements to the right, so we do not need to 
           // manage the valueIds we haven't processed yet as long as we
           // update the index (j++ above) correctly.
           vidList.insertAt(currIndex++,proxyOutput->getValueId());
        }

        break;
      }

      default: 
      {
        // ## Here we ought to manufacture a unique name per Ansi 7.9 SR 9c.
        ColRefName colRefName;
        resultTable->addColumn(bindWA, colRefName, boundValId);
        break;
      }
    } // switch
  } // for

  // need this for static cursor declaration
  cmpCurrentContext->saveRetrievedCols_ = resultTable->getDegree();

  // Before we can return the result table, we need to check for the possible
  // syntax error below, in which we can't use the definition of "inSubquery"
  // that we calculate above.  Our example case is, if we're directly below
  // a GroupByAgg, then we need to look at the scope *before* the GroupByAgg
  // to determine if we satisfy the error condition below.  This is a problem
  // with how our plan trees don't sync completely with SQL syntax.
  // Here's the error case (Genesis 10-980518-0765):
  //
  //   >> select (select distinct 1,2 from T1 t) from T1;
  //
  // First of all, yes, it's a really stupid query.  Oh well!  :-)
  //
  // It's pretty clear that the "1,2" is part of a "select list inside the
  // subquery of a select list."  However, the parser creates a GroupByAgg
  // for the distinct keyword (sigh), which means that we have an
  // additional scope between the scope of the SQLRecord (1,2) and the
  // scope of the "TRUE" parent, the inner-select.  This additional scope
  // is for the GroupByAgg.  So in the case of a GroupByAgg (and possibly
  // another case will arise later ...?), we need to look at the
  // GroupByAgg's parent to determine if we satisfy this error condition.
  //
  // To recap: To handle this one (stupid) case we've added a ton of
  // comments and code here and in GroupByAgg::bindNode(), plus created
  // the new functions/members BindWA::getSubqueryScope(), and
  // BindContext::lookAboveToDecideSubquery_/().  Wonderful!
  //
  if (prevScope) {

    BindScope *subQScope = bindWA->getSubqueryScope(currScope);
    //
    // subQScope should be non-NULL when prevScope is non-NULL
    //
    CMPASSERT(subQScope);

    NABoolean inSubqueryInSelectList = subQScope->context()->inSubquery() &&
                                       subQScope->context()->inSelectList();

    NABoolean inSubqueryInGroupByClause = subQScope->context()->inSubquery() &&
                   subQScope->context()->inGroupByClause() && 
                   (CmpCommon::getDefault(UDF_SUBQ_IN_AGGS_AND_GBYS) == DF_ON);

    //10-060602-6930 Begin
    //Added a check to not enter this condition when we are in bindView scope
    if (inSelectList && 
        (inSubqueryInSelectList || 
        inSubqueryInGroupByClause) && 
        !bindWA->inViewExpansion()) {
      //10-060602-6930 End
      // We now can check for the syntax error that we've done so much work
      // above (and in GroupByAgg::bindNode(), BindWA.h & BindWA.cpp)
      // to detect:

      if ((j > 1) && 
          (!allowMultiDegSubqInSelect_Enabled) ) {
        // 4019 The select list of a subquery in a select list must be scalar
        *CmpCommon::diags() << DgSqlCode(-4019);
        bindWA->setErrStatus();
        return NULL;
      }
    }
  } // prevScope

  return resultTable;
} // bindRowValues()
#pragma warn(770)  // warning elimination

// Bind a constraint (MP Check Constraint).
// Returns NULL if error in constraint *OR* we can safely ignore the constraint
// (e.g., a NOT NULL NONDROPPABLE constraint); caller must check bindWA errsts.
//
static ItemExpr* bindCheckConstraint(
  BindWA *bindWA,
  CheckConstraint *constraint,
  const NATable *naTable,
  NABoolean catmanCollectUsages = FALSE,
  ItemExpr *viewCheckPred = NULL)
{
  ItemExpr *constraintPred = NULL;
  if (viewCheckPred) {
    // view WITH CHECK OPTION: the view's where-clause was already parsed
    // in bindView
    CMPASSERT(constraint->getConstraintText().isNull());   // sanity check
    constraintPred = viewCheckPred;
  }
  else {

    Parser parser(bindWA->currentCmpContext());
    constraintPred = parser.getItemExprTree(constraint->getConstraintText().data(),
                                            constraint->getConstraintText().length(),
                                            CharInfo::UTF8 // ComGetNameInterfaceCharSet()
                                            );

  }
  if (constraintPred) {
    ParNameLocList *saveNameLocList = bindWA->getNameLocListPtr();
    if (!catmanCollectUsages ||
        !bindWA->getUsageParseNodePtr() ||
        bindWA->getUsageParseNodePtr()->getOperatorType() == DDL_CREATE_VIEW)
      bindWA->setNameLocListPtr(NULL);

    CMPASSERT(!bindWA->getCurrentScope()->context()->inCheckConstraint());
    bindWA->getCurrentScope()->context()->inCheckConstraint() = constraint;

    constraintPred->bindNode(bindWA);
    bindWA->setNameLocListPtr(saveNameLocList);
    bindWA->getCurrentScope()->context()->inCheckConstraint() = NULL;

    if (bindWA->errStatus()) {
      delete constraintPred;
      constraintPred = NULL;
    }
  }
  // A NOT NULL constraint on a single column which never allows nulls
  // (has no null indicator bytes)
  // -- i.e., the common case of a column declared NOT NULL NONDROPPABLE --
  // does not need to be separately enforced as a constraint, because
  // Executor will raise a numeric-overflow error if someone tries to
  // put a NULL into such a column.
  //
  // So we don't need to put this constraint into the list, but we do need
  // to save its name, for run-time error diags.
  //
  // ##To be done:
  // ## GenRelUpdate DP2Insert/Update: for each col in newRecExpr(),
  // ##   if getNotNullViolationCode(), then
  // ##     save the SqlCode and the getNotNullConstraintName()...asAnsiString()
  // ##     and some column identifier (pos or offset) in some per-query struct
  // ## Executor: if error 8411, if truly a NULL violation, look up that column
  // ##   in the nnconstraint struct and populate diags with the info there.
  //
  if (constraintPred) {
    ItemExprList nncols(bindWA->wHeap());
    constraintPred->getColumnsIfThisIsISNOTNULL(nncols);
    for (CollIndex i = 0; i < nncols.entries(); i++) {
      NAColumn *nacol = nncols[i]->getValueId().getNAColumn();
      if (!nacol->getType()->supportsSQLnullPhysical()) {
        nacol->setNotNullNondroppable(constraint);
          //
          // DO *NOT* do:   delete constraintPred;
          // -- it deletes a whole tree of stuff referenced elsewhere!
          //
        constraintPred = NULL;
      } else {
        // Leaving the column's type's supportsSQLnullPhysical() as is (TRUE),
        // set its supportsSQLnullLogical() to FALSE,
        // for the Transform phase.
        nacol->mutateType()->setNullable(TRUE/*supports physical nulls*/,
                                         FALSE/*but not logical nulls */);
      }
    }
  }
  else {
    *CmpCommon::diags() << DgSqlCode(-4025)
      << DgConstraintName(ToAnsiIdentifier(constraint->getConstraintName().getObjectName()))
      << DgTableName(naTable->getTableName().getQualifiedNameAsAnsiString());
    bindWA->setErrStatus();
  }
  return constraintPred;
} // bindCheckConstraint()

// LCOV_EXCL_START - cnu
static ItemExpr *intersectColumns(const RETDesc &leftTable,
                                  const RETDesc &rightTable,
                                  BindWA* bindWA)
{
  ItemExpr *predicate = NULL;
  for (CollIndex i = 0; i < leftTable.getDegree(); i++) {
    ItemExpr *leftExpr  = leftTable.getValueId(i).getItemExpr();
    ItemExpr *rightExpr = rightTable.getValueId(i).getItemExpr();
    BiRelat *compare = new (bindWA->wHeap())
      BiRelat(ITM_EQUAL, leftExpr, rightExpr, TRUE);
    if (predicate)
      predicate = new (bindWA->wHeap()) BiLogic(ITM_AND, predicate, compare);
    else
      predicate = compare;
  }
  // Binding this predicate must be done in caller's context/scope, not here...
  return predicate;
} // intersectColumns()
// LCOV_EXCL_STOP

static ItemExpr *joinCommonColumns(const RelExpr *const leftRelExpr,
                                   const RelExpr *const rightRelExpr,
                                   BindWA* bindWA)
{
  const RETDesc &leftTable = *leftRelExpr->getRETDesc();
  const RETDesc &rightTable = *rightRelExpr->getRETDesc();
  //
  // Find the common column names between two tables and create a predicate
  // that joins the columns.  For example, if tables T1 and T2 have common
  // column names A and B, return the predicate T1.A = T2.A AND T1.B = T2.B.
  // The checking for ambiguous common columns will be done when they are
  // are coalesced for the output list.
  //
  ItemExpr *predicate = NULL;
  for (CollIndex i = 0; i < leftTable.getDegree(); i++) {
    ColRefName simpleColRefName(leftTable.getColRefNameObj(i).getColName()); //
    if (NOT simpleColRefName.isEmpty()) {                                    //
      ColumnNameMap *commonCol = rightTable.findColumn(simpleColRefName);    //
      if (commonCol) {                                                       //
        ItemExpr *leftExpr  = leftTable.getValueId(i).getItemExpr();
        ItemExpr *rightExpr = commonCol->getValueId().getItemExpr();         //

        bindWA->markAsReferencedColumn(leftExpr);

        bindWA->markAsReferencedColumn(rightExpr);

        BiRelat *compare = new (bindWA->wHeap())
        BiRelat(ITM_EQUAL, leftExpr, rightExpr);
        if (predicate)
          predicate = new(bindWA->wHeap()) BiLogic(ITM_AND, predicate, compare);
        else
          predicate = compare;
      }
    }
  }
  // Binding this predicate is being done in caller, Join::bindNode()
  return predicate;
} // joinCommonColumns()

// Functions findNonCommonColumns() and coalesceCommonColumns()
//
// These create the column descriptors for the result of a natural join.
// A natural join is equivalent to
//
// SELECT SLCC, SLT1, SLT2 FROM T1, T2
//
// where SLCC represents the list of coalesced common columns of T1 and T2,
//       SLT1 represents the list of non-common columns of T1, and
//       SLT2 represents the list of non-common columns of T2.
//
// A coalesced common column C is equivalent to
//
// COALESCE (T1.C, T2.C) AS C  -- i.e. there is no table name; CorrName is ""
//
// where COALESCE (T1.C, T2.C) is equivalent to
//
// CASE WHEN T1.C IS NOT NULL THEN T1.C ELSE T2.C END
//
// Function findNonCommonColumns(), on the first call, coalesces common
// columns into the resultTable, and collects non-common columns.
// On the second call it continues to collect non-common columns.
//
// Function coalesceCommonColumns() adds SLCC, SLT1, SLT2 to the
// resultTable in the proper order.
//
static void findNonCommonColumns(BindWA *bindWA,
                                 OperatorTypeEnum joinType,
                                 const RETDesc &sourceTable,
                                 const RETDesc &targetTable,
                                 RETDesc &resultTable,
                                 ColumnDescList &nonCommonCols)
{
  // Used for ANSI 6.4 SR 3aii below.
  CorrName implemDependCorr(bindWA->fabricateUniqueName(), TRUE);
  //
  for (CollIndex i = 0; i < sourceTable.getDegree(); i++) {
    const ColRefName &sourceColRefName = sourceTable.getColRefNameObj(i);
    ValueId sourceId = sourceTable.getValueId(i);
    ColRefName simpleColRefName(sourceColRefName.getColName());
    //
    // If a column is an unnamed expression, it is a non-common column.
    //
    if (simpleColRefName.isEmpty())
      nonCommonCols.insert(new (bindWA->wHeap())
               ColumnDesc(sourceColRefName, sourceId, NULL, bindWA->wHeap()));
    else {
      ColumnNameMap *commonCol = targetTable.findColumn(simpleColRefName);
      //
      // If the named column does not have a corresponding column in the
      // target table, it is a non-common column.
      //
      if (NOT commonCol)
        nonCommonCols.insert(new (bindWA->wHeap())
                ColumnDesc(sourceColRefName, sourceId, NULL, bindWA->wHeap()));
      //
      // If the target table has more than one corresponding column, error.
      //
      else if (commonCol->isDuplicate()) {
        NAString fmtdList(bindWA->wHeap());
        LIST(TableNameMap*) xtnmList(bindWA->wHeap());
        targetTable.getTableList(xtnmList, &fmtdList);   // Tables in the RETDesc

        *CmpCommon::diags() << DgSqlCode(-4004)
          << DgColumnName(simpleColRefName.getColName())
          << DgTableName(commonCol->getColRefNameObj().getCorrNameObj().
                                    getExposedNameAsAnsiString())
          << DgString0(fmtdList)
          << DgString1(bindWA->getDefaultSchema().getSchemaNameAsAnsiString());

        bindWA->setErrStatus();
        return;
      }
      else if (joinType != ITM_NO_OP) {
        //
        // Coalesce the common columns and add them to the result table.
        //
        ValueId resultId;
        switch(joinType) {
        case REL_JOIN:
        case REL_LEFT_JOIN:
          resultId = sourceId;
          break;
        case REL_RIGHT_JOIN:
          resultId = commonCol->getValueId();
          break;
        default: {
          ItemExpr *sourceExpr = sourceId.getItemExpr();
          ItemExpr *targetExpr = commonCol->getValueId().getItemExpr();
          UnLogic *test = new (bindWA->wHeap())
          UnLogic(ITM_IS_NULL, sourceExpr);
          ItemExpr *coalesce = new (bindWA->wHeap())
                                 Case(NULL, new (bindWA->wHeap())
                                   IfThenElse(test,
                                              targetExpr,
                                              sourceExpr));
          coalesce = coalesce->bindNode(bindWA)->castToItemExpr();
          if (bindWA->errStatus()) {
            delete test;
            delete coalesce;
            return;
          }
          resultId = coalesce->getValueId();
          break;
        } // default case (braces required since vars are initialized here)
        } // switch
        //
        // ANSI 6.4 SR 3aii:
        // We've fabricated a unique implementation-dependent CorrName
        // outside the loop; the common columns have this basically
        // invisible CorrName, the point of which seems to be that
        //   select * from
        //       ta natural join tb
        //     join			-- not natural!
        //      (ta tx natural join tb ty)
        //     on 1=1;
        // should not generate an ambiguous column reference error
        // from the star-expansion.  So according to ANSI,
        // the two natural joins produce, respectively,
        //   fab1.slcc, ta.slt1, tb.slt2
        //   fab2.slcc, tx.slt1, ty.slt2
        // so the join produces
        //   fab1.slcc, ta.slt1, tb.slt2, fab2.slcc, tx.slt1, ty.slt2
        // i.e. the two SLCC's are unambiguous.
        //
        ColRefName implemDepend(simpleColRefName.getColName(),implemDependCorr);
        resultTable.addColumn(bindWA, implemDepend, resultId);
      } // coalesce SLCC into resultTable
    } // named column
  } // for
} // findNonCommonColumns()

// Comments for this function can be found above the preceding function.
static void coalesceCommonColumns(BindWA *bindWA,
                                  OperatorTypeEnum joinType,
                                  const RETDesc &leftTable,
                                  const RETDesc &rightTable,
                                  RETDesc &resultTable)
{
  ColumnDescList nonCommonCols(bindWA->wHeap());
  // non-common columns of the left table
  //
  // Coalesce the common column names of the left and right tables and add
  // them to the result table.
  // Collect the non-common column names from the left.
  //
  findNonCommonColumns(bindWA,
    joinType,
    leftTable,
    rightTable,
    resultTable,
    nonCommonCols);
  if (bindWA->errStatus()) return;
  //
  // Collect the non-common column names from the right.
  //
  RETDesc irrelevantOnThisCall;
  findNonCommonColumns(bindWA,
    ITM_NO_OP,      // do not add SLCC to resultTable
    rightTable,
    leftTable,
    irrelevantOnThisCall,
    nonCommonCols);
  if (bindWA->errStatus()) return;
  //
  // Add the non-common columns from the left and right to the result table.
  //
  resultTable.addColumns(bindWA, nonCommonCols);
  nonCommonCols.clearAndDestroy();
  //
  // Add the system columns from the left and right to the result table.
  //
  resultTable.addColumns(bindWA, *leftTable.getSystemColumnList(), SYSTEM_COLUMN);
  resultTable.addColumns(bindWA, *rightTable.getSystemColumnList(), SYSTEM_COLUMN);
} // coalesceCommonColumns()

// For Catalog Manager, this function:
// 1) Fixes up the name location list to help with computing of the view text,
//    check constraint search condition text, etc.
// 2) Collects the table (base table, view, etc.) usages information for
//    view definitions, check constraint definitions, etc.
//
// ** Some of this could be implemented, perhaps more simply,
// ** using BindWA::viewCount() and BindWA::tableViewUsageList().
//
static void BindUtil_CollectTableUsageInfo(BindWA *bindWA,
                                           const CorrName& corrName)
{
  // Task (1)
  //
  ParNameLocList *pNameLocList = bindWA->getNameLocListPtr();
  if (pNameLocList)
  {
    ParNameLoc * pNameLoc
      = pNameLocList->getNameLocPtr(corrName.getNamePosition());
    if (pNameLoc)
    {
      if (NOT pNameLoc->getExpandedName(FALSE).isNull())
        CMPASSERT(pNameLoc->getExpandedName() ==
          corrName.getQualifiedNameObj().getQualifiedNameAsAnsiString());
      pNameLoc->setExpandedName(
                corrName.getQualifiedNameObj().getQualifiedNameAsAnsiString());
    }
    //
    // Task (2)
    //
    ExprNode *pUsageParseNode = bindWA->getUsageParseNodePtr();
    if (pUsageParseNode)
    {
      if (pUsageParseNode->getOperatorType() == DDL_CREATE_VIEW)
      {
        StmtDDLCreateView &cvpn = *pUsageParseNode->castToElemDDLNode()
          ->castToStmtDDLCreateView();
        ParTableUsageList &vtul = cvpn.getViewUsages().getViewTableUsageList();
        vtul.insert(corrName.getExtendedQualNameObj());
      }
      else if (pUsageParseNode->getOperatorType()
               == DDL_ALTER_TABLE_ADD_CONSTRAINT_CHECK)
      {
        StmtDDLAddConstraintCheck &node = *pUsageParseNode->castToElemDDLNode()
           ->castToStmtDDLAddConstraintCheck();
        ParTableUsageList &tul = node.getTableUsageList();
        tul.insert(corrName.getQualifiedNameObj());
      }
    }
  } // if (pNameLocList)

} // BindUtil_CollectTableUsageInfo()

void castComputedColumnsToAnsiTypes(BindWA *bindWA,
                                    RETDesc *rd,
                                    ValueIdList &compExpr)
{
  const ColumnDescList &cols = *rd->getColumnList();
  CollIndex i = cols.entries();
  CMPASSERT(i == compExpr.entries());

  while (i--) {
    ColumnDesc *col = cols[i];

    if (col->getValueId().getType().getTypeQualifier() == NA_ROWSET_TYPE) {
      return;
    }
    NAType *naType = &(NAType&)col->getValueId().getType();
    //
    // Note: the unsupported and DATETIME cases are mutually exclusive with the LARGEDEC case below.
    //
    if (!naType->isSupportedType()) {
      // Unsupported types are displayed as strings of '#' to their display length
      ItemExpr *theRepeat =
        new (bindWA->wHeap()) Repeat(new (bindWA->wHeap()) SystemLiteral("#"),
                                       new (bindWA->wHeap()) SystemLiteral(
                                            naType->getDisplayLength(
                                                 naType->getFSDatatype(),
                                                 0,
                                                 naType->getPrecision(),
                                                 naType->getScale(),
                                                 0)));
      theRepeat = theRepeat->bindNode(bindWA);
      col->setValueId(theRepeat->getValueId());
      compExpr[i] = theRepeat->getValueId();
    }
    else if ((CmpCommon::getDefault(MODE_SPECIAL_1) == DF_ON) &&
             (NOT bindWA->inViewDefinition()) &&
             (NOT bindWA->inMVDefinition()) &&
             (NOT bindWA->inCTAS()) &&
             (naType->getTypeQualifier()== NA_DATETIME_TYPE &&
              ((const DatetimeType *)naType)->getSubtype() == 
              DatetimeType::SUBTYPE_SQLDate) &&
             (! CmpCommon::context()->getSqlmxRegress()) &&
             (strcmp(ActiveSchemaDB()->getDefaults().getValue(OUTPUT_DATE_FORMAT),
               "ANSI") != 0))
      { // Special1 DATE, return as YY/MM/DD
        ItemExpr * newChild =
          new (bindWA->wHeap())
          Format(col->getValueId().getItemExpr(), "YY/MM/DD", FALSE);
        newChild = newChild->bindNode(bindWA);
        col->setValueId(newChild->getValueId());
        compExpr[i] = newChild->getValueId();
      }

    if ((naType->getFSDatatype() == REC_BIN64_UNSIGNED) &&
        (CmpCommon::getDefault(TRAF_LARGEINT_UNSIGNED_IO) == DF_OFF) &&
        (NOT bindWA->inCTAS()) &&
        (NOT bindWA->inViewDefinition()))
      {
        NumericType *nTyp = (NumericType *)naType;
        
        ItemExpr * cast = new (bindWA->wHeap())
          Cast(col->getValueId().getItemExpr(),
               new (bindWA->wHeap())
               SQLBigNum(MAX_HARDWARE_SUPPORTED_UNSIGNED_NUMERIC_PRECISION,
                         nTyp->getScale(),
                         FALSE,
                         FALSE,
                         naType->supportsSQLnull(),
                         NULL));
        
        cast = cast->bindNode(bindWA);
        if (bindWA->errStatus()) 
          return;
        col->setValueId(cast->getValueId());
        compExpr[i] = cast->getValueId();

        naType = (NAType*)&cast->getValueId().getType();
      }

    if ((naType->getFSDatatype() == REC_BOOLEAN) &&
        (CmpCommon::getDefault(TRAF_BOOLEAN_IO) == DF_OFF) &&
        (NOT bindWA->inCTAS()) &&
        (NOT bindWA->inViewDefinition()))
      {
        NumericType *nTyp = (NumericType *)naType;
        
        ItemExpr * cast = new (bindWA->wHeap())
          Cast(col->getValueId().getItemExpr(),
               new (bindWA->wHeap())
               SQLChar(SQL_BOOLEAN_DISPLAY_SIZE, naType->supportsSQLnull()));
        
        cast = cast->bindNode(bindWA);
        if (bindWA->errStatus()) 
          return;
        col->setValueId(cast->getValueId());
        compExpr[i] = cast->getValueId();
        
        naType = (NAType*)&cast->getValueId().getType();
      }
    
    // if OFF, return tinyint as smallint.
    // This is needed until all callers/drivers have full support to
    // handle IO of tinyint datatypes.
    if (((naType->getFSDatatype() == REC_BIN8_SIGNED) ||
         (naType->getFSDatatype() == REC_BIN8_UNSIGNED)) &&
        (NOT bindWA->inCTAS()) &&
        (NOT bindWA->inViewDefinition()) &&
        ((CmpCommon::getDefault(TRAF_TINYINT_SUPPORT) == DF_OFF) ||
         (CmpCommon::getDefault(TRAF_TINYINT_RETURN_VALUES) == DF_OFF)))
      {
        NumericType *srcNum = (NumericType*)naType; 
        NumericType * newType;
        if (srcNum->getScale() == 0)
          newType = new (bindWA->wHeap())
            SQLSmall(NOT srcNum->isUnsigned(),
                     naType->supportsSQLnull());
        else
          newType = new (bindWA->wHeap())
            SQLNumeric(sizeof(short), srcNum->getPrecision(), 
                       srcNum->getScale(),
                       NOT srcNum->isUnsigned(), 
                       naType->supportsSQLnull());

        ItemExpr * cast = new (bindWA->wHeap())
          Cast(col->getValueId().getItemExpr(), newType);

        cast = cast->bindNode(bindWA);
        if (bindWA->errStatus()) 
          return;
        col->setValueId(cast->getValueId());
        compExpr[i] = cast->getValueId();
      }
    else if (naType->getTypeQualifier() == NA_NUMERIC_TYPE && 
             !((NumericType &)col->getValueId().getType()).binaryPrecision()) {
      NumericType *nTyp = (NumericType *)naType;
      
      ItemExpr * ie = col->getValueId().getItemExpr();
      NAType *newTyp = NULL;
      Lng32 newPrec;
      Lng32 newScale;
      Lng32 oflow = -1;
      Lng32 bignumOflow = -1;
      NABoolean bignumIO = FALSE;
      if (CmpCommon::getDefault(BIGNUM_IO) == DF_ON)
        bignumIO = TRUE; // explicitely set to ON
      else if (CmpCommon::getDefault(BIGNUM_IO) == DF_OFF)
        bignumIO = FALSE; // explicitely set to OFF
      else if (CmpCommon::getDefault(BIGNUM_IO) == DF_SYSTEM)
        {
          if ((nTyp->isBigNum()) &&
              (((SQLBigNum*)nTyp)->isARealBigNum()))
            bignumIO = TRUE;
        }

      if (CmpCommon::getDefaultNumeric(MAX_NUMERIC_PRECISION_ALLOWED) ==
          MAX_HARDWARE_SUPPORTED_SIGNED_NUMERIC_PRECISION)
        bignumIO = FALSE;

      if (bignumIO)
        bignumOflow = nTyp->getPrecision() - 
          (Lng32)CmpCommon::getDefaultNumeric(MAX_NUMERIC_PRECISION_ALLOWED);
      else
        {
          if (nTyp->isSigned())
            oflow = nTyp->getPrecision() - MAX_HARDWARE_SUPPORTED_SIGNED_NUMERIC_PRECISION;
          else
            oflow = nTyp->getPrecision() - MAX_HARDWARE_SUPPORTED_UNSIGNED_NUMERIC_PRECISION;
        }

      if ((bignumOflow > 0) || (oflow > 0))
        {
          if (bignumOflow > 0) {
            newPrec = 
              (Lng32)CmpCommon::getDefaultNumeric(MAX_NUMERIC_PRECISION_ALLOWED);
            Lng32 orgMagnitude = nTyp->getPrecision() - nTyp->getScale();
        
            // set the newScale
            // IF there is overflow in magnitude set the scale to 0.
            // ELSE set the accomodate the magnitude part and truncate the scale
            newScale = (orgMagnitude >= newPrec) ? 0 : newPrec - orgMagnitude ;

            if (newScale > newPrec)
              {
                *CmpCommon::diags() << DgSqlCode(-3015) 
                                    << DgInt0(newScale) << DgInt1(newPrec);

                bindWA->setErrStatus();
                return;
              }

            newTyp = new (bindWA->wHeap())
              SQLBigNum(newPrec,
                        newScale,
                        ((SQLBigNum &)col->getValueId().getType()).isARealBigNum(),
                        nTyp->isSigned(),
                        nTyp->supportsSQLnull(),
                        NULL);
          }
          else if (oflow > 0) {
            // If it's not a computed expr, but a column w/ a legal type, re-loop
            if (col->getValueId().getNAColumn(TRUE/*don't assert*/)) {
              //CMPASSERT(!nTyp->isInternalType());
              //continue;
            }
            
            OperatorTypeEnum op = ie->origOpType();
            CMPASSERT(op != NO_OPERATOR_TYPE &&      // Init'd correctly?
                      op != ITM_RENAME_COL &&      // Expect these to have
                      op != ITM_REFERENCE);      // been bound, vanished.
            
            ItemExpr *ie2 = ie;
	    
            while (op == ITM_INSTANTIATE_NULL)
            {
              ie2 = ie2->child(0).getPtr();
              op = ie2->origOpType();
            }

            // ANSI 6.5 SR 7 - 9:  aggregates must be exact if column is exact.
            newPrec  = MAX_NUMERIC_PRECISION;
            Lng32 orgMagnitude = (nTyp->getMagnitude() + 9) / 10;
            // set the newScale
            // IF there is overflow in magnitude set the scale to 0.
            // ELSE set the accomodate the magnitude part and truncate the scale
            newScale = (orgMagnitude >= newPrec) ? 0 : newPrec - orgMagnitude ;
            
            // Based on the CQD set the scale to MIN value.
            // CQD specifies the MIN scale that has to be preserved in case
            // of overflow.
            NADefaults &defs = ActiveSchemaDB()->getDefaults();
            Lng32 minScale = defs.getAsLong(PRESERVE_MIN_SCALE);
            newScale = MAXOF(minScale, newScale);
            
            if (op == ITM_SUM || op == ITM_AVG) {
              // AVG = DIVIDE( SUM(), COUNT() )
              ItemExpr *tmp = (op == ITM_SUM) ?
                ie2 : ie2->child(0).getPtr();

              //
              // Now that we support OLAP functions, this may be
              // a pointer to an ITM_NOTCOVERED node.  If so, we
              // need to check its child(0) node rather than 
              // the ITM_NOTCOVERED node.
              //
              if (tmp->getOperatorType() == ITM_NOTCOVERED )
                  tmp = (Aggregate *)(ItemExpr *)tmp->child(0);

              CMPASSERT(tmp->isAnAggregate());
              Aggregate *sum = (Aggregate *)tmp;
              ItemExpr *arg = (sum->getOriginalChild()) ?
                sum->getOriginalChild()  : sum->child(0).getPtr();
              if (arg->getValueId() == NULL_VALUE_ID)
                arg = sum->child(0).getPtr();
              CMPASSERT(arg->getValueId() != NULL_VALUE_ID);
              Lng32 needScale = arg->getValueId().getType().getScale();
              if (needScale > newPrec)
                needScale = newPrec;
              if (newScale < needScale || op == ITM_SUM) // ANSI 6.5 SR 9 b + c
                newScale = needScale;
            }
            
            if (newScale == 0)
              newTyp = new (bindWA->wHeap())
                         SQLLargeInt(TRUE, // hardware only supports signed
                                     nTyp->supportsSQLnull());
            else
              newTyp = new (bindWA->wHeap())
                         SQLNumeric(sizeof(Int64),
                                    newPrec,
                                    newScale,
                                    nTyp->isSigned(),
                                    nTyp->supportsSQLnull());
            
          } // overflow
          
          ItemExpr *cast = new (bindWA->wHeap())
                             Cast(ie, newTyp, ITM_CAST, TRUE/*checkForTrunc*/);
          cast = cast->bindNode(bindWA);
          if (bindWA->errStatus()) return;
          
          if (!col->getColRefNameObj().getColName().isNull()) {
            // We get here via CREATE VIEW v AS SELECT (expr op expr) AS nam ...;
            
            // ColumnDesc::setValueId() makes the RETDesc's XCNM inconsistent --
            // but this is ok because name lookup over this XCNM doesn't happen
            // after the point we've gotten to here --
            // a) if caller is StmtDDLCreateView::bindNode via RelRoot::bindNode,
            //    there's no further lookup at all;
            // b) if caller is bindView(), then thanks to the way RenameTable
            //    and RETDesc work, the inconsistent XCNM is not consulted
            //    so we don't have to worry about this issue ... (for now anyhow!)
          }
          col->setValueId(cast->getValueId());
          compExpr[i] = cast->getValueId();
        } // overflow (bignum or regular)
    }   // numeric
  }   // loop over cols in RETDesc
}   // castComputedColumnsToAnsiTypes()

TrafDesc *generateSpecialDesc(const CorrName& corrName)
{
  TrafDesc * desc = NULL;

  if (corrName.getSpecialType() == ExtendedQualName::VIRTUAL_TABLE)
    {
      if (corrName.getQualifiedNameObj().getObjectName() == ExplainFunc::getVirtualTableNameStr())
        {
          ExplainFunc ef;
          desc = ef.createVirtualTableDesc();
        }
      else if (corrName.getQualifiedNameObj().getObjectName() == StatisticsFunc::getVirtualTableNameStr())
        {
          StatisticsFunc sf;
          desc = sf.createVirtualTableDesc();
        }
      else if (corrName.getQualifiedNameObj().getObjectName() == ExeUtilRegionStats::getVirtualTableNameStr())
        {
          ExeUtilRegionStats eudss;
          desc = eudss.createVirtualTableDesc();
        }
      else if (corrName.getQualifiedNameObj().getObjectName() == ExeUtilRegionStats::getVirtualTableClusterViewNameStr())
        {
          ExeUtilRegionStats eudss(TRUE);
          desc = eudss.createVirtualTableDesc();
        }
      else if (HiveMDaccessFunc::isHiveMD(corrName.getQualifiedNameObj().getObjectName()))
        {
          NAString mdType = 
            HiveMDaccessFunc::getMDType(corrName.getQualifiedNameObj().getObjectName());

          HiveMDaccessFunc hivemd(&mdType);
          desc = hivemd.createVirtualTableDesc();
        }
    }

  return desc;
} // generateSpecialDesc()


// -----------------------------------------------------------------------
// member functions for class BindWA
// -----------------------------------------------------------------------
NARoutine *BindWA::getNARoutine ( const QualifiedName &name )
{
  NARoutineDBKey key(name, wHeap());
  NARoutine * naRoutine = getSchemaDB()->getNARoutineDB()->get(this, &key);
  if (!naRoutine)
  {
     TrafDesc *udfMetadata = NULL;
     CmpSeabaseDDL cmpSBD(STMTHEAP);
     udfMetadata =  cmpSBD.getSeabaseRoutineDesc(
				       name.getCatalogName(),
				       name.getSchemaName(),
				       name.getObjectName());
     if (!udfMetadata)
       return NULL;

     NAHeap *routineHeap;
     if (getSchemaDB()->getNARoutineDB()->cachingMetaData()) 
     {
       const Lng32 size = 16 * 1024;  // The initial size
       routineHeap = new CTXTHEAP NAHeap("NARoutine Heap", (NAHeap *)CTXTHEAP, 
                                         size);
       routineHeap->setJmpBuf(CmpInternalErrorJmpBufPtr);
     }
     else 
       routineHeap=CmpCommon::statementHeap(); 

     Int32 errors=0;
     naRoutine = new (routineHeap)
       NARoutine(name,
                 udfMetadata, 
                 this,
                 errors,
                 routineHeap);
     if ( NULL == naRoutine || errors != 0)
     {
       setErrStatus();
       return NULL;
     }
     
     // Add NARoutine to the NARoutineDB cache.
     if (getSchemaDB()->getNARoutineDB()->cachingMetaData()) 
       getSchemaDB()->getNARoutineDB()->put(naRoutine);
  }
  return naRoutine;
}

NATable *BindWA::getNATable(CorrName& corrName,
                            NABoolean catmanCollectTableUsages, // default TRUE
                            TrafDesc *inTableDescStruct)     // default NULL
{
  BindWA *bindWA = this;   // for coding convenience

  NATable * table = NULL;
  // Search in volatile schema first. If not found, search in regular cat/sch.
  NABoolean volatileTableFound = FALSE;
  NAString userName;
  if ((CmpCommon::context()->sqlSession()->volatileSchemaInUse()) &&
      (! inTableDescStruct) &&
      (corrName.getSpecialType() != ExtendedQualName::VIRTUAL_TABLE) &&
      (corrName.getSpecialType() != ExtendedQualName::HBMAP_TABLE))
    {
      CorrName newCorrName = 
        CmpCommon::context()->sqlSession()->getVolatileCorrName
          (corrName);
      if (bindWA->errStatus())
        return NULL;

      //get NATable from cache
      table = bindWA->getSchemaDB()->getNATableDB()->
        get(newCorrName, bindWA, inTableDescStruct);
      if (!table)
        {
          // now search in regular cat/sch.
          // clear diags area.
          CmpCommon::diags()->clear();
          bindWA->resetErrStatus();
        }
      else
        {
          NABoolean isValid = 
            CmpCommon::context()->sqlSession()->validateVolatileCorrName
            (corrName);

          // if this table is found in volatile schema, then
          // make sure it is a volatile table.
          if ((isValid) &&
              (NOT table->isVolatileTable()))
            {
              *CmpCommon::diags() << DgSqlCode(-4190) <<
                                     DgTableName(table->getTableName().
                                       getQualifiedNameAsAnsiString(TRUE));
              
              bindWA->setErrStatus();
              return NULL;
            }

          if (isValid)
            {
              newCorrName.setIsVolatile(TRUE);
              corrName = newCorrName;
            }
          else
            {
              // table was found in the volatile schema but it is
              // not a valid volatile name.
              // Look for it in regular schema.
              table = NULL;

              CmpCommon::diags()->clear();
              bindWA->resetErrStatus();

              // remember that volatile table was found so we
              // can generate a better error message later.
              volatileTableFound = TRUE;
            }
        }
    }

  if (! table)
    {
      // Expand the table (base table, view, etc.) name with
      // the default catalog and schema parts if the specified
      // table name does not include these parts.
      // This method will also first apply any prototype value (from a host var)
      // into the corrName's qualifiedName.
      //

      NABoolean catNameSpecified =
              (NOT corrName.getQualifiedNameObj().getCatalogName().isNull());
      NABoolean schNameSpecified =
              (NOT corrName.getQualifiedNameObj().getSchemaName().isNull());

     // try PUBLIC SCHEMA only when no schema was specified
      // and CQD PUBLIC_SCHEMA_NAME is specified
      NAString publicSchema = "";
      CmpCommon::getDefault(PUBLIC_SCHEMA_NAME, publicSchema, FALSE);
      ComSchemaName pubSchema(publicSchema);
      NAString pubSchemaIntName = "";
      if ( !schNameSpecified && !pubSchema.getSchemaNamePart().isEmpty() )
      {
        pubSchemaIntName = pubSchema.getSchemaNamePart().getInternalName();
      }

      corrName.applyDefaults(bindWA, bindWA->getDefaultSchema());
      if (bindWA->errStatus())
        return NULL;      // prototype value parse error

      // cannot use hbase map schema as table name
      if ((corrName.getQualifiedNameObj().getSchemaName() == HBASE_EXT_MAP_SCHEMA) &&
          (! Get_SqlParser_Flags(INTERNAL_QUERY_FROM_EXEUTIL)) &&
          (! Get_SqlParser_Flags(ALLOW_SPECIALTABLETYPE)))
         {
          *CmpCommon::diags() << DgSqlCode(-4261)
                              << DgSchemaName(corrName.getQualifiedNameObj().getSchemaName());
          
          bindWA->setErrStatus();
          return NULL;
        }

      // if this is an HBase mapped table and schema name is not specified, 
      // then set schema to hbase map schema.
      if ((corrName.getSpecialType() == ExtendedQualName::HBMAP_TABLE) &&
          (NOT schNameSpecified))
        {
          corrName.getQualifiedNameObj().setSchemaName(HBASE_EXT_MAP_SCHEMA);
        }
 
      // override schema
      if ( ( overrideSchemaEnabled() )
           // not volatile table
        && ( ! volatileTableFound ) 
        )
      {
        doOverrideSchema(corrName);
      }

      // if DEFAULT_SCHEMA_ACCESS_ONLY, can only access default and public schemas
      if (corrName.getSpecialType()==ExtendedQualName::NORMAL_TABLE) 
                                    // NORMAL_TABLE also covers synonym, view and MV
      {
        if (violateAccessDefaultSchemaOnly(corrName.getQualifiedNameObj()))
          return NULL;
      }

      // make sure that schema name is not a VOLATILE SCHEMA
      if ((! bindWA->inDDL()) ||
          ((bindWA->inViewDefinition()) ||
           (bindWA->inMVDefinition())))
      {
        if (! CmpCommon::context()->sqlSession()->validateVolatileQualifiedSchemaName
            (corrName.getQualifiedNameObj()))
        {
          bindWA->setErrStatus();
          return NULL;
        }
      }

      //get NATable (from cache or from metadata)
      table = bindWA->getSchemaDB()->getNATableDB()->
                                     get(corrName, bindWA, inTableDescStruct);

      //try the public schema if not found
      if ( !table && !pubSchemaIntName.isNull() )
      {
        CorrName pCorrName(corrName);
        pCorrName.getQualifiedNameObj().setSchemaName(pubSchemaIntName);
        if ( !pubSchema.getCatalogNamePart().isEmpty() )
        {
          pCorrName.getQualifiedNameObj().setCatalogName(
            pubSchema.getCatalogNamePart().getInternalName());
        }

        bindWA->resetErrStatus();
        table = bindWA->getSchemaDB()->getNATableDB()->
                                       get(pCorrName, bindWA, inTableDescStruct);
        if ( !bindWA->errStatus() && table )
        { // if found in public schema, do not show previous error
          // and replace corrName
          CmpCommon::diags()->clear();
          corrName.getQualifiedNameObj().setCatalogName(
            pCorrName.getQualifiedNameObj().getCatalogName());
          corrName.getQualifiedNameObj().setSchemaName(
            pCorrName.getQualifiedNameObj().getSchemaName());
        }
      }

      // if sch name was not specified and table is not found in default schema, then
      // look for it in HBase mapped schema.
      if ( !table && ! schNameSpecified)
        {
          CorrName pCorrName(corrName);
          pCorrName.getQualifiedNameObj().setSchemaName(HBASE_EXT_MAP_SCHEMA);
          
          bindWA->resetErrStatus();
          Lng32 diagsMark = CmpCommon::diags()->mark();
          table = bindWA->getSchemaDB()->getNATableDB()->
            get(pCorrName, bindWA, inTableDescStruct);
          if ( !bindWA->errStatus() && table )
            { // if found in mapped schema, do not show previous error
              // and replace corrName
              CmpCommon::diags()->clear();
              corrName.getQualifiedNameObj().setCatalogName(
                   pCorrName.getQualifiedNameObj().getCatalogName());
              corrName.getQualifiedNameObj().setSchemaName(
                   pCorrName.getQualifiedNameObj().getSchemaName());
            }
          else
            {
              // discard the errors from failed map table name lookup and only return
              // the previous error.
              CmpCommon::diags()->rewind(diagsMark);
            }
         }

      // move to here, after public schema try because BindUtil_CollectTableUsageInfo
      // saves table info for mv definition, etc.
      // Conditionally (usually) do stuff for Catalog Manager (static func above).
      if (catmanCollectTableUsages)
        if (corrName.getSpecialType() != ExtendedQualName::TRIGTEMP_TABLE)
          BindUtil_CollectTableUsageInfo(bindWA, corrName); 

      if (!table)
        {
          if (volatileTableFound) 
            {
              if ((CmpCommon::diags()->mainSQLCODE() == -1003) &&
                  (NOT catNameSpecified))
                {
                  // the name is in true USER_NAME.VOL_TAB_NAME form
                  // where the USER_NAME doesn't match current name.
                  // Clear errors and return an appropriate message.
                  CmpCommon::diags()->clear();
                  CmpCommon::context()->sqlSession()->validateVolatileCorrName
                    (corrName);
                  bindWA->setErrStatus();
                }
            }
          
          return NULL;
        }
    }

  // if a volatile table is found, make sure that volatile schema is in
  // use and volatile tables are allowed.
  if ((table) && (table->isVolatileTable()))
    {
      // set volatile table indication in table's tablename
      ((QualifiedName&)(table->getTableName())).setIsVolatile(TRUE);
    }
      
  // For now, don't allow access through the Trafodion external name created for
  // native HIVE or HBASE objects unless the allowExternalTables flag is set.  
  // allowExternalTables is set for drop table and SHOWDDL statements.  
  // TDB - may want to merge the Trafodion version with the native version.
  if ((table) && 
      (table->isExternalTable() && 
       (NOT table->getTableName().isHbaseMappedName()) &&
       (! bindWA->allowExternalTables())))    
    {
      *CmpCommon::diags() << DgSqlCode(-4258)
			  << DgTableName(table->getTableName().getQualifiedNameAsAnsiString());
      
      bindWA->setErrStatus();
      return NULL;
    }
  
  // If the table is an external table and has an associated native table, 
  // check to see if the external table structure still matches the native table.
  // If not, return an error
  if ((table) && table->isExternalTable() &&
      (NOT table->getTableName().isHbaseMappedName()))
    {
      NAString adjustedName =ComConvertTrafNameToNativeName 
           (table->getTableName().getCatalogName(),
            table->getTableName().getUnqualifiedSchemaNameAsAnsiString(),
            table->getTableName().getUnqualifiedObjectNameAsAnsiString()); 
        
      // Get a description of the associated Trafodion table
      Int32 numNameParts = 3;
      QualifiedName adjustedQualName(adjustedName,numNameParts,STMTHEAP, bindWA);
      CorrName externalCorrName(adjustedQualName, STMTHEAP);
      NATable *nativeNATable = bindWA->getSchemaDB()->getNATableDB()->
                                  get(externalCorrName, bindWA, inTableDescStruct);
      if ((bindWA->externalTableDrop()) &&
          (bindWA->errStatus()))
        {
          return NULL;
        }
      
      // Compare column lists
      // TBD - return what mismatches
      if ( nativeNATable && 
           !(table->getNAColumnArray() == nativeNATable->getNAColumnArray()) &&
           (NOT bindWA->externalTableDrop()))
        {
          *CmpCommon::diags() << DgSqlCode(-3078)
                              << DgString0(adjustedName)
                              << DgTableName(table->getTableName().getQualifiedNameAsAnsiString());
          bindWA->setErrStatus();
          nativeNATable->setRemoveFromCacheBNC(TRUE);
          return NULL;
        }
    }
  
  HostVar *proto = corrName.getPrototype();
  if (proto && proto->isPrototypeValid())
    corrName.getPrototype()->bindNode(bindWA);

  // This test is not "inAnyConstraint()" because we DO want to increment
  // the count for View With Check Option constraints.
  if (!getCurrentScope()->context()->inTableCheckConstraint() &&
      !getCurrentScope()->context()->inRIConstraint())
    table->incrReferenceCount();

  if (table)
    OSIM_captureTableOrView(table);

  return table;
} // BindWA::getNATable()

NATable *BindWA::getNATableInternal(
     CorrName& corrName,
     NABoolean catmanCollectTableUsages, // default TRUE
     TrafDesc *inTableDescStruct,     // default NULL
     NABoolean extTableDrop)
{
  ULng32 savedParserFlags = Get_SqlParser_Flags (0xFFFFFFFF);
  Set_SqlParser_Flags(ALLOW_VOLATILE_SCHEMA_IN_TABLE_NAME);
  Set_SqlParser_Flags(INTERNAL_QUERY_FROM_EXEUTIL);
  
  setAllowExternalTables(TRUE);
  if (extTableDrop)
    setExternalTableDrop(TRUE);

  NATable * nat = 
    getNATable(corrName, catmanCollectTableUsages, inTableDescStruct);

  // Restore parser flags settings to what they originally were
  Assign_SqlParser_Flags (savedParserFlags);
  setAllowExternalTables(FALSE);
  setExternalTableDrop(FALSE);

  return nat;
}

static TableDesc *createTableDesc2(BindWA *bindWA,
                                   const NATable *naTable,
                                   CorrName &corrName, Hint *hint)
{
  // Allocate a base table descriptor.
  //
  TableDesc *tdesc = new (bindWA->wHeap()) TableDesc(bindWA, naTable, corrName);

  // Insert the table name into the XTNM.
  //
  bindWA->getCurrentScope()->getXTNM()->insertNames(bindWA, corrName);
  if (bindWA->errStatus()) return NULL;

  // For each NAColumn, allocate a BaseColumn, bind the BaseColumn, and
  // add the ValueId to the TableDesc.
  //
  CollIndex i = 0;
  for (i = 0; i < naTable->getColumnCount(); i++) {
    BaseColumn *baseCol = new (bindWA->wHeap()) BaseColumn(tdesc, i);
    baseCol->bindNode(bindWA);
    if (bindWA->errStatus()) 
      return NULL;
    ValueId valId = baseCol->getValueId();
    tdesc->addToColumnList(valId);
  }

  // set primary key for this table
  tdesc->setPrimaryKeyColumns();

  // For each index, create an IndexDesc.
  //

  NAString indexChoice;
  NADefaults &defs = ActiveSchemaDB()->getDefaults();
  defs.getValue(HIDE_INDEXES,indexChoice);

  for (i = 0; i < naTable->getIndexList().entries(); i++)
  {
      NAFileSet *nfs=naTable->getIndexList()[i];
      
      IndexDesc *idesc = new (bindWA->wHeap())
        IndexDesc(tdesc, nfs, bindWA->currentCmpContext());

      if (naTable->getClusteringIndex()->getFileSetName() ==
          idesc->getIndexName()) {
        tdesc->setClusteringIndex(idesc);
        idesc->markAsClusteringIndex();
      }
      
      if(indexChoice.compareTo("NONE") ==0
         OR indexChoice.compareTo("VERTICAL") ==0
         OR (indexChoice.compareTo("KEYINDEXES") ==0 AND
         tdesc->isKeyIndex(idesc))
         OR naTable->getClusteringIndex()->getFileSetName() ==
            nfs->getFileSetName())
      {
          tdesc->addIndex(idesc);
          // implementation of optimizer hints
          if (hint AND hint->hasIndexHint
              (idesc->getNAFileSet()->getExtFileSetName()))
          {
            tdesc->addHintIndex(idesc);
          }
      if (idesc->isUniqueIndex() )
        tdesc->addUniqueIndex(idesc);
      }
      else
      {
        delete idesc;
      }

  }

  // For each vertical partition, create an IndexDesc.
  // Add this VP to the list of VPs for the TableDesc.
 for (i = 0; i < naTable->getVerticalPartitionList().entries(); i++) {
    if(indexChoice.compareTo("NONE") ==0
       OR indexChoice.compareTo("INDEXES")==0
       OR indexChoice.compareTo("KEYINDEXES")==0)
      {
        IndexDesc *idesc = new (bindWA->wHeap())
            IndexDesc(tdesc, naTable->getVerticalPartitionList()[i],
                     bindWA->currentCmpContext());
        tdesc->addVerticalPartition(idesc);
      }
  }

  // Allocate a RETDesc, attach it to the BindScope.
  //
  bindWA->getCurrentScope()->setRETDesc(new (bindWA->wHeap())
    RETDesc(bindWA, tdesc));

  // Do not include tables-referenced-in-a-constraint (when/if we allow them)
  // in the view-contains-table list; if we did include them, then
  // TableViewUsageList::getViewsOnTable() would give wrong results
  // for where it's used to prevent the Halloween problem.
  //
  // If we end up needing this extra info, I advise either a separate list,
  // or a new field in TableViewUsage indicating usage type (containment
  // versus reference), enhancing method getViewsOnTable() accordingly.
  //
  if (!bindWA->getCurrentScope()->context()->inAnyConstraint())
    bindWA->tableViewUsageList().insert(new (bindWA->wHeap())
      TableViewUsage(
           tdesc->getCorrNameObj().getQualifiedNameObj(),
           tdesc->getCorrNameObj().getSpecialType(),
           naTable->getViewText() != NULL,
           bindWA->viewCount()));

  return tdesc;

} // static createTableDesc2()

TableDesc *BindWA::createTableDesc(const NATable *naTable,
                                   CorrName &corrName,
                                   NABoolean catmanCollectUsages, Hint *hint)
{
  BindWA *bindWA = this;  // for coding convenience

  TableDesc *tdesc = createTableDesc2(bindWA, naTable, corrName, hint);
  if (bindWA->errStatus()) return NULL;

  // Now bind any table check constraints and attach them to our new tdesc.
  // These constraints must be processed for UPDATE and INSERT.
  // DELETEs must clear them; see Delete::bindNode.
  //
  // For SELECTs, NOT NULL constraints are marked on the NAColumn::allowsNulls
  // allowing more elaborate Transformations.  For SELECTs, other types of
  // constraints are not currently used, but could be in future,
  // to optimize by providing additional predicate/selectivity info.
  //
  // ## We ought to write some regression test cases like
  //	INSERT INTO T (SELECT * FROM S)	-- T's constraints yes, S irrelevant
  //	INSERT INTO T VALUES ((SELECT A FROM S WHERE..),..)
  //	INSERT INTO V3 ...	-- underlying basetbl's constrts yes
  //				-- V3 atop VA atop T: let the views be
  //				-- WITH CHECK OPTION, then viewpred-constrt yes
  //
  const CheckConstraintList &ccl = naTable->getCheckConstraints();
  if (ccl.entries()) {

    // Table check constraint text is stored in the metadata tables
    // with the underlying table/view name (e.g. "CHECK (C.S.T.COL > 0)"),
    // whereas any correlation name in a query
    // (e.g. "SELECT * FROM C.S.T FOO WHERE COL < 10")
    // is irrelevant to the persistent constraint text --
    // when binding the check constraint, we want to find column C.S.T.COL,
    // while the TableDesc/RETDesc just built only exposes the column
    // under names COL and FOO.COL.
    //
    // So, if we have a correlation name, we must:
    // - rename our TableDesc (rename FOO to C.S.T)
    // - create a temporary table name scope for C.S.T that will hide FOO
    // - construct a temporary RETDesc with names COL, T.COL, S.T.COL, C.S.T.COL
    //   but the same ValueId's they had before
    //
    // Then we bind the constraints using that RETDesc for name lookups.
    //
    // Then for the non-empty correlation, reset/undo the temporary stuff.

    RETDesc *savedRETDesc = NULL;
    NABoolean corrNameIsNonEmpty = !corrName.getCorrNameAsString().isNull();
    CorrName synonymReferenceCorrName; 

    if(naTable->getIsSynonymTranslationDone()){
      QualifiedName baseQualifiedName(naTable->getSynonymReferenceName(),3);
      synonymReferenceCorrName=baseQualifiedName; 
    }
   
    if ((corrNameIsNonEmpty) || (naTable->getIsSynonymTranslationDone())) {
      
      CorrName baseCorrName;
      baseCorrName = (naTable->getIsSynonymTranslationDone()) ? synonymReferenceCorrName : naTable->getTableName();

      tdesc->setCorrName(baseCorrName);

      bindWA->getCurrentScope()->xtnmStack()->createXTNM();
      bindWA->getCurrentScope()->getXTNM()->insertNames(bindWA, baseCorrName);
      if (bindWA->errStatus()) return NULL;

      savedRETDesc = bindWA->getCurrentScope()->getRETDesc();
      bindWA->getCurrentScope()->setRETDesc(new (bindWA->wHeap())
      RETDesc(bindWA, tdesc));
      if (bindWA->errStatus()) return NULL;
    }

    for (CollIndex i = 0; i < ccl.entries(); i++) {
      ItemExpr *constraintPred =
        bindCheckConstraint(bindWA, ccl[i], naTable, catmanCollectUsages);
      if (constraintPred)
        tdesc->addCheckConstraint(bindWA, naTable, ccl[i], constraintPred);
      else if (bindWA->errStatus())
        break;
    }

    if ((corrNameIsNonEmpty) || (naTable->getIsSynonymTranslationDone())){  // reset temporaries
      tdesc->setCorrName(corrName);
      delete bindWA->getCurrentScope()->getRETDesc();
      bindWA->getCurrentScope()->setRETDesc(savedRETDesc);
      bindWA->getCurrentScope()->xtnmStack()->removeXTNM();
    }
  } // check constraint processing required

  // if the table contains computed columns, bind the expressions to compute the columns
  for (CollIndex c = 0; c < naTable->getColumnCount(); c++) {
    NAColumn *nac = tdesc->getNATable()->getNAColumnArray()[c];

    if (nac->isComputedColumn()) {
        ItemExpr *computedColumnExpr = NULL;
        Parser parser(bindWA->currentCmpContext());

        // parse the text stored in the NAColumn
        computedColumnExpr = parser.getItemExprTree(
             nac->getComputedColumnExprString(),
             str_len(nac->getComputedColumnExprString()),
             CharInfo::UTF8);

        if (computedColumnExpr) {
          ParNameLocList *saveNameLocList = bindWA->getNameLocListPtr();
          bindWA->setNameLocListPtr(NULL);
          bindWA->getCurrentScope()->context()->inComputedColumnExpr() = TRUE;
          
          computedColumnExpr = computedColumnExpr->bindNode(bindWA);

          bindWA->setNameLocListPtr(saveNameLocList);
          bindWA->getCurrentScope()->context()->inComputedColumnExpr() = FALSE;
         
          if (bindWA->errStatus()) {
            delete computedColumnExpr;
            computedColumnExpr = NULL;
            return NULL;
          }
          else {
            // Store the expression tree in the base column
            ((BaseColumn *) tdesc->getColumnList()[c].getItemExpr())->
              setComputedColumnExpr(computedColumnExpr->getValueId());
          }
        }
    }
  }

  return tdesc;

} // BindWA::createTableDesc()


// QSTUFF - helper for BindWA::bindView.
static void propagateDeleteAndStream(RelExpr *re, GroupAttributes *ga)
{
  if (ga->isEmbeddedUpdateOrDelete())
    re->getGroupAttr()->setEmbeddedIUD(
      ga->getEmbeddedIUD());

  if (ga->isStream())
    re->getGroupAttr()->setStream(TRUE);

  if (ga->isSkipInitialScan())
    re->getGroupAttr()->setSkipInitialScan(TRUE);

  Int32 arity = re->getArity();
  for (Int32 i = 0; i < arity; i++) {
    if (re->child(i))
      propagateDeleteAndStream(re->child(i), ga);
  }
}

RelExpr *BindWA::bindView(const CorrName &viewName,
                          const NATable *naTable,
                          const StmtLevelAccessOptions &accessOptions,
                          ItemExpr *predicate,
                          GroupAttributes *groupAttrs,
                          NABoolean catmanCollectUsages)
{
  BindWA *bindWA = this;   // for coding convenience

  CMPASSERT(viewName.getQualifiedNameObj() == naTable->getTableName());

  NABoolean inViewExpansion = bindWA->setInViewExpansion(TRUE);   // QSTUFF
  
  // set a flag for overrride_schema
  //if (overrideSchemaEnabled())
    bindWA->getCurrentScope()->setInViewExpansion(TRUE);

  if (!bindWA->getCurrentScope()->context()->inAnyConstraint())
    bindWA->tableViewUsageList().insert(new (bindWA->wHeap())
      TableViewUsage(
        viewName.getQualifiedNameObj(),
        viewName.getSpecialType(),
        TRUE/*isView*/,
        bindWA->viewCount()));

  // save the current parserflags setting
  ULng32 savedParserFlags = Get_SqlParser_Flags (0xFFFFFFFF);

  // allow funny characters in the tablenames used in the select list.
  // This enables views to be created on 'internal' secret table
  // so they could be accessed.
  // At view creation time, the caller still need to set this
  // parserflag from the sql interface(mxci, etc) otherwise the view
  // creation will fail. Since parserflags can only be set by super
  // users, the view with special tablenames could only have been created
  // by a super user.
  Set_SqlParser_Flags(ALLOW_FUNNY_IDENTIFIER);

  // Parse the view text.
  //
  // isolation level and order by are allowed in create view, if
  // the corresponding cqds are set.
  // These cqds are only valid during 'create view' time. Once the views
  // are created, we don't need to look at them.
  // During view expansion when we reach this method, turn the cqds on if
  // they are not already on, so parser doesn't return an error.
  // Reset them back, if they were set here.
  NABoolean allowIsolationLevelWasSet = FALSE;
  NABoolean allowOrderByWasSet = FALSE;
  if (CmpCommon::getDefault(ALLOW_ISOLATION_LEVEL_IN_CREATE_VIEW) == DF_OFF)
    {
      allowIsolationLevelWasSet = TRUE;

      NAString op("ON");
      ActiveSchemaDB()->getDefaults().validateAndInsert
        ("ALLOW_ISOLATION_LEVEL_IN_CREATE_VIEW", op, FALSE);
    }
  if (CmpCommon::getDefault(ALLOW_ORDER_BY_IN_CREATE_VIEW) == DF_OFF)
    {
      allowOrderByWasSet = TRUE;

      NAString op("ON");
      ActiveSchemaDB()->getDefaults().validateAndInsert
        ("ALLOW_ORDER_BY_IN_CREATE_VIEW", op, FALSE);
    }

  Parser parser(bindWA->currentCmpContext());
  ExprNode *viewTree = parser.parseDML(naTable->getViewText(),
                                       naTable->getViewLen(),
                                       naTable->getViewTextCharSet());

  // Restore parser flags settings to what they originally were
  Set_SqlParser_Flags (savedParserFlags);

  if (allowIsolationLevelWasSet)
    {
      NAString op("OFF");
      ActiveSchemaDB()->getDefaults().validateAndInsert
        ("ALLOW_ISOLATION_LEVEL_IN_CREATE_VIEW", op, FALSE);
    }
  if (allowOrderByWasSet)
    {
      NAString op("OFF");
      ActiveSchemaDB()->getDefaults().validateAndInsert
        ("ALLOW_ORDER_BY_IN_CREATE_VIEW", op, FALSE);
    }

  if (NOT viewTree) {
    bindWA->setErrStatus();
    return NULL;
  }

  // Remove the StmtQuery node.
  // Clear the root flag in the RelRoot node since this not the topmost
  // RelRoot in the query tree.
  //
  CMPASSERT(viewTree->getOperatorType() == STM_QUERY);
  RelExpr *queryTree = viewTree->castToStatementExpr()->getQueryExpression();
  CMPASSERT(queryTree->getOperatorType() == REL_ROOT);
  ((RelRoot *)queryTree)->setRootFlag(FALSE);

  CMPASSERT(queryTree->getChild(0)->getOperatorType() == REL_DDL);
  StmtDDLCreateView *createViewTree = ((DDLExpr *)(queryTree->getChild(0)))->
    getDDLNode()->castToStmtDDLNode()->castToStmtDDLCreateView();
  CMPASSERT(createViewTree);
  queryTree = createViewTree->getQueryExpression();
  CMPASSERT(queryTree->getOperatorType() == REL_ROOT);
  ((RelRoot *)queryTree)->setRootFlag(FALSE);

  RelRoot *viewRoot = (RelRoot *)queryTree;  // save for add'l binding below
  ParNameLocList *saveNameLocList = bindWA->getNameLocListPtr();

  // This was put here for Genesis 10-980217-0467.
  // Now with the fix for 10-980408-5149, we even more strongly need to bypass
  // or ignore any accessOpts from the view, for a consistent access model.

  if ((CmpCommon::getDefault(ALLOW_ISOLATION_LEVEL_IN_CREATE_VIEW) == DF_OFF) ||
      (viewRoot->accessOptions().accessType() == ACCESS_TYPE_NOT_SPECIFIED_))
    {
      // if cqd is set and view options were explicitely specified,
      // then do not overwrite it with accessOptions.
      viewRoot->accessOptions() = accessOptions;
    }

  // Set the WCO context (Genesis 10-971112-7028 + 10-990518-8420):
  //   If this view is WITH CHECK OPTION, then all views below it acquire
  //   check-option-ness, per Ansi 11.19 GR 9-11a
  //   (we implement only CASCADED -- see further notes later on in this func);
  //   if some view above this one is WCO, then this view effectively is too,
  //   regardless of its getViewCheck() value.
  // Genesis 10-990518-8420 fix in particular:
  //   with-check-option views of the form
  //     SELECT..FROM(SELECT..WHERE p1)REN WHERE p2
  //   were emitting a bind error on pred p1, and ignoring pred p2!
  //
  NABoolean topmostViewWithCheckOption = FALSE;
  if (naTable->getViewCheck() &&
      bindWA->getCurrentScope()->context()->inUpdateOrInsert() &&
      !bindWA->inViewWithCheckOption()) {
    topmostViewWithCheckOption = TRUE;
    bindWA->inViewWithCheckOption() = naTable;
  }

  // QSTUFF
  // Give the new query tree the pubsub group attrs before
  // binding, so that binder checks are applied to the new tree.
  if ((groupAttrs) &&
      (groupAttrs->isEmbeddedUpdateOrDelete() || groupAttrs->isStream()))
    propagateDeleteAndStream(queryTree,groupAttrs);

  // ************ THE FIRST OF TWO BINDNODE'S ************
  // Bind the basic queryTree first (before Rename), for stoi_ security stuff.
  // Cascade the WCO-ness down to RelExpr::bindSelf which captures predicates.
  // On this bind, unconditionally we never collect usages.
  //
  bindWA->viewCount()++;

  bindWA->setNameLocListPtr(NULL);      // do not collect usages for catman

  queryTree = queryTree->bindNode(bindWA);

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

  bindWA->viewCount()--;

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

  // if RelRoot has an order by, insert a Logical Sort node below it
  // and move the order by expr from view root to this sort node.
  // The view root node is eliminated during transformation/normalization
  // and the sortlogical node provides a place to 'hold' the order by expr.
  // During transformation, this sort key is moved from the sortlogical node
  // to the root node of the query, if there is no explicit order by 
  // specified as part of the query.
  // SortLogical node is a shortlived node and is eliminated during
  // the normalization phase.
  if (viewRoot->hasOrderBy())
    {
      RelExpr * sortNode = new (bindWA->wHeap())
                             SortLogical(queryTree->child(0)->castToRelExpr(),
                                         viewRoot->reqdOrder(),
                                         bindWA->wHeap());
      sortNode = sortNode->bindNode(bindWA);
      if (bindWA->errStatus())
        return NULL;

      viewRoot->removeOrderByTree();
      viewRoot->reqdOrder().clear();

      viewRoot->setChild(0, sortNode);
    }

  // Insert a RenameTable node above the view tree.
  //
  const NAColumnArray &columns = naTable->getNAColumnArray();
  ItemExpr *columnList = new (bindWA->wHeap())
    RenameCol(NULL, new (bindWA->wHeap())
      ColRefName(columns[0]->getColName(), bindWA->wHeap()));
  //
  CollIndex i = 1;
  for (i = 1; i < naTable->getColumnCount(); i++)
    columnList = new (bindWA->wHeap())
      ItemList(columnList, new (bindWA->wHeap())
        RenameCol(NULL, new (bindWA->wHeap())
          ColRefName(columns[i]->getColName(), bindWA->wHeap())));
  //

  queryTree = new (bindWA->wHeap())
    RenameTable(TRUE/*copy tableName as is*/,
                queryTree->castToRelExpr(),
                viewName,
                columnList,
                bindWA->wHeap(),
                TRUE/*isView*/);
  if (predicate) queryTree->addSelPredTree(predicate);
  ((RenameTable *) queryTree)->setViewNATable(naTable);

  // this query used this view
  appendViewName
    (viewName.getQualifiedNameObj().getQualifiedNameAsAnsiString().data());

  // set a flag for overrride_schema
  // with the call to bindNode below, only the Rename node will be bound.
  // Since the view has already been expanded we reset the viewExpansion flag here.
  //if (overrideSchemaEnabled())
    bindWA->getCurrentScope()->setInViewExpansion(inViewExpansion);

  // ************ THE SECOND OF TWO BINDNODE'S ************
  // Bind the view tree whose top is this new RenameTable.
  // If we are the topmost WCO, then do NOT cascade the incoming predicate!
  // Collect usages only if CatMan caller requested it.
  //
  if (topmostViewWithCheckOption) bindWA->inViewWithCheckOption() = NULL;
  if (!catmanCollectUsages) bindWA->setNameLocListPtr(NULL);
  queryTree = queryTree->bindNode(bindWA);
  bindWA->setNameLocListPtr(saveNameLocList);
  if (bindWA->errStatus()) return NULL;

  ((RenameTable *) queryTree)->setViewNATable(NULL);

  // Genesis 10-980126-5495:
  // Now that we have the RenameTable's RETDesc, set its view column headings.
  // We know that the NATable and the RenameTable column lists are in lockstep.
  //
  const ColumnDescList &columnsRET = *queryTree->getRETDesc()->getColumnList();
  CMPASSERT(columns.entries() == naTable->getColumnCount() &&
            columns.entries() == columnsRET.entries());
  for (i = 0; i < naTable->getColumnCount(); i++)
  {
    columnsRET[i]->setHeading(columns[i]->getHeading());
  }


  // If it's a view that is WITH CHECK OPTION, and this is an UPDATE/INSERT,
  // bind/transform/normalize the view predicate and place it as a constraint
  // on the base table's TableDesc.  This is equivalent to the default kind
  // of check clause, WITH CASCADED CHECK OPTION, which is all we need provide
  // up through Intermediate-Level SQL'92.
  //
  // (ANSI says that all CHECK OPTION views must be updatable (11.19 SR12)
  // which means it references exactly one updatable view or, at bottom,
  // exactly one base table (7.9 SR12).
  // MP guarantees that all CHECK OPTION views must be protection views, and
  // all pviews reference exactly one base table.)
  //
  // Notice that since (Genesis 10-990518-8420) we now bind and collect the
  // view preds in bindSelf -- i.e. pushed down below here --
  // only this topmost WCO can set up the constraint(s).
  // Thus we have lost the nice, but not mandated by Ansi, ability to specify
  // which cascaded-down-to view causes which exact pred violation --
  // i.e. error EXE_CHECK_OPTION_VIOLATION_CASCADED (8104)
  // no longer appears, only EXE_CHECK_OPTION_VIOLATION (8105).

  if (topmostViewWithCheckOption) {

    CheckConstraint *constraint = NULL;
    ItemExpr *viewCheckPred = NULL;

    if (bindWA->predsOfViewWithCheckOption().entries()) {
      constraint = new (bindWA->wHeap())
      CheckConstraint(viewName.getQualifiedNameObj(),       // this view name
                      naTable->getTableName(),       // no parsing needed
                      bindWA->wHeap());
      viewCheckPred = bindWA->predsOfViewWithCheckOption().rebuildExprTree();
    }

    // if at least one predicate exists in the view or what underlies it
    if (constraint) {

      RelExpr *underlyingTableOrView = viewRoot->child(0);
      RETDesc *saveRETDesc = bindWA->getCurrentScope()->getRETDesc();
      RETDesc *underlyingRETDesc = underlyingTableOrView->getRETDesc();
      bindWA->getCurrentScope()->setRETDesc(underlyingRETDesc);
      CMPASSERT(underlyingTableOrView);
      CMPASSERT(underlyingTableOrView->getOperatorType() == REL_RENAME_TABLE ||
                underlyingTableOrView->getOperatorType() == REL_SCAN);

      ItemExpr *constraintPred =
                 bindCheckConstraint(bindWA,
                                     constraint,
                                     naTable,
                                     catmanCollectUsages,
                                     viewCheckPred);
      if (constraintPred)
                 queryTree->getScanNode()->getTableDesc()->addCheckConstraint(
                                                             bindWA,
                                                             naTable,    // topmost WCO view
                                                             constraint,    // this view name
                                                             constraintPred);

      bindWA->getCurrentScope()->setRETDesc(saveRETDesc);

    }   // at least one predicate exists

    bindWA->inViewWithCheckOption() = NULL;
    bindWA->predsOfViewWithCheckOption().clear();

  }   // topmost WCO view

  // QSTUFF
  bindWA->setInViewExpansion(inViewExpansion);
  bindWA->getUpdateToScanValueIds().clear();
  // QSTUFF

  return queryTree;

} // BindWA::bindView()

// -----------------------------------------------------------------------
// member functions for class RelExpr
// -----------------------------------------------------------------------

void RelExpr::bindChildren(BindWA *bindWA)
{
  // Increment the trigger recursion counter.
  if (getInliningInfo().isTriggerRoot())
    getInliningInfo().getTriggerObject()->incRecursionCounter();

  // TSJ's flow their data from left child to right child;
  // some can also share binding scope column info from left to right.
  Int32 arity = getArity();
  for (Int32 i = 0; i < arity; i++) {
    if (child(i)) {

      // If doing a non-first child and the operator is
      // NOT one in which values/names can flow from one scope
      // the sibling scope, then we must clear the current RETDesc
      // (so as to disallow the illegal query in the Binder internals document,
      // section 1.5.3, also in TEST028).
      //
      if (i && !getOperator().match(REL_ANY_TSJ))
        bindWA->getCurrentScope()->setRETDesc(NULL);

      child(i) = child(i)->bindNode(bindWA);
      if (bindWA->errStatus()) return;
    }
  }

  synthPropForBindChecks();   // QSTUFF

  // Decrement the trigger recursion counter.
  if (getInliningInfo().isTriggerRoot())
    getInliningInfo().getTriggerObject()->decRecursionCounter();

} // RelExpr::bindChildren()

void RelExpr::synthPropForBindChecks()   // QSTUFF
{
  // synthesis of delete and stream properties to
  // allow for binder checks. We assume that all
  // operators are rejected when binding the respective node
  // -- except UNIONS -- in which more than one child has
  // has any of those attributes. If both attributes are
  // specified both must be specified for the same
  // result-set/base table.

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

     if (child(j)) {

        if (child(j)->getGroupAttr()->isStream())
        {
          getGroupAttr()->setStream(TRUE);

          if (child(j)->getGroupAttr()->isSkipInitialScan())
            getGroupAttr()->setSkipInitialScan(TRUE);
        }

        if (child(j)->getGroupAttr()->isEmbeddedUpdateOrDelete() ||
            child(j)->getGroupAttr()->isEmbeddedInsert())
          getGroupAttr()->setEmbeddedIUD(
               child(j)->getGroupAttr()->getEmbeddedIUD());
 
        if (child(j)->getGroupAttr()->reorderNeeded())
            getGroupAttr()->setReorderNeeded(TRUE);
     }
  }
}

RelExpr *RelExpr::bindSelf(BindWA *bindWA)
{
  // create the group attributes
  //
  if (NOT getGroupAttr())
    setGroupAttr(new (bindWA->wHeap()) GroupAttributes);

  //
  // Detach the item expression tree for the predicate, bind it, convert it to
  // a ValueIdSet, and attach it to the RelExpr node.
  //
  ItemExpr *predTree = removeSelPredTree();
  if (predTree) {
    bindWA->getCurrentScope()->context()->inWhereClause() = TRUE;
    predTree->convertToValueIdSet(selectionPred(), bindWA, ITM_AND);
    bindWA->getCurrentScope()->context()->inWhereClause() = FALSE;

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

    // If this is an embedded insert, then subquery predicates are not
    // allowed.  
    // For example:  To handle this query and issue an error stating
    //               subqueries are not allowed in embedded inserts
    // 
    //  select a from (insert into t901t01 values(22,22,222))t(a,b,c)
    //  where t.a IN (select m from t901t03 where t901t03.m = 77);

    if (getGroupAttr()->isEmbeddedInsert())
    {
       if (!selectionPred().isEmpty() && selectionPred().containsSubquery())
       {
         *CmpCommon::diags() << DgSqlCode(-4337);
         bindWA->setErrStatus();
         return this;
       }
    }  

    // Genesis 10-990518-8420.
    if (bindWA->inViewWithCheckOption())
      bindWA->predsOfViewWithCheckOption() += selectionPred();
  }

  // ++MV
  // Bind the uniqueColumnsTree expression.
  //
  ItemExpr *uniqueColumnsTree = removeUniqueColumnsTree();
  if (uniqueColumnsTree)
  {
    uniqueColumnsTree->
      convertToValueIdSet(getUniqueColumns(), bindWA, ITM_ITEM_LIST);
    if (bindWA->errStatus()) return this;
  }
  // --MV

  // set flag here if an Insert/Update/Delete operation is below this node   
  if( bindWA->isBindingIUD() )
  {
    setSeenIUD();
  }

  //
  // This mechanism is used to set InliningInfo flags on an entire subtree.
  getInliningInfo().setFlags(bindWA->getInliningInfoFlagsToSetRecursivly());

  //
  // Add the values in the Outer References Set as the input values
  // that must be supplied to this RelExpr.
  //
  getGroupAttr()->addCharacteristicInputs(bindWA->getCurrentScope()->getOuterRefs());
  markAsBound();
  return this;
} // RelExpr::bindSelf()

RelExpr *RelExpr::bindNode(BindWA *bindWA)
{
  if (nodeIsBound())
  {
    bindWA->getCurrentScope()->setRETDesc(getRETDesc());
    return this;
  }

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

RETDesc *RelExpr::getRETDesc() const
{
  if (RETDesc_)
    return RETDesc_;
  if (getArity() == 1)
    return child(0)->getRETDesc();
  else
    return NULL;
}

// When there is a view atop a view atop a ... atop a single base table,
// this will follow the chain of RenameTable-RelRoot-... down till it finds
// the bottom, the single base table's Scan node.
//
// This method does check to ensure exactly one single base table.
//
Scan *RelExpr::getScanNode(NABoolean assertExactlyOneScanNode) const
{
  RelExpr *result = (RelExpr *)this;   // cast away constness, big whoop

  while (result) {
    if ((result->getOperatorType() == REL_SCAN) ||
	(result->getOperatorType() == REL_HBASE_ACCESS))
      break;
    if (result->getArity() > 1) {
      if (assertExactlyOneScanNode)
      { 
        CMPASSERT(result->getArity() <= 1);
      }
      else return NULL;
    }
    result = result->child(0);
  }

  if (assertExactlyOneScanNode) { CMPASSERT(result); }
  return (Scan *)result;
}


Scan *RelExpr::getLeftmostScanNode() const
{
  RelExpr *result = (RelExpr *)this;   // cast away constness, big whoop

  while (result) {
    if (result->getOperatorType() == REL_SCAN) break;
    result = result->child(0);
  }

  return (Scan *)result;
}



Join * RelExpr::getLeftJoinChild() const
{
  RelExpr *result = (RelExpr *)this;
  
  while(result)
    {
      if (result->getOperatorType() == REL_LEFT_JOIN) 
        break;
      result = result->child(0);
    }
  return (Join *)result;
}

RelSequence* RelExpr::getOlapChild() const
{
  RelExpr *result = (RelExpr *)this;
  
  while(result)
    {
      if (result->getOperatorType() == REL_SEQUENCE) 
        break;
      result = result->child(0);
    }
  return (RelSequence *)result;
}

// QSTUFF
// We use this method for finding the scan node of an updatable view.
// This may either be a base table scan or a RenameTable node inserted
// by a previous index expansion.
RelExpr *RelExpr::getViewScanNode(NABoolean isTopLevelUpdateInView) const
{
  RelExpr *result = (RelExpr *)this;    // cast away constness, big whoop

  while (result) {
    if (result->getOperatorType() == REL_SCAN) break;

    if (result->getOperatorType() == REL_RENAME_TABLE &&
        ((RenameTable *)result)->isView()) break;

    result = result->child(0);
  }

  return result;
}

// -----------------------------------------------------------------------
// getFirstIUDNode
//
// Return the first node that is an insert, update, or delete.
// Only search down left side from the starting point (currentNode)
//
// If an IUD node is not found, return NULL
// -----------------------------------------------------------------------
GenericUpdate * Join::getFirstIUDNode(RelExpr *currentNode)
{
  while(currentNode)
  {
    if( currentNode->getOperator().match(REL_ANY_GEN_UPDATE))
    {      
      break;
    }        
    currentNode = currentNode->child(0);
  }
  return (GenericUpdate*)currentNode;
}

// -----------------------------------------------------------------------
// member functions for class Join
//
// When we implement "JOIN USING (column list)", we need to:		##
// - disallow both NATURAL and USING in the same query (syntax err in Parser?)
// - ensure that the named USING cols are indeed common cols
// - coalesce common cols for USING just as we do for NATURAL,
//   including ensuring that common cols are marked as referenced
//   (as done in joinCommonColumns)
// -----------------------------------------------------------------------

RelExpr *Join::bindNode(BindWA *bindWA)
{
  if (nodeIsBound())
  {
    bindWA->getCurrentScope()->setRETDesc(getRETDesc());
    return this;
  }

  // Do not support for general NEO users.
  if ( (getOperatorType() == REL_FULL_JOIN) &&
       (CmpCommon::getDefault(COMP_BOOL_192) == DF_ON) ) {
    
    RelExpr *leftJoin = this;
    leftJoin->setOperatorType(REL_LEFT_JOIN);
    
    Join *antiJoin = static_cast<Join *>(leftJoin->copyTree(bindWA->wHeap()));
    antiJoin->setOperatorType(REL_RIGHT_JOIN);

    NAString leftName("ALJ", bindWA->wHeap());

    // Make it unique.  
    //  
    leftName += bindWA->fabricateUniqueName();

    RelExpr *rename = new (bindWA->wHeap())
      RenameTable(antiJoin, leftName);

    RelExpr *unionAll = new (bindWA->wHeap()) Union(leftJoin, rename);

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

    ItemExpr *nullCheck = antiJoin->addNullInstIndicatorVar(bindWA).getItemExpr();

    CMPASSERT(nullCheck);
    
    ItemExpr *filter = new (bindWA->wHeap())
      UnLogic(ITM_IS_NULL, nullCheck );
    
    filter->bindNode(bindWA);
    if (bindWA->errStatus()) return this;
    
    // Add filter to Join
    //
    antiJoin->selectionPred() += filter->getValueId();

    return unionAll;
  }

  Join *saveInJ = bindWA->getCurrentScope()->context()->inJoin();
  bindWA->getCurrentScope()->context()->inJoin() = this;
  NABoolean savedPrivSetting = FALSE;

  // Bind the child nodes.
  //
  bindChildren(bindWA);
  if (bindWA->errStatus()) return this;

  // MV logging push-down
  if( getInliningInfo().isDrivingMvLogInsert() )
  {
    GenericUpdate *rightSideIUD = getFirstIUDNode(this->child(1));

    if( NULL != rightSideIUD )
    {
      TableDesc *tdesc = rightSideIUD->getTableDesc();

      CMPASSERT(tdesc);

      const NATable *table = tdesc->getNATable();

      // only for MV logs
      if( ExtendedQualName::IUD_LOG_TABLE == table->getSpecialType() )
      {
        updateTableDesc_ = tdesc;
        updateSelectValueIdMap_ = new (bindWA->wHeap())
                             ValueIdMap(rightSideIUD->updateToSelectMap());
      }
    }
  }


  // Controlled availability of Full Outer Join support 
  // The COMP_BOOL_199 must be removed when full outer join
  // becomes general availability.
  
  // Full outer joins are not currently supported.
  // But can enabled by setting COMP_BOOL_199 to ON.

  if ((getOperatorType() == REL_FULL_JOIN &&
       (CmpCommon::getDefault(COMP_BOOL_199) == DF_OFF))
      ||  //OR
      (getOperatorType() == REL_UNION_JOIN )){
    // 3022 Feature not yet supported
    *CmpCommon::diags() << DgSqlCode(-3022)
                        << DgString0(
                                    (getOperatorType() == REL_FULL_JOIN) ?
                                    "FULL OUTER JOIN" : "UNION JOIN");
    bindWA->setErrStatus();
    return this;
  }
  
  //
  // Bind the ON clause of the join.
  //
  RelExpr *leftRelExpr  = child(0).getPtr();
  RelExpr *rightRelExpr = child(1).getPtr();
  RETDesc *leftTable    = child(0)->getRETDesc();
  RETDesc *rightTable   = child(1)->getRETDesc();

  ItemExpr *joinPredx;
  if (isNaturalJoin()) {
    // since the common column references need fetch histograms, the where
    // flag is set here so that when we call markAsReferencedColumn()
    // in the joinCommoncolumns() method it would set the common
    // columns as refenced by looking a the inWhereCaluse_ flag.
    NABoolean orig = bindWA->getCurrentScope()->context()->inWhereClause();
    bindWA->getCurrentScope()->context()->inWhereClause() = TRUE;
    joinPredx = joinCommonColumns(leftRelExpr, rightRelExpr, bindWA);
    bindWA->getCurrentScope()->context()->inWhereClause() = orig;
  }
  else
    joinPredx = removeJoinPredTree();

  if (joinPredx) {
    ItemExpr *saveInJP = bindWA->getCurrentScope()->context()->inJoinPred();
    bindWA->getCurrentScope()->context()->inJoinPred() = joinPredx;
    RETDesc preJoinResult;
    preJoinResult.addColumns(bindWA, *leftTable);
    preJoinResult.addColumns(bindWA, *rightTable);
    bindWA->getCurrentScope()->setRETDesc(&preJoinResult);
    joinPredx->convertToValueIdSet(joinPred(), bindWA, ITM_AND);
    bindWA->getCurrentScope()->context()->inJoinPred() = saveInJP;
    if (bindWA->errStatus()) return this;
  }
  //
  // Create the output list.
  // The TRUE's in the nullInstantiate() force a Cast expression to be set up,
  // as required by the Normalizer.
  //
  NABoolean newTables = TRUE;
  ValueIdList &nullOutputList = nullInstantiatedOutput();
  ValueIdList &nullOutputForRightJoinList = nullInstantiatedForRightJoinOutput();

  switch(getOperatorType()) {
  case REL_LEFT_JOIN:
    leftTable  = new (bindWA->wHeap()) RETDesc(bindWA, *leftTable);
    rightTable = rightTable->nullInstantiate(bindWA, TRUE, nullOutputList);
    break;
  case REL_RIGHT_JOIN:
    leftTable  = leftTable->nullInstantiate(bindWA,  TRUE, nullOutputList);
    rightTable = new (bindWA->wHeap()) RETDesc(bindWA, *rightTable);
    break;
  case REL_FULL_JOIN:
  case REL_UNION_JOIN:
    {
    leftTable  = leftTable->nullInstantiate(bindWA,  TRUE, nullOutputForRightJoinList);
    
    rightTable = rightTable->nullInstantiate(bindWA, TRUE, nullOutputList);

    
    // comp_bool_198 = 'on' enables FullOuter transformation
    // inner, left or right
    if (CmpCommon::getDefault(COMP_BOOL_198) == DF_OFF) //don't enable FOJ transformation
      {
      ItemExpr * instNull = NULL;
      CollIndex index = 0; 
      
      // disable the FOJ Transformation.
      for (index = 0; index < nullInstantiatedOutput().entries(); index++)
        {
          instNull = nullInstantiatedOutput()[index].getItemExpr();
          CMPASSERT(instNull->getOperatorType() == ITM_INSTANTIATE_NULL);
          ((InstantiateNull *)instNull)->NoCheckforLeftToInnerJoin = TRUE;
        } // endfor
      
      instNull = NULL;
      
      for (index = 0; 
        index < nullInstantiatedForRightJoinOutput().entries(); index++)
        {
          instNull = nullInstantiatedForRightJoinOutput()[index].getItemExpr();
          CMPASSERT(instNull->getOperatorType() == ITM_INSTANTIATE_NULL);
          ((InstantiateNull *)instNull)->NoCheckforLeftToInnerJoin = TRUE;
        } // endfor
      } // env "ENABLE_FOJ_TRANSFORMATION"
    break;
    }
  case REL_JOIN:
  default:
    newTables = FALSE;
    break;
  }
  RETDesc *resultTable = new (bindWA->wHeap()) RETDesc(bindWA);

  Int32 rowSet = (child(0)->getOperatorType() == REL_RENAME_TABLE) &&
               (child(0)->child(0)->getOperatorType() == REL_UNPACKROWS) &&
               (child(1)->getOperatorType() == REL_ROOT);

  if (NOT isNaturalJoin()) {
    if ((!rowSet) &&
        (getOperatorType() != REL_TSJ_FLOW)) {
      resultTable->addColumns(bindWA, *leftTable);
    }
    // ++MV  -- bug fixing for semi-joins
    if (!isSemiJoin())
    {
      resultTable->addColumns(bindWA, *rightTable);
    }
    // --MV  -- bug fixing for semi-joins
  } else {
    coalesceCommonColumns(bindWA,
                          getOperatorType(),
                          *leftTable,
                          *rightTable,
                          *resultTable);
    if (bindWA->errStatus()) return this;
  }
  setRETDesc(resultTable);
  bindWA->getCurrentScope()->setRETDesc(resultTable);

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

  bindWA->getTablesInScope(xtnmList, &fmtdList);

  if ((child(0)->getGroupAttr()->isStream()) &&
      (child(1)->getGroupAttr()->isStream())){
    bindWA->getTablesInScope(xtnmList, &fmtdList);
    *CmpCommon::diags() << DgSqlCode(-4158)
      << DgString0(fmtdList);
    bindWA->setErrStatus();
    return this;
  }

  // Disallowing joins for EMBEDDED...INSERT
  // 
  if (getGroupAttr()->isEmbeddedInsert() && 
      !isTSJForWrite()   // the tsjForWrite flag is set for
                         // those joins which are created by
                         // the Binder during inlining (eg. IndexMaintanence)
                         // Here we only want to disable user specified joins
                         // and not joins introduced as part of inlining.
      ){
      *CmpCommon::diags() << DgSqlCode(-4336)
        << DgString0(fmtdList)
        << DgString1(getGroupAttr()->getOperationWithinGroup());
      bindWA->setErrStatus();
      return this;
    }


  if ( ((child(0)->getGroupAttr()->isEmbeddedUpdateOrDelete()) &&
        (child(1)->getGroupAttr()->isEmbeddedUpdateOrDelete())) ||
       ((child(0)->getGroupAttr()->isEmbeddedInsert()) &&
        (child(1)->getGroupAttr()->isEmbeddedInsert())) ||
       (bindWA->isEmbeddedIUDStatement()) ) {
    NAString type0,type1;
    if (child(0)->getGroupAttr()->isEmbeddedUpdate())
      type0 = "UPDATE";
    else
    {
      if (child(0)->getGroupAttr()->isEmbeddedInsert())
        type0 = "INSERT";
      else
        type0 = "DELETE";
    }
    if (child(1)->getGroupAttr()->isEmbeddedUpdate())
      type1 = "UPDATE";
    else
    {
      if (child(1)->getGroupAttr()->isEmbeddedInsert())
        type1 = "INSERT";
      else
        type1 = "DELETE";
    }
    *CmpCommon::diags() << DgSqlCode(-4175)
      << DgString0(fmtdList)
      << DgString1(type0)
      << DgString2(type1);
    bindWA->setErrStatus();
    return this;
  }

  if ((child(0)->getGroupAttr()->isEmbeddedUpdateOrDelete() ||
       child(0)->getGroupAttr()->isStream()) &&
      (child(1)->getGroupAttr()->isEmbeddedUpdateOrDelete() ||
       child(1)->getGroupAttr()->isStream())){
    *CmpCommon::diags() << DgSqlCode(-4176)
      << DgString0(fmtdList)
      << (getGroupAttr()->isEmbeddedUpdate() ?
          DgString1("UPDATE"):DgString1("DELETE"));
    bindWA->setErrStatus();
    return this;
  }

  if (getOperatorType() == REL_LEFT_JOIN){
    if (child(1)->getGroupAttr()->isEmbeddedUpdateOrDelete()){
      *CmpCommon::diags() << DgSqlCode(-4156)
        << DgString0(fmtdList)
        << (child(1)->getGroupAttr()->isEmbeddedUpdate() ?
            DgString1("UPDATE"):DgString1("DELETE"));
      bindWA->setErrStatus();
      return this;
    }
    if (child(1)->getGroupAttr()->isStream()){
      *CmpCommon::diags() << DgSqlCode(-4157)
        << DgString0(fmtdList);
      bindWA->setErrStatus();
      return this;
    }
  }

  if (getOperatorType() == REL_RIGHT_JOIN){
    if (child(0)->getGroupAttr()->isEmbeddedUpdateOrDelete()){
      *CmpCommon::diags() << DgSqlCode(-4164)
        << DgString0(fmtdList)
        << (child(0)->getGroupAttr()->isEmbeddedUpdate() ?
            DgString1("UPDATE"):DgString1("DELETE"));
      bindWA->setErrStatus();
      return this;
    }
    if (child(0)->getGroupAttr()->isStream()){
      *CmpCommon::diags() << DgSqlCode(-4165)
        << DgString0(fmtdList);
      bindWA->setErrStatus();
      return this;
    }
  }

  // we need to move stream and nested updates to the
  // left to ensure correct execution. This causes the statement
  // to be rejected if the user specified join_order_by_user and
  // the query must be reordered

  if (child(1)->getGroupAttr()->isStream() ||
    child(1)->getGroupAttr()->isEmbeddedUpdateOrDelete()){
    getGroupAttr()->setReorderNeeded(TRUE);
  }
  // QSTUFF

  if (newTables) {
    delete leftTable;
    delete rightTable;
  }

  bindWA->getCurrentScope()->context()->inJoin() = saveInJ;

  if (getOperatorType() == REL_TSJ){
    //Using rowsets in a predicate with embedded update/delete results
    //in a NestedJoin subtree after Normalization.This NestedJoin subtree
    //has embedded update/delete as the right child, which is not allowed
    //during optimization. Here we try to disallow this usage at Binding
    //when a REL_TSJ subtree has rowsets as the left child and embedded
    //update/delete as the right child. An error message[4123] is signaled.
    if (rowSet && getGroupAttr()->isEmbeddedUpdateOrDelete()){
      *CmpCommon::diags() << DgSqlCode(-4213);
      bindWA->setErrStatus();
      return this;
    }
  }

  // transfer rowsetRowCountArraySize from HostArrayWA to this node.
  if (bindWA->getHostArraysArea() && isRowsetIterator())
    setRowsetRowCountArraySize(bindWA->getHostArraysArea()->getRowsetRowCountArraySize());

  // Bind the base class.
  //
  return bindSelf(bindWA);
} // Join::bindNode()

ValueId Join::addNullInstIndicatorVar(BindWA *bindWA,
                                      ItemExpr *indicatorVal)
{
  // Add an indicator variable that can tell us whether
  // a left join found a match in the right child table
  // or not. The returned ValueId will have the value 1
  // if a match was found, and NULL if no match was found.

  ItemExpr *cval = indicatorVal;

  if (!cval)
    cval = new (bindWA->wHeap()) SystemLiteral(1);
  cval = cval->bindNode(bindWA);
  if (bindWA->errStatus())
    return NULL_VALUE_ID;

  // Null instantiate the value.
  ValueId niCval = cval->getValueId().nullInstantiate(bindWA, TRUE);

  // Add it to the RETDesc of the Join.
  ColRefName cvalName("", bindWA->wHeap());
  getRETDesc()->addColumn(bindWA, cvalName , niCval, USER_COLUMN);

  // Add it to the list of null instantiated outputs.
  nullInstantiatedOutput().insert(niCval);

  return niCval;
}

//++MV
// This function builds the BalueIdMap that is used for translating the required
// sort key to the right child sort key and backwards
void Join::BuildRightChildMapForLeftJoin()
{
  ValueIdMap &map = rightChildMapForLeftJoin();

  for (CollIndex j = 0; j < nullInstantiatedOutput().entries(); j++)
  {
    ValueId instNullId, rightChildId;

    instNullId = nullInstantiatedOutput_[j];

    assert(instNullId.getItemExpr()->getOperatorType() == ITM_INSTANTIATE_NULL);

    // Access the operand of the InstantiateNull
    rightChildId = (((InstantiateNull *)(instNullId.getItemExpr()))->getExpr()->getValueId());

    map.addMapEntry(instNullId, rightChildId);
  }
}
//--MV

//++MV
// This function builds the ValueIdMap that is used for translating the 
// required
// sort key to the left  child sort key and backwards
void Join::BuildLeftChildMapForRightJoin()
{
  ValueIdMap &map = leftChildMapForRightJoin();

  for (CollIndex j = 0; j < nullInstantiatedForRightJoinOutput().entries(); j++)
  {
    ValueId instNullId, leftChildId;

    instNullId = nullInstantiatedForRightJoinOutput_[j];

    assert(instNullId.getItemExpr()->getOperatorType() == ITM_INSTANTIATE_NULL);

    // Access the operand of the InstantiateNull
    leftChildId = (((InstantiateNull *)(instNullId.getItemExpr()))->getExpr()->getValueId());

    map.addMapEntry(instNullId, leftChildId);
  }
}
//--MV

// -----------------------------------------------------------------------
// member functions for class Intersect
// -----------------------------------------------------------------------

// LCOV_EXCL_START - cnu
RelExpr *Intersect::bindNode(BindWA *bindWA)
{
  if (nodeIsBound())
  {
    bindWA->getCurrentScope()->setRETDesc(getRETDesc());
    return this;
  }

  // Bind the child nodes.
  //
  bindChildren(bindWA);
  if (bindWA->errStatus()) return this;

  // Check that there are an equal number of select items on both sides.
  //
  const RETDesc &leftTable = *child(0)->getRETDesc();
  const RETDesc &rightTable = *child(1)->getRETDesc();
  if (leftTable.getDegree() != rightTable.getDegree()) {
    // 4014 The operands of an intersect must be of equal degree.
    *CmpCommon::diags() << DgSqlCode(-4014);
    bindWA->setErrStatus();
    return this;
  }

  // Join the columns of both sides. 
  //
  if(CmpCommon::getDefault(MODE_SPECIAL_4) != DF_ON)
  {
    *CmpCommon::diags() << DgSqlCode(-3022)    // ## INTERSECT not yet supported , not fully tested
        << DgString0("INTERSECT");             // ##
    bindWA->setErrStatus();                    // ##
    if (bindWA->errStatus()) return NULL;      // ##
  }
  //
  ItemExpr *predicate = intersectColumns(leftTable, rightTable, bindWA);
  RelExpr *join = new (bindWA->wHeap())
    Join(child(0)->castToRelExpr(),
         child(1)->castToRelExpr(),
         REL_JOIN,
         predicate);

  // Bind the join.
  //
  join = join->bindNode(bindWA)->castToRelExpr();
  if (bindWA->errStatus()) return join;

  // Change the output of the join to just the left side.
  //
  delete join->getRETDesc();
  join->setRETDesc(new (bindWA->wHeap()) RETDesc(bindWA, leftTable));
  bindWA->getCurrentScope()->setRETDesc(join->getRETDesc());

  // QSTUFF
  NAString fmtdList1(bindWA->wHeap());
  LIST(TableNameMap*) xtnmList1(bindWA->wHeap());
  NAString fmtdList2(bindWA->wHeap());
  LIST(TableNameMap*) xtnmList2(bindWA->wHeap());

  leftTable.getTableList(xtnmList1, &fmtdList1);
  rightTable.getTableList(xtnmList2, &fmtdList2);

  if (child(0)->getGroupAttr()->isStream() &&
      child(1)->getGroupAttr()->isStream()){
    *CmpCommon::diags() << DgSqlCode(-4159)
                << DgString0(fmtdList1) << DgString1(fmtdList2);
    bindWA->setErrStatus();
    return this;
  }

  // Needs to be removed when supporting get_next for INTERSECT
  if (getGroupAttr()->isEmbeddedUpdateOrDelete()) {
    *CmpCommon::diags() << DgSqlCode(-4160)
                << DgString0(fmtdList1)
                << DgString1(fmtdList2)
                << (child(0)->getGroupAttr()->isEmbeddedUpdate() ?
                             DgString2("UPDATE"):DgString2("DELETE"))
                << (child(1)->getGroupAttr()->isEmbeddedUpdate() ?
                             DgString3("UPDATE"):DgString3("DELETE"));
    bindWA->setErrStatus();
    return this;
  }
  // QSTUFF

  return join;
} // Intersect::bindNode()
// LCOV_EXCL_STOP

// -----------------------------------------------------------------------
// member functions for class Except 
// -----------------------------------------------------------------------

// LCOV_EXCL_START - cnu
RelExpr *Except::bindNode(BindWA *bindWA)
{
  if (nodeIsBound())
  {
    bindWA->getCurrentScope()->setRETDesc(getRETDesc());
    return this;
  }

  // Bind the child nodes.
  //
  bindChildren(bindWA);
  if (bindWA->errStatus()) return this;

  // Check that there are an equal number of select items on both sides.
  //
  const RETDesc &leftTable = *child(0)->getRETDesc();
  const RETDesc &rightTable = *child(1)->getRETDesc();
  if (leftTable.getDegree() != rightTable.getDegree()) {
    // 4014 The operands of an intersect must be of equal degree.
    *CmpCommon::diags() << DgSqlCode(-4014);
    bindWA->setErrStatus();
    return this;
  }

  // Join the columns of both sides. 
  //
  if(CmpCommon::getDefault(MODE_SPECIAL_4) != DF_ON)
  {
    *CmpCommon::diags() << DgSqlCode(-3022)    // ## EXCEPT not yet supported: not fully tested
        << DgString0("EXCEPT");             // ##
    bindWA->setErrStatus();                    // ##
    if (bindWA->errStatus()) return NULL;      // ##
  }
  //
  ItemExpr *predicate = intersectColumns(leftTable, rightTable, bindWA);
  RelExpr *join = new (bindWA->wHeap())
    Join(child(0)->castToRelExpr(),
         child(1)->castToRelExpr(),
         REL_ANTI_SEMIJOIN,
         predicate);

  // Bind the join.
  //
  join = join->bindNode(bindWA)->castToRelExpr();
  if (bindWA->errStatus()) return join;

  // Change the output of the join to just the left side.
  //
  delete join->getRETDesc();
  join->setRETDesc(new (bindWA->wHeap()) RETDesc(bindWA, leftTable));
  bindWA->getCurrentScope()->setRETDesc(join->getRETDesc());

  // QSTUFF
  NAString fmtdList1(bindWA->wHeap());
  LIST(TableNameMap*) xtnmList1(bindWA->wHeap());
  NAString fmtdList2(bindWA->wHeap());
  LIST(TableNameMap*) xtnmList2(bindWA->wHeap());

  leftTable.getTableList(xtnmList1, &fmtdList1);
  rightTable.getTableList(xtnmList2, &fmtdList2);

  if (child(0)->getGroupAttr()->isStream() &&
      child(1)->getGroupAttr()->isStream()){
    *CmpCommon::diags() << DgSqlCode(-4159)
                << DgString0(fmtdList1) << DgString1(fmtdList2);
    bindWA->setErrStatus();
    return this;
  }

  // Needs to be removed when supporting get_next for EXCEPT
  if (getGroupAttr()->isEmbeddedUpdateOrDelete()) {
    *CmpCommon::diags() << DgSqlCode(-4160)
                << DgString0(fmtdList1)
                << DgString1(fmtdList2)
                << (child(0)->getGroupAttr()->isEmbeddedUpdate() ?
                             DgString2("UPDATE"):DgString2("DELETE"))
                << (child(1)->getGroupAttr()->isEmbeddedUpdate() ?
                             DgString3("UPDATE"):DgString3("DELETE"));
    bindWA->setErrStatus();
    return this;
  }
  // QSTUFF

  return join;
} // Excpet::bindNode()
// LCOV_EXCL_STOP

// -----------------------------------------------------------------------
// member functions for class Union
// -----------------------------------------------------------------------

RelExpr *Union::bindNode(BindWA *bindWA)
{
  if (nodeIsBound())
  {
    bindWA->getCurrentScope()->setRETDesc(getRETDesc());
    return this;
  }

  //
  // Bind the conditional expression.
  //
  ItemExpr *condExprTree = removeCondExprTree();
  if (condExprTree)
  {
    condExprTree->convertToValueIdList(condExpr(), bindWA, ITM_ITEM_LIST);
    if (bindWA->errStatus()) {
      return NULL;
    }
  }

  //
  // Bind the triggered action exception expression.
  //
  ItemExpr *trigExprTree = removeTrigExceptExprTree();
  if (trigExprTree)
  {
    // the assumption in the binder (in Union::addValueIdUnion) is that 
    // unionMap_ count is always less than or equal to one but triggers 
    // code might increment this number during binding because of 
    // recursive triggers or triggers that are used more than once 
    // in the statement. This check fixes the unionMap_ for triggers. 
    if ((unionMap_ != NULL) && (unionMap_->count_ > 1))
    {
       unionMap_->count_--;
       unionMap_ = new (CmpCommon::statementHeap()) UnionMap;
    }

    trigExprTree->convertToValueIdList(trigExceptExpr(), bindWA, ITM_ITEM_LIST);
    if (bindWA->errStatus()) {
      return NULL;
    }
  }

  AssignmentStArea *assignArea = NULL;
  // We store a pointer to this Union node in the assignment statements area.
  // This is needed for compound statements project, in particular when we have
  // assignment statements within an IF statement
  if (getUnionForIF()) {
    assignArea = bindWA->getAssignmentStArea();
    setPreviousIF(assignArea->getCurrentIF());
    assignArea->setCurrentIF(this);
  }

  //
  // Bind the child nodes.
  //
  bindWA->getCurrentScope()->context()->inUnion() = TRUE;

  currentChild() = 0;
  child(0) = child(0)->bindNode(bindWA);

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

  // If we have assignment statements of compound statements, we need to get rid
  // of the value ids generated while binding the first child. Also, we create a
  // list of the value ids of the variables that are on the left side of a SET
  // statement
  if (getUnionForIF() && leftList() && assignArea) {
    assignArea->removeLastValueIds(leftList(), this);
  }

  if (getCondUnary()) {
    CollIndex leftDegree = child(0)->getRETDesc()->getDegree();

    ItemExpr *tupleExpr = new (bindWA->wHeap()) ConstValue();

    for (CollIndex i=0; i+1<leftDegree; i++) {
      ItemExpr *con = new (bindWA->wHeap()) ConstValue();

      ItemList *list = new (bindWA->wHeap()) ItemList(con, tupleExpr);

      tupleExpr = list;
    }

    RelExpr *tuple = new (bindWA->wHeap()) Tuple(tupleExpr);

    // create the selection predicate (1=0) for the Tuple node
    ItemExpr *predicate = new (bindWA->wHeap())
                            BiRelat(ITM_EQUAL,
                                  new (bindWA->wHeap()) ConstValue(1),
                                  new (bindWA->wHeap()) ConstValue(0));
    tuple->addSelPredTree(predicate);

    RelExpr *tupleRoot = new (bindWA->wHeap()) RelRoot(tuple);

    setChild (1, tupleRoot);
  }

  if (child(1)) {
    if (!(child(1)->getOperator().match(REL_ANY_TSJ))) {
      bindWA->getCurrentScope()->setRETDesc(NULL);
    }

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

    // If we have assignment statements of compound statements,
    // we need to get rid of the value ids generated while binding
    // the second child
    if (getUnionForIF() && rightList() && assignArea) {
      assignArea->removeLastValueIds(rightList(), this);
    }
  }

  // check for & warn against UNIONs that have inconsistent access/lock modes.
  // flag "select * from t1 union select * from t2 for <access> mode"
  // with a warning that t1 and t2 may have inconsistent access/lock modes.
  checkAccessLockModes();

  //Copies the leftlist and rightlist this conditional union to the appropriate list of the
  //conditional union node pointed to by the previousIF argument.
  Union * previousIF = getPreviousIF();
  if (previousIF && getUnionForIF()) {
     copyLeftRightListsToPreviousIF(previousIF, bindWA);
  }

  synthPropForBindChecks();
                                              // QSTUFF

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

  //
  // Check that there are an equal number of select items on both sides.
  //
  const RETDesc &leftTable = *child(0)->getRETDesc();
  const RETDesc &rightTable = *child(1)->getRETDesc();
  RETDesc *resultTable = NULL;

  RelRoot * root = bindWA->getTopRoot() ;
  if (root) {
     if (getGroupAttr()->isStream() && root->hasOrderBy()){
       NAString fmtdList1(bindWA->wHeap());
       LIST(TableNameMap*) xtnmList1(bindWA->wHeap());
       NAString fmtdList2(bindWA->wHeap());
       LIST(TableNameMap*) xtnmList2(bindWA->wHeap());
       leftTable.getTableList(xtnmList1, &fmtdList1);
       rightTable.getTableList(xtnmList2, &fmtdList2);
       *CmpCommon::diags() << DgSqlCode(-4166)
                           << DgString0(fmtdList1)
                           << DgString1(fmtdList2) ;
       bindWA->setErrStatus();
       return this;
     }
  }

  if (leftTable.getDegree() != rightTable.getDegree()) {

#ifndef NDEBUG
    dumpChildrensRETDescs(leftTable, rightTable);
#endif

    if ( (!getUnionForIF()) &&
         (!getCondUnary()) //for triggers
       ) {
      // 4126 The row-value-ctors of a VALUES must be of equal degree.
      // 4066 The operands of a union must be of equal degree.
      // This is not necessary if we are in an assignment stmt.
      Lng32 sqlcode = bindWA->getCurrentScope()->context()->inTupleList() ?
                                                            -4126 : -4066;
      *CmpCommon::diags() << DgSqlCode(sqlcode);
      bindWA->setErrStatus();
      return this;
    }
  }

  //
  // For each select item on both sides, create a ValueIdUnion and insert its
  // ValueId into the select list for the union.
  //

  // We check to see if there were assignments on either side
  if  ( !getUnionForIF() ) {
    resultTable = new (bindWA->wHeap()) RETDesc(bindWA);
    for (CollIndex i = 0; i < leftTable.getDegree(); i++) {
      ValueIdUnion *vidUnion = new (bindWA->wHeap())
      ValueIdUnion(leftTable.getValueId(i),
                   rightTable.getValueId(i),
                   NULL_VALUE_ID,
#pragma nowarn(1506)   // warning elimination
                   getUnionFlags());
#pragma warn(1506)  // warning elimination
      vidUnion->setIsTrueUnion(TRUE);
      vidUnion->bindNode(bindWA);
      if (bindWA->errStatus()) {
        delete vidUnion;
        delete resultTable;
        return this;
      }
      ValueId valId = vidUnion->getValueId();
      addValueIdUnion(valId, bindWA->wHeap());
      resultTable->addColumn(bindWA, leftTable.getColRefNameObj(i), valId);
    }
  }
  else {
    // Case in which we have asignment statements below this node.
    // We have to carefuly match the valueids in the IF and ELSE part.
    // For instance, if SET :a = ... occurs in both branches or only in one.
    if (getUnionForIF() && assignArea) {
      resultTable = createReturnTable(assignArea, bindWA);
    }
  }


  setRETDesc(resultTable);
  bindWA->getCurrentScope()->setRETDesc(resultTable);
  //
  // Bind the base class.
  //

  // We are done binding this node. The current IF node is now the closest
  // IF node that is also an ancestor of this node
  if (getUnionForIF() && assignArea) {
    assignArea->setCurrentIF(getPreviousIF());
  }

  // QSTUFF
  // this is not a hard restriction. Once the get_next protocol supports unions
  // similar to the split-top operator, this check can be removed.
  if (getGroupAttr()->isEmbeddedUpdateOrDelete() ||
      (getGroupAttr()->isEmbeddedInsert() && !isSystemGenerated_) ||
      (bindWA->isEmbeddedIUDStatement())) {
    if (getUnionForIF()) {
      *CmpCommon::diags() << DgSqlCode(-4210);
      bindWA->setErrStatus();
      return this;
    }

  NAString fmtdList1(bindWA->wHeap());
    LIST(TableNameMap*) xtnmList1(bindWA->wHeap());
  NAString fmtdList2(bindWA->wHeap());
    LIST(TableNameMap*) xtnmList2(bindWA->wHeap());

    leftTable.getTableList(xtnmList1, &fmtdList1);
    rightTable.getTableList(xtnmList2, &fmtdList2);

    // Fix for Solution 10-070117-1834. 
    // Error Message for -4161 - assumes that both sides
    // of the UNION is an embedded operation. For a
    // query such as, 
    // select * from (delete from t709t1)as x union all (select * from t709t1)
    // the right side of the UNION is not an embedded operation.
    // Hence, changing the text for 4161 to a more generic one so
    // that all cases are covered in this one text message.


    *CmpCommon::diags() << DgSqlCode(-4161)
      << DgString0(fmtdList1)
      << DgString1(fmtdList2);

    bindWA->setErrStatus();
    return this;
  }
  // QSTUFF


  // ++MV
  // Bind the alternateRightChildOrderExprTree expression.
  //
  ItemExpr *alternateRightChildOrderExprTree = removeAlternateRightChildOrderExprTree();
  if (alternateRightChildOrderExprTree)
  {
    alternateRightChildOrderExprTree->
      convertToValueIdList(alternateRightChildOrderExpr(), bindWA, ITM_ITEM_LIST);
    if (bindWA->errStatus()) {
      return NULL;
    }
  }
  // --MV

  // Bind the base class.
  //
  RelExpr *boundExpr = bindSelf(bindWA);
  if (bindWA->errStatus()) {
    delete resultTable;
    return boundExpr;
  }
  return boundExpr;
} // Union::bindNode()

// check for & warn against UNIONs that have inconsistent access/lock modes
void Union::checkAccessLockModes()
{
  Scan *left = child(0)->getAnyScanNode();
  Scan *right = child(1)->getAnyScanNode(); 
  
  if (!left || !right) return; // no-op.

  // UNION is user-specified as opposed to system-generated (eg, by
  // triggers/RI in GenericUpdate::inlinePipelineActions, etc)
  if (isSystemGenerated_) {
    return;
  }
  
  Lng32 lockFlagSession = CmpCommon::transMode()->getDP2LockFlags().getValue();
  StmtLevelAccessOptions optionsLeft = left->accessOptions();
  StmtLevelAccessOptions optionsRight = right->accessOptions();

  Lng32 lockFlagLeft = lockFlagSession;
  Lng32 lockFlagRight = lockFlagSession;

  if (optionsLeft.userSpecified()) {
    lockFlagLeft = optionsLeft.getDP2LockFlags().getValue();
  }
  if (optionsRight.userSpecified()) {
    lockFlagRight = optionsRight.getDP2LockFlags().getValue();
  }
  if (lockFlagLeft != lockFlagRight) {
    *CmpCommon::diags()
      << DgSqlCode(3192)
      << DgString0(left->getTableName().getQualifiedNameAsString())
      << DgString1(right->getTableName().getQualifiedNameAsString());
  }
} // Union::checkAccessLockModes()

void Union::copyLeftRightListsToPreviousIF(Union * previousIF, BindWA * bindWA)
{
  AssignmentStHostVars *thisLeftList =  leftList();
  AssignmentStHostVars *thisRightList = rightList();

  // If the previous IF node does not have a left list, we copy the left and right
  // lists to that left list
  if (previousIF->currentChild() == 0 && !(previousIF->leftList())) {
      AssignmentStHostVars *leftListOfPreviousIF = previousIF->getCurrentList(bindWA);
      // Copy the leftList of this node to the left list of the previous IF
      leftListOfPreviousIF->addAllToListInIF(thisLeftList) ;
      // Copy the rightList of this node to the left list of the previous IF
      leftListOfPreviousIF->addAllToListInIF(thisRightList) ;
  }

  // If the previous IF node does not have a right list, we copy the left and right
  // lists to that left list
  if (previousIF->currentChild() == 1 && !(previousIF->rightList())) {
      AssignmentStHostVars *rightListOfPreviousIF = previousIF->getCurrentList(bindWA);
      // Copy the leftList of this node to the right list of the previous IF
      rightListOfPreviousIF->addAllToListInIF(thisLeftList) ;
      // Copy the rightList of this node to the right list of the previous IF
      rightListOfPreviousIF->addAllToListInIF(thisRightList) ;
  }
} // Union::copyLeftRightListsToPreviousIF

// -----------------------------------------------------------------------
// MV --
// A debugging method for dumping the columns in the RETDesc of both
// children when they do not match.
void Union::dumpChildrensRETDescs(const RETDesc& leftTable,
                                  const RETDesc& rightTable)
{
// turn this code on when you need it by changing the #if below
#if 0   
  // -- MVs. Debugging code !!!!! TBD
  fprintf(stdout, " #    Left                                Right\n");
  CollIndex maxIndex, minIndex;
  NABoolean leftIsBigger;
  if (leftTable.getDegree() > rightTable.getDegree())
  {
    maxIndex = leftTable.getDegree();
    minIndex = rightTable.getDegree();
    leftIsBigger = TRUE;
  }
  else
  {
    maxIndex = rightTable.getDegree();
    minIndex = leftTable.getDegree();
    leftIsBigger = FALSE;
  }

  for (CollIndex i=0; i<minIndex; i++)
  {
    ColumnDesc *leftColDesc  = leftTable.getColumnList()->at(i);
    ColumnDesc *rightColDesc = rightTable.getColumnList()->at(i);
    NAString leftCol (leftColDesc->getColRefNameObj().getColRefAsString());
    NAString rightCol(rightColDesc->getColRefNameObj().getColRefAsString());
    fprintf(stdout, " %3d  %-55s %-55s \n",
            i, leftCol.data(), rightCol.data());
  }

  if (leftIsBigger)
  {
    for (CollIndex j=minIndex; j<maxIndex; j++)
    {
      ColumnDesc *leftColDesc  = leftTable.getColumnList()->at(j);
      NAString leftCol(leftColDesc->getColRefNameObj().getColRefAsString());
      fprintf(stdout, " %3d  %-35s\n",
              j, leftCol.data());
    }
  }
  else
  {
    for (CollIndex k=minIndex; k<maxIndex; k++)
    {
      ColumnDesc *rightColDesc = rightTable.getColumnList()->at(k);
      NAString rightCol(rightColDesc->getColRefNameObj().getColRefAsString());
      fprintf(stdout, " %3d                                      %-35s \n",
              k, rightCol.data());
    }
  }
#endif
}


// ----------------------------------------------------------------------
// static helper functions for classes RelRoot and GroupByAgg
// ----------------------------------------------------------------------

static NABoolean containsGenericUpdate(const RelExpr *re)
{
  if (re->getOperator().match(REL_ANY_GEN_UPDATE)) return TRUE;
  for (Int32 i = 0; i < re->getArity(); ++i ) {
    if (re->child(i) && containsGenericUpdate(re->child(i))) return TRUE;
  }
  return FALSE;
}

static NABoolean containsUpdateOrDelete(const RelExpr *re)
{
  if (re->getOperator().match(REL_ANY_UPDATE_DELETE))
    return TRUE;
  for (Int32 i = 0; i < re->getArity(); ++i ) {
    if (re->child(i) && containsUpdateOrDelete(re->child(i)))
      return TRUE;
  }
  return FALSE;
}

// QSTUFF

static GenericUpdate *getGenericUpdate(RelExpr *re)
{
  if (re) {
    if (re->getOperatorType() == REL_UNARY_UPDATE ||
        re->getOperatorType() == REL_UNARY_DELETE)
      return (GenericUpdate *)re;

    for (Int32 i = 0; i < re->getArity(); ++i) {    // check all children (both sides)
      GenericUpdate *gu = getGenericUpdate(re->child(i));
      if (gu) return gu;
    }
  }
  return NULL;
}

static NABoolean checkUnresolvedAggregates(BindWA *bindWA)
{
  const ValueIdSet &aggs = bindWA->getCurrentScope()->getUnresolvedAggregates();
  if (aggs.isEmpty()) return FALSE;         // no error

  NAString unparsed(bindWA->wHeap());
  for (ValueId vid = aggs.init(); aggs.next(vid); aggs.advance(vid)) {

    const ItemExpr *ie = vid.getItemExpr();
    CMPASSERT(ie->isAnAggregate());
    Aggregate *agg = (Aggregate *)ie;

  // Don't display COUNT() part of SUM()/COUNTxxx(), our implementation of AVG()
  // Display only the COUNT_NONULL() our implementation of VARIANCE and STDDEV
  // This is to avoid printing the aggregate functions more than once.

    if((agg->origOpType() != ITM_AVG || agg->getOperatorType() == ITM_SUM) &&
       (!(agg->origOpType() == ITM_STDDEV || agg->origOpType() == ITM_VARIANCE)
       || agg->getOperatorType() == ITM_COUNT_NONULL)){

      unparsed += ", ";
      if (agg->origOpType() == ITM_COUNT_STAR__ORIGINALLY)
        unparsed += "COUNT(*)";
      else
        agg->unparse(unparsed, DEFAULT_PHASE, USER_FORMAT_DELUXE);
    }
  }
  unparsed.remove(0,2);              // remove initial ", "

  // 4015 Aggregate functions placed incorrectly.
  *CmpCommon::diags() << DgSqlCode(-4015) << DgString0(unparsed);
  bindWA->setErrStatus();
  return TRUE;
} // checkUnresolvedAggregates()

// ----------------------------------------------------------------------
// member functions for class RelRoot
// ----------------------------------------------------------------------


static NABoolean isRenamedColInSelList(BindWA * bindWA, ItemExpr * col, 
                                       ItemExprList &origSelectList,
                                       CollIndex &indx,
                                       RETDesc * childRETDesc)
{
  if (col->getOperatorType() != ITM_REFERENCE)
    return FALSE;

  ColReference * havingColReference = (ColReference*)col;
  
  CollIndex j = 0;

  NABoolean found = FALSE;
  while (j < origSelectList.entries())
    {
      ItemExpr * selectListEntry = origSelectList[j];
      
      if (selectListEntry->getOperatorType() == ITM_RENAME_COL)
        {
          const ColRefName &selectListColRefName = 
            *((RenameCol *)selectListEntry)->getNewColRefName();
          
          if (havingColReference->getColRefNameObj() == selectListColRefName)
            {
              if (found)
                {
                  // multiple entries with the same name. Error.
                  *CmpCommon::diags() << DgSqlCode(-4195) 
                                      << DgString0(selectListColRefName.getColName());
                  bindWA->setErrStatus();
                  return FALSE;
                }

              ColumnNameMap *baseColExpr = NULL;
              if (childRETDesc)
                baseColExpr = childRETDesc->findColumn(selectListColRefName);
              if ( NOT baseColExpr)
              { 
                found = TRUE;
                indx = j;
              }
            }
        } // rename col
      
      j++;
    } // while
  return found;
}

static short replaceRenamedColInHavingWithSelIndex(
                                     BindWA * bindWA,
                                     ItemExpr * expr, 
                                     ItemExprList &origSelectList,
                                     NABoolean &replaced,
                                     NABoolean &notAllowedWithSelIndexInHaving,
                                     RETDesc * childRETDesc)
{
  if (((expr->getOperatorType() >= ITM_ROW_SUBQUERY) &&
       (expr->getOperatorType() <= ITM_GREATER_EQ_ANY)) ||
      ((expr->getOperatorType() >= ITM_AVG) &&
       (expr->getOperatorType() <= ITM_VARIANCE)) ||
      ((expr->getOperatorType() >= ITM_DIFF1) &&
       (expr->getOperatorType() <= ITM_NOT_THIS)))
    {
      notAllowedWithSelIndexInHaving = TRUE;
      return 0;
    }

  for (Int32 i = 0; i < expr->getArity(); i++)
    {
      CollIndex j = 0;
      if (isRenamedColInSelList(bindWA, expr->child(i), origSelectList, 
                                j, childRETDesc))
        {
          SelIndex * selIndex = new(bindWA->wHeap()) SelIndex(j+1);
          expr->setChild(i, selIndex);
          replaced = TRUE;
        }
      else if (bindWA->errStatus())
        return -1;
      else if (replaceRenamedColInHavingWithSelIndex(
                              bindWA, expr->child(i), origSelectList, replaced,
                              notAllowedWithSelIndexInHaving, childRETDesc))
        return -1;
    }
  return 0;
}

static short setValueIdForRenamedColsInHaving(BindWA * bindWA,
                                              ItemExpr * expr, 
                                              ValueIdList &compExpr)
{
  if (((expr->getOperatorType() >= ITM_ROW_SUBQUERY) &&
       (expr->getOperatorType() <= ITM_GREATER_EQ_ANY)) ||
      ((expr->getOperatorType() >= ITM_AVG) &&
       (expr->getOperatorType() <= ITM_VARIANCE)) ||
      ((expr->getOperatorType() >= ITM_DIFF1) &&
       (expr->getOperatorType() <= ITM_NOT_THIS)))
    {
      return 0;
    }

  for (Int32 i = 0; i < expr->getArity(); i++)
    {
      if (expr->child(i)->getOperatorType() == ITM_SEL_INDEX)
        {
          SelIndex * si = (SelIndex*)expr->child(i)->castToItemExpr();
          si->setValueId(compExpr[si->getSelIndex()-1]);
        }
      else
        setValueIdForRenamedColsInHaving(bindWA, expr->child(i), compExpr);
    }
  return 0;
}

// Method to update the selIndecies after we have gone through a
// selectList expansion due to MVFs or Subqueries with degree > 1
// used to update the orderByTree
// 
// Returns a list of SelIndecies that were updated.
static void fixUpSelectIndecies(ItemExpr * expr, ValueIdSet &updatedIndecies,
                                CollIndex idx, CollIndex offset)
{

  if (expr == NULL ) return;

  for (Int32 i = 0; i < expr->getArity(); i++)
    {
      // Only update ones that we haven't already done.
      if ((expr->child(i)->getOperatorType() == ITM_SEL_INDEX) && 
           !updatedIndecies.contains(expr->child(i)->getValueId()))
        {
          SelIndex * si = (SelIndex*)expr->child(i)->castToItemExpr();
          if (si->getSelIndex() > idx)
          {
            si->setSelIndex(si->getSelIndex() + offset);
            updatedIndecies += si->getValueId();
          }
        }
      else
        fixUpSelectIndecies(expr->child(i), updatedIndecies, idx, offset);
    }

    // Now check myself..
    // Only update ones that we haven't already done.
    if ((expr->getOperatorType() == ITM_SEL_INDEX) && 
         !updatedIndecies.contains(expr->getValueId()))
      {
        SelIndex * si = (SelIndex*)expr->castToItemExpr();
        if (si->getSelIndex() > idx)
        {
          si->setSelIndex(si->getSelIndex() + offset);
          updatedIndecies += si->getValueId();
        }
      }
}

// Method to update the selIndecies after we have gone through a
// selectList expansion due to MVFs or Subqueries with degree > 1
// used to update the GroupByList
// 
// Returns a list of SelIndecies that were updated.
static void fixUpSelectIndeciesInSet(ValueIdSet & expr, 
                                ValueIdSet &updatedIndecies,
                                CollIndex idx, 
                                CollIndex offset)
{

  for (ValueId vid = expr.init(); expr.next(vid); expr.advance(vid))
    {
      // Only update ones that we haven't already done.
      if (((ItemExpr *)vid.getItemExpr())->getOperatorType() == ITM_SEL_INDEX &&
          !updatedIndecies.contains(vid))
        {
          SelIndex * si = (SelIndex*) vid.getItemExpr();
          if (si->getSelIndex() > idx)
          {
            si->setSelIndex(si->getSelIndex() + offset);
            updatedIndecies += si->getValueId();
          }
        }
    }
}

RelRoot * RelRoot::transformOrderByWithExpr(BindWA *bindWA)
{
  NABoolean specialMode = (CmpCommon::getDefault(GROUP_OR_ORDER_BY_EXPR) == DF_ON);
  if (NOT specialMode)
    return this;
  ItemExprList origSelectList(bindWA->wHeap());
  ItemExprList origOrderByList(bindWA->wHeap());
  
  CollIndex origSelectListCount ;
  if ((getCompExprTree() == NULL) &&
      (child(0)->getOperatorType() != REL_GROUPBY))
    {
      return this;
    }
  
  ItemExpr *orderByTree = getOrderByTree();
  if (!orderByTree) 
    return this;
  
  if (orderByTree)
    {
      origOrderByList.insertTree(orderByTree);
    }
  
  if (getCompExprTree())
    origSelectList.insertTree(getCompExprTree());
  else if (child(0)->getOperatorType() == REL_GROUPBY)
    {
      // this is the case:  select distinct <expr> from t order by <expr>
      GroupByAgg * grby = (GroupByAgg *)(child(0)->castToRelExpr());
      if (grby->child(0) && grby->child(0)->getOperatorType() == REL_ROOT)
        {
          RelRoot * selRoot = (RelRoot*)grby->child(0)->castToRelExpr();
          if (selRoot->getCompExprTree())
            origSelectList.insertTree(selRoot->getCompExprTree());
        }
    }
  
  Lng32 selListCount = origSelectList.entries();

  // if there is an expression in the order by list and this expression matches
  // a select list expression, then replace it with the index of that select list item.
  ItemExprList newOrderByList((Lng32)origOrderByList.entries(), bindWA->wHeap());
  NABoolean orderByExprFound = FALSE;
  for (Lng32 i = 0; i < origOrderByList.entries(); i++)
    {
      ItemExpr * currOrderByItemExpr = origOrderByList[i];

      NABoolean isDesc = FALSE;
      if (currOrderByItemExpr->getOperatorType() == ITM_INVERSE)
        {
          currOrderByItemExpr = currOrderByItemExpr->child(0)->castToItemExpr();
          isDesc = TRUE;
        }

      if (NOT ((currOrderByItemExpr->getOperatorType() == ITM_SEL_INDEX) ||
               (currOrderByItemExpr->getOperatorType() == ITM_REFERENCE) ||
               (currOrderByItemExpr->getOperatorType() == ITM_CONSTANT)))
        {
          NABoolean found = FALSE;
          Lng32 selListIndex = 0;
          ItemExpr * selItem = NULL;
          ItemExpr * renameColEntry = NULL;
          while ((NOT found) && (selListIndex < selListCount))
            {
              selItem = origSelectList[selListIndex];
              
              if (selItem->getOperatorType() == ITM_RENAME_COL)
                {
                  renameColEntry = selItem;
                  selItem = selItem->child(0);
                }
              
              found = currOrderByItemExpr->duplicateMatch(*selItem);
              if (NOT found)
                selListIndex++;
            }
          
          if (NOT found)
            {
              *CmpCommon::diags() << DgSqlCode(-4197) 
                                  << DgString0("ORDER BY");
              bindWA->setErrStatus();
              return NULL;
            }

          selItem->setInOrderByOrdinal(TRUE);
          currOrderByItemExpr = new(bindWA->wHeap()) SelIndex(selListIndex+1);
          if (isDesc)
            {
              currOrderByItemExpr = new(bindWA->wHeap()) InverseOrder(currOrderByItemExpr);
            }

          orderByExprFound = TRUE;
        } // if order by expr
      
      newOrderByList.insert(currOrderByItemExpr);
    }
  
  if ((orderByExprFound) &&
      (newOrderByList.entries() > 0))
    {
      removeOrderByTree();
      addOrderByTree(newOrderByList.convertToItemExpr());
    }

  return this;
}

//////////////////////////////////////////////////////////////////////
// GROUPING functions returns a 1 or 0 depending on whether a null
// value was moved as a rollup group or not.
//
// GROUPING_ID(a,b,c) returns a value corresponding to the bit vector 
// where each bit entry represents the GROUPING result for the argument
// of GROUPING_ID function.
//
// For ex: GROUPING_ID(a,b,c) will have 3 bit entries, 
// and is equivalent to:
//   GROUPING(a)*4 + GROUPING(b)*2 + GROUPING(c)*1
//////////////////////////////////////////////////////////////////////
ItemExpr * RelRoot::processGroupingID(ItemExpr * ie, BindWA *bindWA)
{
  if (ie->getOperatorType() != ITM_GROUPING_ID)
    return ie;

  ItemExpr * groupingIdExpr = NULL;

  ItemExprList childExprList(bindWA->wHeap());
  childExprList.insertTree(ie->child(0)->castToItemExpr());
  
  Int64 multiplier = (Int64)pow(2, (childExprList.entries()-1));
  SQLLargeInt * li = 
    new(bindWA->wHeap()) SQLLargeInt(FALSE, FALSE); // +ve value, no nulls
  for (CollIndex i = 0; i < (CollIndex)childExprList.entries(); i++)
    {
      ItemExpr * currChildIE = 
        ((ItemExpr *) childExprList[i])->castToItemExpr();
      
      ItemExpr * groupingClause =
        new(bindWA->wHeap()) Aggregate(ITM_GROUPING, currChildIE, FALSE);
      
      ItemExpr * multiplierClause = new(bindWA->wHeap()) 
        ConstValue(li, (void*)&multiplier, sizeof(Int64));
      ItemExpr * groupingExpr = new(bindWA->wHeap()) 
        BiArith(ITM_TIMES, groupingClause, multiplierClause);
      
      if (i == 0)
        {
          groupingIdExpr = groupingExpr;
        }
      else
        {
          groupingIdExpr = new(bindWA->wHeap())
            BiArith(ITM_PLUS, groupingIdExpr, groupingExpr);
        }
      
      multiplier = multiplier / 2;
    }
  
  groupingIdExpr = new(bindWA->wHeap()) Cast(groupingIdExpr, li);

  return groupingIdExpr;
}

///////////////////////////////////////////////////////////////////////////
//
// This methods performs the following in this order:
//
// If groupby name refers to a renamed col name in the select list,
// replace group by entry with ordinal position of that sel list entry.
//
// If groupby ordinal exceeds the number of select list elements, 
// return error.
//
// If groupby ordinal referes to a '*', return error.
// 
// If groupby ordinal refers to a column(ITM_REFERENCE) or a renamed 
// col name(ITM_RENAME_COL) whose child is a column(ITM_REFERENCE),
// replace ordinal with actual col name.
//
// If there are ordinals in group by list, mark RelRoot indicating
// phase2 transformation is needed.
//
// Mark all select list item exprs which are referened as an ordinal to
// indicate that groupby check to validate grouping columns is not needed
// for the subtree rooted below that select list item.
//
///////////////////////////////////////////////////////////////////////////
RelRoot * RelRoot::transformGroupByWithOrdinalPhase1(BindWA *bindWA)
{
  NABoolean specialMode =
    (CmpCommon::getDefault(MODE_SPECIAL_1) == DF_ON);

  // make sure child of root is a groupby node.or a sequence node 
  // whose child is a group by node
  if (child(0)->getOperatorType() != REL_GROUPBY && 
      (child(0)->getOperatorType() != REL_SEQUENCE || 
       (child(0)->child(0) && child(0)->child(0)->getOperatorType()!=REL_GROUPBY)))
    return this;

  NABoolean compExprTreeIsNull = FALSE;
  CollIndex origSelectListCount ;
  if (getCompExprTree() == NULL)
  {
    compExprTreeIsNull = TRUE;
    origSelectListCount = 0;
   // return this;
  }

  GroupByAgg * grby;

  if (child(0)->getOperatorType() == REL_GROUPBY)
  {  
    grby = (GroupByAgg *)(child(0)->castToRelExpr());
  }
  else
  {// sequence node above group by
    grby = (GroupByAgg *)(child(0)->child(0)->castToRelExpr());
  }

  DCMPASSERT(grby != NULL);

  if ((NOT specialMode) &&
      (grby->getGroupExprTree() == NULL))
    return this;

  ItemExpr * groupExprTree  = grby->getGroupExprTree();
  ItemExprList origSelectList(bindWA->wHeap());
  ItemExprList origGrbyList(bindWA->wHeap());

  if (groupExprTree)
  {
    origGrbyList.insertTree(groupExprTree);
  }

  if (NOT compExprTreeIsNull)
  {
    // expand GROUPING_ID in terms of GROUPING aggregates
    if (grby->isRollup())
      {
        NABoolean groupingIDfound = FALSE;

        ItemExprList selList(getCompExprTree(), bindWA->wHeap());
        ItemExprList newSelList(bindWA->wHeap());
        for (CollIndex ii = 0; ii < selList.entries(); ii++)
          {
            ItemExpr * ie = selList[ii];
            if (ie->getOperatorType() == ITM_GROUPING_ID)
              {
                ItemExpr * newIE = processGroupingID(ie, bindWA);
                if (bindWA->errStatus())
                  return this;
                
                groupingIDfound = TRUE;
                newSelList.insert(newIE);
              }
            else
              newSelList.insert(ie);
          } // for

        if (groupingIDfound)
          {
            ItemExpr * newCompExprTree = newSelList.convertToItemExpr();
            removeCompExprTree();
            addCompExprTree(newCompExprTree);
          }
       }

    origSelectList.insertTree(getCompExprTree());
    origSelectListCount = origSelectList.entries();
  }

  ItemExprList newGroupByList((Lng32)origGrbyList.entries(), bindWA->wHeap());
  
  NABoolean foundSelIndex = FALSE;

  NABoolean lookForRenamedCols = TRUE;
  if ((CmpCommon::getDefault(GROUP_OR_ORDER_BY_EXPR) == DF_OFF) &&
      (NOT specialMode))
    lookForRenamedCols = FALSE;

  NABoolean lookForExprInGroupByClause = TRUE;
  if (CmpCommon::getDefault(COMP_BOOL_92) == DF_ON)
    lookForExprInGroupByClause = FALSE;

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

  // This list will store duplicate expression specified in  select list and 
  // GroupBy clause. It helps with specifying select Index  as well as 
  // mark InGroupByOrdinal flag correctly (Gen Sol:10-100129-7836)
  NAList<CollIndex> listOfExpressions(CmpCommon::statementHeap());

  for (CollIndex i = 0; (i < (CollIndex) origGrbyList.entries());i++)
    {
      ItemExpr * currGroupByItemExpr = 
        ((ItemExpr *) origGrbyList[i])->castToItemExpr();
      ItemExpr * newGroupByItemExpr = NULL;

      NABoolean selIndexError = FALSE;
      Int64 selIndex = -1;
      if (currGroupByItemExpr->getOperatorType() == ITM_CONSTANT)
        {
          ConstValue * cv = (ConstValue*)currGroupByItemExpr;
          if ((cv->canGetExactNumericValue()) &&
              (cv->getType()->getScale() == 0))
            {
              selIndex = cv->getExactNumericValue();
              if ((selIndex >= 0) && (selIndex < MAX_COMSINT32))
                {
                  if (selIndex == 0 || selIndex > origSelectListCount)
                    {
                      // remember that this select index is in error.
                      // Look for this constant in the select list.
                      // If it is not found, then this const will be
                      // treated as a select index and an error will 
                      // returned. If it is found in the select list,
                      // then it will be treated as a group by expression.
                      selIndexError = TRUE;
                    }
                  else
                    currGroupByItemExpr = 
                      new(bindWA->wHeap()) SelIndex((Lng32)selIndex);
                }
            }
        }

      NABoolean found = FALSE;
      if ((currGroupByItemExpr->getOperatorType() != ITM_REFERENCE) &&
          (currGroupByItemExpr->getOperatorType() != ITM_SEL_INDEX) &&
          (lookForExprInGroupByClause))
        {
           Int32 selListIndex = -1, lastMatch = -1;
          CollIndex j = 0;
          while ((NOT found) && (j < origSelectListCount))
            {
              ItemExpr * selectListEntry = origSelectList[j];
              
              if ((selectListEntry->getOperatorType() != ITM_REFERENCE) &&
                  ((selectListEntry->getOperatorType() != ITM_RENAME_COL) ||
                  ((selectListEntry->child(0)) && 
                  (selectListEntry->child(0)->getOperatorType() != ITM_REFERENCE))))
                {
                  ItemExpr * renameColEntry = NULL;
                  if (selectListEntry->getOperatorType() == ITM_RENAME_COL)
                    {
                      renameColEntry = selectListEntry;
                      selectListEntry = selectListEntry->child(0);
                    }
                  
                  found = 
                    currGroupByItemExpr->duplicateMatch(*selectListEntry);
                  if (found)
                    {
		      lastMatch = j;
		      if(!listOfExpressions.contains(j))
		      {
			selListIndex = j;
			listOfExpressions.insert(j);
			
                        selectListEntry->setInGroupByOrdinal(TRUE);
                        selectListEntry->setIsGroupByExpr(TRUE);

			if (renameColEntry)
			  renameColEntry->setInGroupByOrdinal(TRUE);
		      }
		      else
			found = FALSE;
                    }
                }
              j++;
            } // while

	    if(lastMatch != -1)
	    {
	      found = TRUE;

	      if(selListIndex == -1)
		selListIndex = lastMatch;

	      if (bindWA->inViewDefinition())
		currGroupByItemExpr = 
		  new(bindWA->wHeap()) SelIndex(selListIndex+1, 
						currGroupByItemExpr);
	      else
		currGroupByItemExpr = new(bindWA->wHeap()) SelIndex(selListIndex+1);
	    }
        } // expr in group by clause
      
      if ((NOT found) &&
          (selIndexError) &&
          (selIndex > 0))
        {
          // this const was not found in the select list and it was
          // not a valid select index.
          // Return an error.
          *CmpCommon::diags() << DgSqlCode(-4007) 
                              << DgInt0((Lng32)selIndex)
                              << DgInt1((Lng32)origSelectList.entries());
          bindWA->setErrStatus();
          return NULL;
        }
      if (compExprTreeIsNull)
        return this;

      if (currGroupByItemExpr->getOperatorType() == ITM_SEL_INDEX)
        {
          SelIndex * si = (SelIndex*)currGroupByItemExpr;
          if (si->getSelIndex() > origSelectList.entries())
            {
              *CmpCommon::diags() << DgSqlCode(-4007) 
                                  << DgInt0((Lng32)si->getSelIndex()) 
                                  << DgInt1((Lng32)origSelectList.entries());
              bindWA->setErrStatus();
              return NULL;
            }

          ItemExpr * selectListEntry = origSelectList[si->getSelIndex()-1];
          if ((selectListEntry->getOperatorType() == ITM_RENAME_COL) &&
              (selectListEntry->child(0)->getOperatorType() == ITM_REFERENCE))
            {
              // make a copy of this entry's child
              newGroupByItemExpr = 
                selectListEntry->child(0)->
                  castToItemExpr()->copyTopNode(NULL, bindWA->wHeap());
            }
          else if (selectListEntry->getOperatorType() == ITM_REFERENCE)
            {
              if (((ColReference*)selectListEntry)-> getColRefNameObj().isStar())
                {
                  *CmpCommon::diags() << DgSqlCode(-4185) ;
                  bindWA->setErrStatus();
                  return NULL;
                }

              // make a copy of this entry
              newGroupByItemExpr = 
                selectListEntry->copyTopNode(NULL, bindWA->wHeap());
            }
          else
            {
              selectListEntry->setInGroupByOrdinal(TRUE);
              newGroupByItemExpr = currGroupByItemExpr;
            }

          foundSelIndex = TRUE;
        } // group by ordinal
      else if (currGroupByItemExpr->getOperatorType() == ITM_REFERENCE)
        {
           ColReference * groupByColReference = 
                                 (ColReference*)currGroupByItemExpr;
           
          // find out if this ColReference name is a renamed col in the
          // select list.
          if (lookForRenamedCols && 
              groupByColReference->getCorrNameObj().getQualifiedNameObj().getObjectName().length() == 0)
            {

              NABoolean renamedColsInSelectList = FALSE;
              CollIndex j = 0;
              NABoolean found = FALSE;
              while (j < origSelectList.entries())
                {
                  ItemExpr * selectListEntry = origSelectList[j];

                  if (selectListEntry->getOperatorType() == ITM_RENAME_COL)
                    {
                      renamedColsInSelectList = TRUE;

                      const ColRefName &selectListColRefName = 
                        *((RenameCol *)selectListEntry)->getNewColRefName();
                      
                      if (groupByColReference->getColRefNameObj().getColName()
                          == selectListColRefName.getColName())
                        {
                          if (found)
                            {
                              // multiple entries with the same name. Error.
                              *CmpCommon::diags() << DgSqlCode(-4195) 
                                << DgString0(selectListColRefName.getColName());
                              bindWA->setErrStatus();
                              return NULL;
                            }

                          foundSelIndex = TRUE;

                          selectListEntry->setInGroupByOrdinal(TRUE);

                          newGroupByItemExpr = 
                            new(bindWA->wHeap()) SelIndex(j+1);
                          ((SelIndex *) newGroupByItemExpr)->
                            setRenamedColNameInGrbyClause(TRUE);


                          found = TRUE;
                        }
                    } // rename col

                  j++;
                } // while

              if ((NOT renamedColsInSelectList) &&
                  (j == origSelectList.entries()))
                lookForRenamedCols = FALSE;
            } // lookForRenamedCols

          if (! newGroupByItemExpr)
            newGroupByItemExpr = currGroupByItemExpr;
        } // else foundSelIndex
      else if ((currGroupByItemExpr->getOperatorType() == ITM_USER_DEF_FUNCTION) &&
               (udfSubqInAggGrby_Enabled))
            newGroupByItemExpr = currGroupByItemExpr;
      else if ((currGroupByItemExpr->getOperatorType() == ITM_ROW_SUBQUERY) &&
               (udfSubqInAggGrby_Enabled))
            newGroupByItemExpr = currGroupByItemExpr;
      else
        {
          *CmpCommon::diags() << DgSqlCode(-4197) 
                              << DgString0("GROUP BY");
          bindWA->setErrStatus();
          return NULL;
        }

      newGroupByList.insert(newGroupByItemExpr);

    } // for
  
  if ((foundSelIndex) &&
      (newGroupByList.entries() > 0))
    {
      grby->removeGroupExprTree();
      grby->addGroupExprTree(newGroupByList.convertToItemExpr());
    }

  grby->setParentRootSelectList(getCompExprTree());

  // if order by and group by are specified, check to see that
  // all columns specified in the order by clause are also present
  // in the group by clause.
  allOrderByRefsInGby_ = FALSE;
  if (
      (getOrderByTree()) &&
      (grby->getGroupExprTree() != NULL))
    {
      ItemExpr *orderByTree = getOrderByTree();

      ItemExprList orderByList(orderByTree, bindWA->wHeap());
      ItemExprList groupByList(grby->getGroupExprTree(), bindWA->wHeap());

      allOrderByRefsInGby_ = TRUE;
      for (CollIndex ii = 0; ii < orderByList.entries(); ii++)
        {
          ItemExpr * colRef = orderByList[ii];
          if (colRef->getOperatorType() == ITM_INVERSE)
            colRef = colRef->child(0)->castToItemExpr();
          if (colRef && colRef->getOperatorType() == ITM_REFERENCE)
            {
              ColReference * obyColRef = (ColReference*)colRef;
              
              NABoolean found = FALSE;
              for (CollIndex j = 0; j < groupByList.entries(); j++)
                {
                  ItemExpr * gbyExpr = groupByList[j];
                  if (gbyExpr->getOperatorType() == ITM_REFERENCE)
                    {
                      ColReference * gbyColRef = (ColReference*)gbyExpr;
                      if (obyColRef->getColRefNameObj().getColName() ==
                          gbyColRef->getColRefNameObj().getColName())
                        {
                          found = TRUE;
                          break;
                        }
                    } // if
                } // for

              if (NOT found)
                {
                  allOrderByRefsInGby_ = FALSE;
                  break;
                }
            } // if
        } // for
    } // if

  return this;
}

RelRoot * RelRoot::transformGroupByWithOrdinalPhase2(BindWA *bindWA)
{
  NABoolean specialMode =
    (CmpCommon::getDefault(MODE_SPECIAL_1) == DF_ON);

  // make sure child of root is a groupby node or a sequence node 
  // whose child is a group by node
  if (child(0)->getOperatorType() != REL_GROUPBY && 
       (child(0)->getOperatorType() != REL_SEQUENCE || 
         (child(0)->child(0) && child(0)->child(0)->getOperatorType()!=REL_GROUPBY)))
    return this;

  GroupByAgg * grby;
  RelSequence * seqNode=NULL;

  if (child(0)->getOperatorType() == REL_GROUPBY )
  {
    grby=(GroupByAgg *)(child(0)->castToRelExpr());
  }
  else
  {//sequence node above group by
    grby=(GroupByAgg *)(child(0)->child(0)->castToRelExpr());
    seqNode=(RelSequence *)(child(0)->castToRelExpr());
  }

  DCMPASSERT(grby != NULL);

  if (grby->isRollup())
    {
      if (grby->groupExpr().entries() != grby->rollupGroupExprList().entries())
        {
          *CmpCommon::diags() << DgSqlCode(-4384)
                              << DgString0("Cannot have duplicate entries.");
          
          bindWA->setErrStatus();
          return NULL;
        }

      for (ValueId valId = grby->aggregateExpr().init();
           grby->aggregateExpr().next(valId);
           grby->aggregateExpr().advance(valId))
        {
          ItemExpr * ae = valId.getItemExpr();

          // right now, only support groupby rollup on min/max/sum/avg/count
          if (NOT ((ae->getOperatorType() == ITM_MIN) ||
                   (ae->getOperatorType() == ITM_MAX) ||
                   (ae->getOperatorType() == ITM_SUM) ||
                   (ae->getOperatorType() == ITM_AVG) ||
                   (ae->getOperatorType() == ITM_COUNT) ||
                   (ae->getOperatorType() == ITM_COUNT_NONULL) ||
                   (ae->getOperatorType() == ITM_GROUPING)))
            {
              *CmpCommon::diags() << DgSqlCode(-4384)
                                  << DgString0("Unsupported rollup aggregate function.");
              
              bindWA->setErrStatus();
              return NULL;
            }
          
          // right now, only support groupby rollup on non-distinct aggrs
          Aggregate * ag = (Aggregate*)ae;
          if (ag->isDistinct())
            {
              *CmpCommon::diags() << DgSqlCode(-4384)
                                  << DgString0("Distinct rollup aggregates not supported.");
              
              bindWA->setErrStatus();
              return NULL;
            }

          // if grouping aggr, find the rollup group it corresponds to.
          if (ae->getOperatorType() == ITM_GROUPING)
            {
              NABoolean found = FALSE;
              ItemExpr * aggrChild = ae->child(0);
              int i = 0;
              while ((NOT found) and (i < grby->rollupGroupExprList().entries()))
                {
                  ValueId vid =  grby->rollupGroupExprList()[i];
                  if (vid.getItemExpr()->getOperatorType() == ITM_SEL_INDEX)
                    {
                      SelIndex * si = (SelIndex*)vid.getItemExpr();
                      vid = compExpr()[si->getSelIndex()-1];
                    }
                  found =  aggrChild->duplicateMatch(*vid.getItemExpr());
                  if (found)
                    ag->setRollupGroupIndex(i);
                  i++;
                } // while

              if (NOT found)
                {
                  // must find it.
                  *CmpCommon::diags() << DgSqlCode(-4384)
                                      << DgString0("GROUPING function can only be specified on a GROUP BY ROLLUP entry.");
                  
                  bindWA->setErrStatus();
                  return NULL;
                }
            }
        } // for
    }
  else
    {
      // not groupby rollup
      for (ValueId valId = grby->aggregateExpr().init();
           grby->aggregateExpr().next(valId);
           grby->aggregateExpr().advance(valId))
        {
          ItemExpr * ae = valId.getItemExpr();

          // grouping can only be specified with 'groupby rollup' clause
          if (ae->getOperatorType() == ITM_GROUPING)
            {
              *CmpCommon::diags() << DgSqlCode(-3242)
                                  << DgString0("GROUPING function can only be specified with GROUP BY ROLLUP clause.");
              
              bindWA->setErrStatus();
              return NULL;
            }
 
        } // for
    }

  ValueIdSet &groupExpr = grby->groupExpr();
  // copy of groupExpr used to identify the changed
  // value ids
  ValueIdSet groupExprCpy(grby->groupExpr());

  // When we encounter subqueries or MVFs in the select list 
  // these gets expanded at bind time, and so the select index have to
  // be offset with the expansion number since the sel_index number 
  // reflects the select list at parse time.
  for (ValueId vid = groupExpr.init(); 
       groupExpr.next(vid);
       groupExpr.advance(vid))
    {
      if (vid.getItemExpr()->getOperatorType() == ITM_SEL_INDEX)
        {
          CollIndex selIndexExpansionOffset = 0;
          SelIndex * si = (SelIndex*)(vid.getItemExpr());
          ValueId grpById = 
                      compExpr()[si->getSelIndex() -1];
          si->setValueId(grpById);
          if (child(0)->getOperatorType() != REL_SEQUENCE)
          {
            groupExprCpy.remove(vid);
            groupExprCpy.insert(grpById);
            if (grby->isRollup())
              {
                CollIndex idx = grby->rollupGroupExprList().index(vid);
                grby->rollupGroupExprList()[idx] = grpById;
              }
          }
          else
          {  //sequence
            CMPASSERT(seqNode);
            const ValueIdSet seqCols = ((const RelSequence*)seqNode)->sequencedColumns();

            ItemExpr * ie = grpById.getItemExpr();
            ItemExpr::removeNotCoveredFromExprTree(ie,seqCols);

            //ie = ie->copyTree(bindWA->wHeap());
            //ie = ie->bindNode(bindWA);
            if (bindWA->errStatus())
	      return NULL;

            groupExprCpy.remove(vid);
            groupExprCpy.insert(ie->getValueId());

            ie = new (bindWA->wHeap()) NotCovered(ie);
            ie->synthTypeAndValueId();

            compExpr()[si->getSelIndex()-1] = ie->getValueId();
            seqNode->addSequencedColumn(ie->getValueId());

          }

          switch (grpById.getItemExpr()->getOperatorType())
          {
            case ITM_VALUEID_PROXY:
            {
              ValueId derivedId = 
                    (( ValueIdProxy *)(grpById.getItemExpr()))->isDerivedFrom();

              // If this is not the ValueIdProxy that represents the MVF or Subq
              // skip the expansion.
              if ((( ValueIdProxy *)(grpById.getItemExpr()))->
                     needToTransformChild() != TRUE) break;

              ValueIdList outputs;

              switch (derivedId.getItemExpr()->getOperatorType())
              {
                case ITM_USER_DEF_FUNCTION:
                {
                  // When we reference a UDF in the groupBy clause,
                  // if the UDF is a MVF(has multiple outputs), we need to add 
                  // the other elements from the MVF's outputs.
                
                  // These elements have already been expanded into the 
                  // select list, so all we need to do is to add them to the
                  // groupby expression.
   
                  // By default, we associate the valueId of the MVF with 
                  // its first output, so we just need to copy the rest of the 
                  // outputs.
                  UDFunction *udf = (UDFunction *) derivedId.getItemExpr();
                  const RoutineDesc *rDesc = udf->getRoutineDesc();
                  outputs =  rDesc->getOutputColumnList();
                  break;
                }

                case ITM_ROW_SUBQUERY:
                {
                  // When we reference a subquery in the groupBy clause,
                  // if the subquery has a degree > 1, we need to add the other
                  // elements from the subquery's select list.
                  Subquery *subq = (Subquery *) derivedId.getItemExpr();
                  RelRoot *subqRoot = (RelRoot *) subq->getSubquery();
                  outputs =  subqRoot->compExpr();
                  break;
                }
                default:
                  CMPASSERT(0); // we don't support anything else
              }


              // Add in the other outputs from the MVF/Subquery
              for (CollIndex i=1; i < outputs.entries();  i++)
              {
                selIndexExpansionOffset ++;
                groupExprCpy.insert(outputs[i]);
              }

              // Need to check the groupBy and orderBy lists
              // for selIndexes with an index greater than this one, 
              // If we find one, bump its index into the select list by
              // the expansion.
     
              ValueIdSet fixedUpIndecies;

              fixUpSelectIndeciesInSet(grby->groupExpr(),fixedUpIndecies,
                                       si->getSelIndex(), 
                                       selIndexExpansionOffset);

              fixUpSelectIndecies(getOrderByTree(), fixedUpIndecies,
                                  si->getSelIndex(), 
                                  selIndexExpansionOffset);
            break;
            }
          }

          // Now that we have swapped the vid list from grouping
          // expression to the corresponding one from select list
          // go thru each expression, collect the base columns
          // and mark each column as referenced for histogram.
          // Since this is only for group by, we will get only single
          // interval histograms - 10-081015-6557
          ValueIdSet columns;
          grpById.getItemExpr()->findAll(ITM_BASECOLUMN, columns, TRUE, TRUE);
          for (ValueId id = columns.init(); 
                       columns.next(id); 
                       columns.advance(id))
          {
            NAColumn *nacol = id.getNAColumn();
            if (nacol->isReferencedForHistogram())
              continue;
            nacol->setReferencedForSingleIntHist();
          }
       } // found Sel Index
    }

  ValueId valId;
  if (grby->isRollup())
    {
      for (CollIndex i = 0; i < grby->rollupGroupExprList().entries(); i++)
        {
          valId = grby->rollupGroupExprList()[i];
          
          if (NOT valId.getType().supportsSQLnull())
            {
              *CmpCommon::diags() << DgSqlCode(-4384)
                                  << DgString0("Grouped columns must be nullable.");
              bindWA->setErrStatus();
              return NULL;
            }
        }
    }

  //looking for extra order requirement, currently, aggregate function PIVOT_GROUP will need extra order 
  //so loop through the aggregation expression and check if there is PIVOT_GROUP and it needs explicit order
  //if found, populate the extraOrderExpr for the GroupAggBy
  //so later optimizer can add correct sort key 
  ValueIdSet &groupAggExpr = grby->aggregateExpr();

  for (ValueId vid = groupAggExpr.init(); 
       groupAggExpr.next(vid);
       groupAggExpr.advance(vid))
    {
      if (vid.getItemExpr()->getOperatorType() == ITM_PIVOT_GROUP)
      {
        if( ((PivotGroup*)vid.getItemExpr())->orderBy() ) 
        {
          grby->setExtraGrpOrderby(((PivotGroup*)vid.getItemExpr())->getOrderbyItemExpr());
          ValueIdList tmpList;
          grby->getExtraGrpOrderby()->convertToValueIdList(tmpList, bindWA, ITM_ITEM_LIST);
          grby->setExtraOrderExpr(tmpList);
        }
      }
    }
  // recreate the groupExpr expression after updating the value ids
  grby->setGroupExpr (groupExprCpy);

  if ((grby->selPredTree()) &&
      (grby->selIndexInHaving()))
    {
      setValueIdForRenamedColsInHaving(bindWA, grby->selPredTree(),
                                       compExpr());

      BindScope *currScope = bindWA->getCurrentScope();
      
      ItemExpr *havingPred = grby->removeSelPredTree();
      currScope->context()->inHavingClause() = TRUE;
      havingPred->convertToValueIdSet(grby->selectionPred(), 
                                      bindWA, ITM_AND);
      currScope->context()->inHavingClause() = FALSE;
      if (bindWA->errStatus()) 
        return this;
    }

  if (orderByTree_ && seqNode && grby)
  {
    ItemExprList origOrderByList(bindWA->wHeap());

    origOrderByList.insertTree(orderByTree_);
    
    ItemExprList newOrderByList((Lng32)origOrderByList.entries(), bindWA->wHeap());

    for (CollIndex i = 0; (i < (CollIndex) origOrderByList.entries());i++)
    {
      ItemExpr * currOrderByItemExpr = 
                      ((ItemExpr *) origOrderByList[i])->castToItemExpr();
      ItemExpr * newOrderByItemExpr = currOrderByItemExpr;
      
      if (currOrderByItemExpr->getOperatorType() == ITM_SEL_INDEX)
      {
         SelIndex * si = (SelIndex*)(currOrderByItemExpr);
         if (compExpr()[si->getSelIndex()-1].getItemExpr()->getOperatorType() != ITM_BASECOLUMN)
         {
           newOrderByItemExpr = compExpr()[si->getSelIndex()-1].getItemExpr();
         }
      }
      newOrderByList.insert(newOrderByItemExpr);
    }
    orderByTree_ = newOrderByList.convertToItemExpr();
  }

  return this;
}

void RelRoot::transformTDPartitionOrdinals(BindWA *bindWA)
{
  if(!getHasTDFunctions()) 
    return ;

  if (getCompExprTree() == NULL)
    return ;

  BindScope *currScope = bindWA->getCurrentScope();

  RelExpr * realChildNode = NULL;
 
  if (child(0)->getOperatorType() == REL_FIRST_N)
  {
    realChildNode = child(0)->child(0);
  }
  else
  {
    realChildNode = child(0);
  }
  
  if(realChildNode->getOperatorType() != REL_SEQUENCE )
  {
    return;
  }

  RelSequence * seqNode = (RelSequence *)realChildNode;

  if (!seqNode->getPartitionBy())
  {
    return;
  }
  
  ItemExpr * partitionBy  = seqNode->getPartitionBy()->copyTree(bindWA->wHeap());

  ItemExprList origSelectList(getCompExprTree(), bindWA->wHeap());

  ItemExprList origPartitionByList(bindWA->wHeap());
  if (partitionBy)
  {
      origPartitionByList.insertTree(partitionBy);
  }

  for (CollIndex i = 0; (i < (CollIndex) origPartitionByList.entries());i++)
  {
    ItemExpr * currPartitionByItemExpr = 
      ((ItemExpr *) origPartitionByList[i])->castToItemExpr();    

    NABoolean selIndexError = FALSE;
    Int64 selIndex = -1;
    if (currPartitionByItemExpr->getOperatorType() == ITM_CONSTANT)
    {
      ConstValue * cv = (ConstValue*)currPartitionByItemExpr;
      if ((cv->canGetExactNumericValue()) &&
          (cv->getType()->getScale() == 0))
      {
        selIndex = cv->getExactNumericValue();

        if (selIndex <= 0 || selIndex > origSelectList.entries())
        { //index in error -- produce error message
          //in TD mode group by <constant> -- constant is purely positional  
          //selIndexError = TRUE;
          *CmpCommon::diags() << DgSqlCode(-4366);
          bindWA->setErrStatus();
          return;
        }
        else
        {
          origPartitionByList.usedEntry( i )= 
            origSelectList.usedEntry((CollIndex)selIndex-1)->copyTree(bindWA->wHeap());
        }
      }
    }
  }
  seqNode->setPartitionBy(origPartitionByList.convertToItemExpr());
}
// resolveAggregates - 
// If aggregate functions have been found in the select list, then
// either attach the aggregate functions to the existing GroupBy below
// this RelRoot, or if there is no GroupBy create a GroupBy with an
// empty groupby list (scalar) and attach the aggregate functions to
// this GroupBy.
//
void RelRoot::resolveAggregates(BindWA *bindWA) 
{
  BindScope *currScope = bindWA->getCurrentScope();

  if (NOT currScope->getUnresolvedAggregates().isEmpty()) {
    if (getHasTDFunctions())
    { //Using rank function and aggregate functions in the same scope is not supported. 
      *CmpCommon::diags() << DgSqlCode(-4365);
      bindWA->setErrStatus();
      return;    
    }

    RelExpr *sequence = currScope->getSequenceNode();

    // The aggregates were used without a GROUP BY or HAVING
    // clause, i.e. an implicit aggregation is performed
    // (with a NULL result for an empty input table).
    NABoolean implicitGrouping = (child(0)->getOperatorType() != REL_GROUPBY);
    
    if(getHasOlapFunctions()) {
      implicitGrouping = (sequence->child(0)->getOperatorType() != REL_GROUPBY);
    }
    GroupByAgg *groupByAgg = NULL;
    if (implicitGrouping) {
      RelExpr * realChildNode = NULL;

      // if my child is a FIRST_N node, then add the GroupByAgg below it.
      // Otherwise, add the GroupByAgg below me.
      if (child(0)->getOperatorType() == REL_FIRST_N)
      {
        realChildNode = child(0)->child(0);
      }
      else
        realChildNode = child(0);

      if(getHasOlapFunctions()) {

        realChildNode = sequence->child(0);
      }

      groupByAgg =
        new (bindWA->wHeap()) GroupByAgg(realChildNode,REL_GROUPBY);
      realChildNode->setBlockStmt(isinBlockStmt());

      if(getHasOlapFunctions())
        sequence->setChild(0, groupByAgg);
      else if (child(0)->getOperatorType() == REL_FIRST_N)
        child(0)->setChild(0, groupByAgg);
      else
        setChild(0, groupByAgg);

      groupByAgg->setBlockStmt(isinBlockStmt());
    }
    else {
      if(getHasOlapFunctions()) {
        groupByAgg = (GroupByAgg *)sequence->child(0).getPtr();
      } else {
        groupByAgg = (GroupByAgg *)child(0).getPtr();
      }
    }

    NAString colName(bindWA->wHeap());
    Lng32 sqlCode = 0;
    ValueId valId = NULL_VALUE_ID;

    if (currScope->context()->unaggColRefInSelectList()) {
      sqlCode = -4021;
      valId = currScope->context()->unaggColRefInSelectList()->getValueId();
    }
    else if (implicitGrouping) {
      // Genesis 10-000414-9410:  "SELECT SUM(A),* FROM T; --no GROUP BY"
      // cannot be flagged with err 4012 in ColReference::bindNode
      // because table not marked "grouped" yet.
      //
      const ColumnDescList &cols = *currScope->getRETDesc()->getColumnList();
      CollIndex i, n = cols.entries();
      for (i=0; i<n; i++) {
        const ColumnDesc *col = cols[i];
        if (!col->isGrouped())
          if (col->getColRefNameObj().isStar() ||
              col->getValueId().getNAColumn(TRUE/*okIfNotColumn*/)) {
            sqlCode = -4012;
            valId = col->getValueId();
            colName = col->getColRefNameObj().getColRefAsAnsiString();
            break;
          }
      }
    }

    // Table has no GROUP BY (so no grouping columns exist at all)
    // but is grouped by dint of a column reference within an aggregate,
    // making any unaggregated column references illegal, by ANSI 7.9 SR 7.
    if (sqlCode) {

      if (colName.isNull()) {
        const NAColumn *nacol = valId.getNAColumn(TRUE/*okIfNotColumn*/);
        if (nacol)
          colName = nacol->getFullColRefNameAsAnsiString();
        else
          colName = "_unnamed_column_";
      }

      // 4012 Col ref must be grouping or aggregated -- no star ref allowed!
      // 4021 The select list contains a non-grouping non-aggregated column.
      *CmpCommon::diags() << DgSqlCode(sqlCode) << DgColumnName(colName);
      bindWA->setErrStatus();
      return;
    }

    // Move the unresolved aggregates into the groupby node and bind
    // (simply returns if "groupByAgg" isn't new).
    groupByAgg->aggregateExpr() += currScope->getUnresolvedAggregates();
    currScope->getUnresolvedAggregates().clear();
    groupByAgg->bindNode(bindWA);
  }
}

// resolveSequenceFunctions -
// Add the unresolvedSequenceFunctions to the Sequence node for this
// scope.  If there are sequence functions, but no sequence node, it
// is an error.  Also if there is a sequence node, but no sequence
// functions, it is an error.
//
// 
void RelRoot::resolveSequenceFunctions(BindWA *bindWA)
{
  BindScope *currScope = bindWA->getCurrentScope();

  // If we have a Sequence Node associated with the RelRoot node,
  //
  RelSequence *sequenceNode = (RelSequence *)currScope->getSequenceNode();
  currScope->getSequenceNode() = NULL;

  if (sequenceNode) {
    if (getHasTDFunctions() && sequenceNode->child(0)->getOperatorType() == REL_GROUPBY) 
    { //Using rank function and group by clause in the same scope is not supported.
      *CmpCommon::diags() << DgSqlCode(-4366);
      bindWA->setErrStatus();
      return;
    }

    CMPASSERT(sequenceNode->getOperatorType() == REL_SEQUENCE);

    // Do not allow sequence functions or OLAP Window functions
    // with Embedded Updates.
    //
    if (getGroupAttr()->isEmbeddedUpdateOrDelete()){
      *CmpCommon::diags() << DgSqlCode(-4202)
        << (getGroupAttr()->isEmbeddedUpdate() ?
            DgString0("UPDATE"):DgString0("DELETE"));
      bindWA->setErrStatus();
      return;
      }

    // If there are some sequence functions that have not been attached
    // to the Sequence node, do so now.  These were found when binding
    // the select list.
    //
    sequenceNode->
      addUnResolvedSeqFunctions(currScope->getUnresolvedSequenceFunctions(),
                                bindWA);

    currScope->getUnresolvedSequenceFunctions().clear();
    currScope->getAllSequenceFunctions().clear();
    if (bindWA->errStatus()) return;

    // Make sure the sequence function has some work to do.
    // The cast is needed since the compiler will attempt to pick the
    // protected (writable) version of 'sequenceFunctions()'.  (Is this
    // a compiler bug)
    //
    if ((((const RelSequence *)sequenceNode)->sequenceFunctions().isEmpty() )
        && 
        ( !getHasOlapFunctions() &&
          ((const RelSequence *)sequenceNode)->requiredOrder().entries() != 0 )) {
      // Can't have a sequence by clause without
      // sequence functions.
      //
      *CmpCommon::diags() << DgSqlCode(-4111);
      bindWA->setErrStatus();
      return;
    }
  } else if (! currScope->getUnresolvedSequenceFunctions().isEmpty()) {

    // Can't have sequence functions without a
    // sequence by clause.
    // First, loop through the list of functions.
    //
    ValueIdSet &unresolved = currScope->getUnresolvedSequenceFunctions();
    NAString unparsed(bindWA->wHeap());
    for (ValueId vid = unresolved.init(); unresolved.next(vid); unresolved.advance(vid)) {
     ItemExpr *ie = vid.getItemExpr();
     CMPASSERT(ie->isASequenceFunction());
     unparsed += ", ";
     ie->unparse(unparsed, DEFAULT_PHASE, USER_FORMAT_DELUXE);
    }
    unparsed.remove(0,2);     // remove initial ", "

    *CmpCommon::diags() << DgSqlCode(-4110) << DgString0(unparsed);
    bindWA->setErrStatus();
    return;
  }
}

// if a where pred is specified on an immediate child scan or rename node,
// and it contains an 'and'ed rownum() predicate of the form:
//    rownum < val, or rownum <= val, or rownum = val
// then get the val and make it the firstN value.
// Also, remove this predicate from selPredTree.
void RelRoot::processRownum(BindWA * bindWA)
{
  NABoolean specialMode = (CmpCommon::getDefault(MODE_SPECIAL_4) == DF_ON);
  if (NOT specialMode)
    return;

  if (! child(0))
    return;

  if ((child(0)->getOperatorType() != REL_SCAN) &&
      (child(0)->getOperatorType() != REL_RENAME_TABLE))
    return;

  if (! child(0)->selPredTree())
    return;
  
  ItemExpr * wherePred = child(0)->selPredTree();
  ItemExprList iel(wherePred, bindWA->wHeap(), ITM_AND, FALSE, FALSE);

  NABoolean found = FALSE;
  for (Lng32 i = 0; ((NOT found) && (i < iel.entries())); i++)
    {
      ItemExpr * ie = iel[i];
      if (ie->getArity() != 2)
        continue; 

      if (NOT ((ie->getOperatorType() == ITM_LESS) ||
               (ie->getOperatorType() == ITM_EQUAL) ||
               (ie->getOperatorType() == ITM_LESS_EQ)))
        continue;
      
      ItemExpr * child0 = ie->child(0)->castToItemExpr();
      ItemExpr * child1 = ie->child(1)->castToItemExpr();

      if (NOT ((child0->getOperatorType() == ITM_REFERENCE) &&
               (child1->getOperatorType() == ITM_CONSTANT)))
        continue;
               
      ColReference * col = (ColReference*)child0;
      ColRefName &colRefName = col->getColRefNameObj();
      CorrName &cn = col->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 (NOT ((catName.isNull()) &&
               (schName.isNull()) &&                
               (objName.isNull()) &&
               (colName == "ROWNUM")))
        continue;

      ConstValue * cv = (ConstValue*)child1;
      if (NOT cv->canGetExactNumericValue())
        continue;

      Int64 val = cv->getExactNumericValue();
      if (val < 0)
        continue;

      if ((ie->getOperatorType() == ITM_EQUAL) &&
          (val != 1))
        continue;

      if ((ie->getOperatorType() == ITM_LESS) &&
          (val > 0))
        val--;

      setFirstNRows(val);

      // remove this pred from the list
      iel.removeAt(i);

      found = TRUE;
    }

  if (found)
    {
      // convert the list back to selection pred.
      ItemExpr * ie = iel.convertToItemExpr();
      child(0)->removeSelPredTree();
      child(0)->addSelPredTree(ie);
    }

  return;
}

RelExpr *RelRoot::bindNode(BindWA *bindWA)
{
  if (nodeIsBound())
  {
    bindWA->getCurrentScope()->setRETDesc(getRETDesc());
    return this;
  }

  if (isTrueRoot()) 
    {
      // if this is simple scalar aggregate on a seabase table
      //  (of the form:  select count(*), sum(a) from t; )
      // then transform it so it could be evaluated using hbase co-processor.
      if ((CmpCommon::getDefault(HBASE_COPROCESSORS) == DF_ON) &&
	  (child(0) && child(0)->getOperatorType() == REL_SCAN))
	{
          Scan * scan = (Scan*)child(0)->castToRelExpr();

	  if ((getCompExprTree()) &&
              (NOT hasOrderBy()) &&
              (! getSelPredTree()) &&
              (! scan->getSelPredTree()) &&
	      (scan->selectionPred().isEmpty()) &&
              ((scan->getTableName().getSpecialType() == ExtendedQualName::NORMAL_TABLE) ||
	       (scan->getTableName().getSpecialType() == ExtendedQualName::INDEX_TABLE)) &&
              !scan->getTableName().isPartitionNameSpecified() &&
              !scan->getTableName().isPartitionRangeSpecified() &&
              (NOT bindWA->inViewDefinition()))
	    {
              ItemExprList selList(bindWA->wHeap());
              selList.insertTree(getCompExprTree());
	      // for now, only count(*) can be co-proc'd
              if ((selList.entries() == 1) &&
                  (selList[0]->getOperatorType() == ITM_COUNT) &&
		  (selList[0]->origOpType() == ITM_COUNT_STAR__ORIGINALLY))
                {
		  NATable *naTable = bindWA->getNATable(scan->getTableName());
		  if (bindWA->errStatus()) 
		    return this;

		  if (((naTable->getObjectType() == COM_BASE_TABLE_OBJECT) ||
		       (naTable->getObjectType() == COM_INDEX_OBJECT)) &&
		      ((naTable->isSeabaseTable()) ||
                       ((naTable->isHiveTable()) &&
                        (naTable->getClusteringIndex()->getHHDFSTableStats()->isOrcFile()))))
		    {
		      Aggregate * agg = 
			new(bindWA->wHeap()) Aggregate(ITM_COUNT,
						       new (bindWA->wHeap()) SystemLiteral(1),
						       FALSE /*i.e. not distinct*/,
						       ITM_COUNT_STAR__ORIGINALLY,
						       '!');
		      agg->bindNode(bindWA);
		      if (bindWA->errStatus())
			{	  
			  return this;
			}

		      ValueIdSet aggrSet;
		      aggrSet.insert(agg->getValueId());
		      ExeUtilExpr * eue = NULL;
                      
                      if (naTable->isSeabaseTable())
                        eue = 
                          new(CmpCommon::statementHeap())
                          ExeUtilHbaseCoProcAggr(scan->getTableName(),
                                                 aggrSet);
                      else
                        eue = 
                          new(CmpCommon::statementHeap())
                          ExeUtilOrcFastAggr(scan->getTableName(),
                                             aggrSet);
		      
		      eue->bindNode(bindWA);
		      if (bindWA->errStatus())
			{	  
			  return this;
			}
		      
		      setChild(0, eue);

                      removeCompExprTree();
                      addCompExprTree(agg);

		    } // if seabaseTable
		} // count aggr
	    }
	} // coproc on


      if (child(0) && 
	  ((child(0)->getOperatorType() == REL_INSERT) ||
	   (child(0)->getOperatorType() == REL_UNARY_INSERT) ||
	   (child(0)->getOperatorType() == REL_LEAF_INSERT)))
	{
	  Insert * ins = (Insert*)child(0)->castToRelExpr();
	  if (ins->isNoRollback())
          {
            if ((CmpCommon::getDefault(AQR_WNR) 
                 != DF_OFF) &&
                (CmpCommon::getDefault(AQR_WNR_INSERT_CLEANUP)
                 != DF_OFF))
              ins->enableAqrWnrEmpty() = TRUE;
          }
          if (CmpCommon::transMode()->anyNoRollback())
          {
            // tbd - may need to integrate these two.
            if ((CmpCommon::getDefault(AQR_WNR)
                != DF_OFF) &&
                (CmpCommon::getDefault(AQR_WNR_INSERT_CLEANUP)
                != DF_OFF))
              ins->enableAqrWnrEmpty() = TRUE;
          }
	}
      
      // if lob is being extracted as chunks of string, then only one
      // such expression could be specified in the select list.
      // If this is the case, then insert ExeUtilLobExtract operator.
      // This operator reads lob contents and returns them to caller as
      // multiple rows.
      // This lobextract function could only be used in the outermost select
      // list and must be converted at this point.
      // It is not evaluated on its own.
      if (getCompExprTree())
	{
	  ItemExprList selList(bindWA->wHeap());
	  selList.insertTree(getCompExprTree());
	  if ((selList.entries() == 1) &&
	      (selList[0]->getOperatorType() == ITM_LOBEXTRACT))
	    {
	      LOBextract * lef = (LOBextract*)selList[0];
	      
	      ExeUtilLobExtract * le =
		new (PARSERHEAP()) ExeUtilLobExtract
		(lef, ExeUtilLobExtract::TO_STRING_,
		 NULL, NULL, lef->getTgtSize(), 0,
		 NULL, NULL, NULL, child(0), PARSERHEAP());
	      le->setHandleInStringFormat(FALSE);
	      setChild(0, le);
	    }
	}

      processRownum(bindWA);
      
    } // isTrueRoot

  if (getHasTDFunctions()) 
  {
    transformTDPartitionOrdinals(bindWA);
    if (bindWA->errStatus()) return NULL;
  }

  RelRoot * returnedRoot = 
    transformGroupByWithOrdinalPhase1(bindWA);
  if (! returnedRoot)
    return NULL;

  returnedRoot = 
    transformOrderByWithExpr(bindWA);
  if (! returnedRoot)
    return NULL;

  if (bindWA->getCurrentScope()->context()->inTableCheckConstraint()) {
    // See ANSI 11.9 Leveling Rule 1a (Intermediate Sql).
    // 4089 A check constraint cannot contain a subquery.
    *CmpCommon::diags() << DgSqlCode(-4089)
      << DgConstraintName(
            bindWA->getCurrentScope()->context()->inCheckConstraint()->
            getConstraintName().getQualifiedNameAsAnsiString());
    bindWA->setErrStatus();
  }

  if (isTrueRoot()) 
    bindWA->setTopRoot(this);

  bindWA->setBindTrueRoot(isTrueRoot());

  if (!bindWA->getAssignmentStArea()) {
    bindWA->getAssignmentStArea() =
      new (bindWA->wHeap()) AssignmentStArea(bindWA);
    bindWA->getAssignmentStArea()->getAssignmentStHostVars() =
      new (bindWA->wHeap()) AssignmentStHostVars(bindWA);
  }


  // If there are one or more output rowset variables, then we introduce
  // a RowsetInto node below this Root node. The RowsetInto node will
  // create a Pack node later on when it is binded, so that we can
  // insert values into the rowset output variables.
  // We don't do this transformation if we are inside a compound statement.
  //
  if (isTrueRoot() && assignmentStTree()) {
    ItemExpr *outputVar = getOutputVarTree();
    if (outputVar) {

      CMPASSERT(outputVar->getChild(0)->getOperatorType() == ITM_HOSTVAR);
      HostVar *hostVar = (HostVar *) outputVar->getChild(0);

      if (hostVar->getType()->getTypeQualifier() == NA_ROWSET_TYPE) {

        ItemExpr *outputVar = removeOutputVarTree();
        assignmentStTree() = NULL;

        // Get the output size expression. It may be a constant or a variable.
        ItemExpr * sizeExpr = getHostArraysArea()->outputSize();

        // set the SelectIntoRowsets flag
        getHostArraysArea()->setHasSelectIntoRowsets(TRUE);

        // Create INTO node. Its child is the current root
        RelExpr *intoNode =
          new (bindWA->wHeap()) RowsetInto(this, outputVar, sizeExpr);

        //If case of first N with ORDER BY generator introduces the FIRST N
        //operator.  For rowsets FIRST N node need to be introduced below the
        //PACK node and not below the top root. So set first N rows for INTO
        //node and not the top root.
        if (hasOrderBy()) {
          intoNode->setFirstNRows(getFirstNRows());
          setFirstNRows(-1);
        }

        // Create a new root node that will go above the RowsetInto node
        setRootFlag(FALSE);
        RelRoot *newRoot  = new (bindWA->wHeap()) RelRoot(intoNode);
        newRoot->setRootFlag(TRUE);
        // copy the display flag from this true Root to the new root.
        // newRoot->setDisplayTree(getDisplayTree());
        newRoot->setDisplayTree(TRUE);
        newRoot->addInputVarTree(removeInputVarTree());
        newRoot->outputVarCnt() = outputVarCnt();

        NABoolean defaultSortedRows = newRoot->needFirstSortedRows();
        //Int64 defaultFirstNRows = newRoot->getFirstNRows();
        newRoot->needFirstSortedRows() = needFirstSortedRows();
        //newRoot->setFirstNRows(getFirstNRows());
        needFirstSortedRows() = defaultSortedRows;
        //        setFirstNRows(defaultFirstNRows);

        newRoot->rollbackOnError() = rollbackOnError();

        // migrate hostArraysArea to newroot, and tell bindWA about it
        newRoot->setHostArraysArea(getHostArraysArea());
        bindWA->setHostArraysArea(getHostArraysArea());
        setSubRoot(FALSE);      // old root is no longer the root
        newRoot->setSubRoot(TRUE);   // newRoot becomes the root

        return newRoot->bindNode(bindWA);
      }
    }
  }

  if (assignmentStTree() && child(0)->getOperatorType() != REL_ROWSET_INTO) {
    AssignmentStHostVars *ptr =
      new (bindWA->wHeap()) AssignmentStHostVars(bindWA);

    if (ptr->containsRowsets(assignmentStTree())) {
      ItemExpr *outputSizeExpr = NULL;

      // The user may have used the ROWSET FOR OUTPUT SIZE construct
      // set the SelectIntoRowsets flag.
      if (getHostArraysArea()) {
        outputSizeExpr  = getHostArraysArea()->outputSize();
        getHostArraysArea()->setHasSelectIntoRowsets(TRUE);
      }

      // Create RowsetInto node. Its child is the current root
      RelExpr *intoNode = new (bindWA->wHeap())
                           RowsetInto(this, assignmentStTree(), outputSizeExpr);

      //If case of first N with ORDER BY generator introduces the FIRST N
      //operator.  For rowsets FIRST N node need to be introduced below the
      //PACK node and not below the top root. So set first N rows for INTO
      //node and not the top root.
      if (hasOrderBy()) {
        intoNode->setFirstNRows(getFirstNRows());
        setFirstNRows(-1);
      }

      RelRoot *newRoot  = new (bindWA->wHeap()) RelRoot(*this);

      newRoot->child(0) = intoNode;
      newRoot->removeCompExprTree();
      setRootFlag(FALSE);
      removeInputVarTree();
      assignmentStTree() = NULL;

      return newRoot->bindNode(bindWA);
    }
  }

  // Create a new scope.
  //
  if (!isDontOpenNewScope())  // -- Triggers.
  {
    bindWA->initNewScope();

    // MV --
    if(TRUE == hasMvBindContext())
    {
      // Copy the MvBindContext object from the RelRoot node to the
      // current BindContext.
      bindWA->markScopeWithMvBindContext(getMvBindContext());
    }

    if (getInliningInfo().isTriggerRoot())
    {
      CMPASSERT(getInliningInfo().getTriggerObject() != NULL);
      bindWA->getCurrentScope()->context()->triggerObj() =
        getInliningInfo().getTriggerObject()->getCreateTriggerNode();
    }

    if (getInliningInfo().isActionOfRI())
      bindWA->getCurrentScope()->context()->inRIConstraint() = TRUE;
  }

  // Save whether the user specified SQL/MP-style access options in the query
  // (this is always true for the LOCK stmt, which we must maximize).
  //
  if (child(0)->getOperatorType() == REL_LOCK) {
    accessOptions().updateAccessOptions(
      TransMode::ILtoAT(TransMode::READ_COMMITTED_),
      ((RelLock *)child(0).getPtr())->getLockMode());
    accessOptions().updateAccessOptions(
      TransMode::ILtoAT(CmpCommon::transMode()->getIsolationLevel()));
  }

  // QSTUFF:  the updateOrDelete flag is set to ensure that scans done as 
  // part of a generic update cause an exclusive lock to be set to ensure
  // a consistent completion of the following update or delete.
  if (containsUpdateOrDelete(this))
  {
    accessOptions().setUpdateOrDelete(TRUE);
  }
  else if (isTrueRoot())
  {
    // if the query does not contain any Generic Update nodes, mark it
    // as read only query. In that case, we have freedom not to include
    // some indexes in the indexes list.
    bindWA->setReadOnlyQuery();
  }


  // This block of code used to be in RelRoot::propagateAccessOptions() which
  // used to be called from here. We've since replaced this old 'push' call
  // with the 'pull' of BindWA->findUserSpecifiedAccessOption() calls from
  // RelRoot, Scan, and GenericUpdate.
  // QSTUFF
  // We decided to stick with READ COMMITTED as the default access
  //  (even for streams).  However, if we change our mind again, this is
  //  the place to do it.
  // if (getGroupAttr()->isStream() &&
  //   (accessOptions().accessType() == ACCESS_TYPE_NOT_SPECIFIED_))
  //	  accessOptions().accessType() = SKIP_CONFLICT_;

  // Set the flag to indicate to DP2 that this executes an
  //  embedded update or delete.
  if (getGroupAttr()->isEmbeddedUpdateOrDelete())
    accessOptions().setUpdateOrDelete(TRUE);
  // QSTUFF

  if (accessOptions().userSpecified())
    bindWA->getCurrentScope()->context()->setStmtLevelAccessOptions(accessOptions());

  if (isSubRoot() && getHostArraysArea())
    getHostArraysArea()->setRoot(this);

  if (isTrueRoot()) {

    // If this were false, then SynthType's ValueDesc::create()
    // would use a DIFFERENT SchemaDB than BindItemExpr's createValueDesc()
    // -- wrong!  Assert this only once per query.
    CMPASSERT(ActiveSchemaDB() == bindWA->getSchemaDB());

    // set the upDateCurrentOf_ attribute for the root if possible
    if (child(0)->getOperatorType() == REL_UNARY_UPDATE ||
      child(0)->getOperatorType() == REL_UNARY_DELETE) {
      GenericUpdate *gu = (GenericUpdate *)child(0)->castToRelExpr();
      if (gu->updateCurrentOf()) {
        updateCurrentOf()  = gu->updateCurrentOf();
        currOfCursorName() = gu->currOfCursorName();
      }
    }

    // If we are processing a rowset,
    // then the child operator is a REL_TSJ.
    // If this is the case, and the operation is
    // an update or delete, we need to search
    // further to deterine its correct child
    // operator type. 
    
    // Otherwise, the child operator type is correct.
 
    if (bindWA->getHostArraysArea() && 
        bindWA->getHostArraysArea()->hasHostArraysInWhereClause() && 
        bindWA->getHostArraysArea()->hasInputRowsetsInSelectPredicate() == HostArraysWA::NO_  &&
        NOT bindWA->getHostArraysArea()->hasHostArraysInTuple())
        // ensure that we don't flag rowset selects or insert selects with rowsets in the predicate
    {
      if (bindWA->getHostArraysArea()->hasHostArraysInSetClause())  // includes rowset merge statements too
        childOperType() = REL_UNARY_UPDATE;
      else
        childOperType() = REL_UNARY_DELETE;
    }
    else
      childOperType() = child(0)->getOperator();

    // see if we can potentially optimize the buffer sizes for
    // oltp queries. Done for update/delete/insert-values/select-unique.

    // if scan, olt opt is possible.
    if (childOperType() == REL_SCAN)
      oltOptInfo().setOltOpt(TRUE);

    /*
    // For Denali release 1, compound statements are restricted
    // to yield at most one row; so olt opt is possible for CS.
    // If a compound statement is not pushed down to DP2, then
    // OLT optimization will be turned off in generator.
    //
    //       Turn it off for Compound statement as insertion with tuple list
    //       is possible in a CS.
    */
    else if (childOperType() == REL_COMPOUND_STMT)
      oltOptInfo().setOltOpt(TRUE);

    // if INSERT...VALUES, olt opt is possible.
    else if ((childOperType() == REL_UNARY_INSERT) &&
             (NOT child(0)->child(0) ||
             child(0)->child(0)->getOperatorType() == REL_TUPLE))
      oltOptInfo().setOltOpt(TRUE);

  } // isTrueRoot

  else if (checkFirstNRowsNotAllowed(bindWA)) {
    *CmpCommon::diags() << DgSqlCode(-4102);
    bindWA->setErrStatus();
    return NULL;
  }

  BindScope *currScope = bindWA->getCurrentScope();

  // -- MVs
  // Check for the Refresh node before binding, because after binding it
  // will be gone.
  if (child(0)->getOperatorType() == REL_REFRESH)
    setRootOfInternalRefresh();

  // set the currect host area in bindWA for non-root stmt.
  // fix 10-031106-4430 (RG: mxcmp failed to compile INSERT
  //                         statement with rowsets within IF statement)
  HostArraysWA *tempWA = NULL;
  if ( NOT isTrueRoot() && getHostArraysArea() )
  {
     tempWA = bindWA->getHostArraysArea();
     bindWA->setHostArraysArea(getHostArraysArea());
  }

  bindWA->setBindTrueRoot(FALSE);

  // Bind the children here to determine if we need to rollback on error
  // for embedded update/delete's.
  //
  bindChildren(bindWA);

  if ( tempWA )
  {
    // Restore previous environment
    bindWA->setHostArraysArea(tempWA);
  }

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

  // For SPJ, store the spOutParams_ from the bindWA in RelRoot,
  // We need it at codegen
  if ( bindWA->getSpOutParams ().entries ())
    spOutParams_ = &( bindWA->getSpOutParams ());

  if (isTrueRoot()) {

    if (child(0)->getGroupAttr()->isEmbeddedUpdateOrDelete()) {
      // Olt optimization is now supported for embedded updates/deletes (pub/sub
      // thingy) for now.
      oltOptInfo().setOltOpt(TRUE);
      if (getFirstNRows() != -1) {
        // [FIRST/ANY n] syntax cannot be used with an embedded update or embedded delete.
      *CmpCommon::diags() << DgSqlCode(-4216);
      bindWA->setErrStatus();
      return NULL;
      }
    }

    // If updateCurrentOf_ not set yet
    // Check the tree for a GenericUpdate RelExpr (anywhere in the tree)
    // so we can set the root node accordingly.
    GenericUpdate *gu = getGenericUpdate(this);
    if (!updateCurrentOf() && gu && gu->updateCurrentOf()) {
      updateCurrentOf()  = gu->updateCurrentOf();
      currOfCursorName() = gu->currOfCursorName();
    }

    // if standalone update/delete(no update where current of),
    // olt opt is possible.
    if (((childOperType() == REL_UNARY_UPDATE) ||
        (childOperType() == REL_UNARY_DELETE)) &&
        (NOT updateCurrentOf()))
      oltOptInfo().setOltOpt(TRUE);

    // If transaction statement (begin/commit/rollback/set xn,
    // olt opt is possible.
    if (childOperType() == REL_TRANSACTION)
      oltOptInfo().setOltOpt(TRUE);

    // Set indication whether transaction need to be aborted on error
    // during an IUD query.
    // Rollback will be done for a query that contains
    // rowsets, or an insert which is
    // not an 'insert...values' with a single value.
    //
    // There are more cases when a transaction will be rolled back on
    // an IUD error. These are set in GenericUpdate::preCodeGen,
    // and DP2(IUD)::preCodeGen.
    // These include embedded update or delete, stream access, non-unique
    // update or delete... See ::preCodeGen methods for details.
    rollbackOnError() = FALSE;
    if (childOperType().match(REL_ANY_GEN_UPDATE))
      {
        if (bindWA->getHostArraysArea() &&
            bindWA->getHostArraysArea()->done()) // rowsets
          rollbackOnError() = TRUE;
        else if ((childOperType() == REL_UNARY_INSERT) &&
                 (child(0)->child(0) &&
                  child(0)->child(0)->getOperatorType() != REL_TUPLE))
          rollbackOnError() = TRUE;
      }
      if (bindWA->getHostArraysArea() &&
          bindWA->getHostArraysArea()->getTolerateNonFatalError())
      {
        setTolerateNonFatalError(RelExpr::NOT_ATOMIC_);
      }
  }

  CMPASSERT(currScope == bindWA->getCurrentScope());   // sanity check

  // do not do olt qry optimization, if rowsets are present.
  if (bindWA->getHostArraysArea() && bindWA->getHostArraysArea()->done())
    {
      oltOptInfo().setOltOpt(FALSE);

      if (bindWA->getHostArraysArea()->getTolerateNonFatalError()) {
        // we also cannot do  dp2 level olt optimization if this is a non-atomic rowset insert
        oltOptInfo().setOltEidOpt(FALSE);
      }
      else {
        // but can do dp2 level olt optimization if this is "regular" rowset insert
        oltOptInfo().setOltEidOpt(TRUE); 
      }
    }

  // If unresolved aggregate functions have been found in the children of the
  // root node, that would mean that we are referencing aggregates before
  // the groupby operation is performed

  if (checkUnresolvedAggregates(bindWA)) return this;

  // A RelRoot does not have a select list for SQL update, delete, insert
  // statements as well as when the query contains an SQL union. If a
  // select list is absent, assign the select list of its child to it.
  // This will propagate the selection lists of the children of the
  // union up to the root.
  //
  // Detach the item expression tree for the select list and bind it.
  //
  ItemExpr *compExprTree = removeCompExprTree();
  if (NOT compExprTree) {
        // -- for RI and Triggers
    if (isEmptySelectList())
      setRETDesc(new (bindWA->wHeap()) RETDesc(bindWA));
    else {
      setRETDesc(child(0)->getRETDesc());
      getRETDesc()->getValueIdList(compExpr());
    }
  }
  else {
    CMPASSERT(!currScope->context()->inSelectList());
    currScope->context()->inSelectList() = TRUE;

    // QSTUFF
    // in case we are binding an embedded generic update within a view
    // we have to rename column references using OLD or NEW as
    // table names since we adopted the RETDesc/TableDesc of the
    // scan node or the view scan node, i.e. the RenameTable node
    // at the root of an expanded view.

    if (bindWA->renameToScanTable()){

      ColReference * cr = NULL;
      ItemExpr * itm = compExprTree;
      NABoolean done = FALSE;

      const CorrName corr =
        (getViewScanNode()->getOperatorType() == REL_RENAME_TABLE) ?
        ((RenameTable *)getViewScanNode())->getTableName() :
      ((Scan *)getViewScanNode())->getTableDesc()->getCorrNameObj();

      while (NOT done){

        if (itm->getOperatorType() == ITM_ITEM_LIST){
          cr = (ColReference *) itm->getChild(0);
          itm = itm->getChild(1)->castToItemExpr();
          }
        else {
          cr = (ColReference *) itm;
          done = TRUE;
          }

        cr->getCorrNameObj().getQualifiedNameObj().
          setObjectName(corr.getQualifiedNameObj().getObjectName());

        }
      }
    // QSTUFF

    RelRoot *viewQueryRoot = NULL;
    StmtDDLCreateView *pCreateView = NULL;
    if (bindWA->inViewDefinition()) {
      pCreateView = bindWA->getCreateViewParseNode();
      if (pCreateView->getQueryExpression() == this) {
        viewQueryRoot = this;
        CMPASSERT(isTrueRoot());
        pCreateView->setCurViewColNum((CollIndex)0);
      }
    }

    // charset inference
    compExprTree->setResolveIncompleteTypeStatus(TRUE);

    HostArraysWA * arrayWA = bindWA->getHostArraysArea() ;
    if (arrayWA && arrayWA->hasHostArraysInTuple()) {
      CollIndex counterRowVals = 0;
      CMPASSERT(!bindWA->getCurrentScope()->context()->counterForRowValues());
      bindWA->getCurrentScope()->context()->counterForRowValues() = &counterRowVals;
      
      // If this query (scope) contains OLAP Window functions, then add
      // a Sequence Operator just below the Root node.  Also, if aggregates
      // exist, resolve them now.
      //
      setRETDesc(bindRowValues(bindWA, compExprTree, compExpr(), this, isTrueRoot()));
      bindWA->getCurrentScope()->context()->counterForRowValues() = NULL;
    }
    else {
      setRETDesc(bindRowValues(bindWA, compExprTree, compExpr(), viewQueryRoot, isTrueRoot()));
    }
    if (bindWA->errStatus()) return NULL;

    if (viewQueryRoot) pCreateView->resetCurViewColNum();

    currScope->context()->inSelectList() = FALSE;
  }

  // MVs --
  if (bindWA->isPropagateOpAndSyskeyColumns()        &&
      child(0)->getOperatorType()!=REL_GROUPBY       &&
      child(0)->getOperatorType()!=REL_AGGREGATE     &&
      currScope->getUnresolvedAggregates().isEmpty() &&
      !isEmptySelectList()                           &&
      !isTrueRoot())
    getRETDesc()->propagateOpAndSyskeyColumns(bindWA, TRUE);

  CMPASSERT(currScope == bindWA->getCurrentScope());   // sanity check
  currScope->setRETDesc(getRETDesc());
  bindWA->setRenameToScanTable(FALSE);         // QSTUFF

  // Genesis 10-980106-2038 + 10-990202-1098.
  //
  if (isTrueRoot()) {
    castComputedColumnsToAnsiTypes(bindWA, getRETDesc(), compExpr());
    if (bindWA->errStatus()) return NULL;
  }

  // Genesis 10-970822-2581.  See finalize() in SqlParser.y.
  //
  // If we are in a compound statement (an IF's UNION), do not issue an error.
  //
  // Added condition for CALL StoredProcedures
  // If we invoke a CALL statement, the #out params do not match the
  // # columns, we make that check in the CallSP::bindNode, so ignore it
  // for now.
  if (isTrueRoot() &&
      (child(0)->getOperatorType() != REL_CALLSP &&
      (child(0)->getOperatorType() != REL_COMPOUND_STMT &&
      (child(0)->getOperatorType() != REL_TUPLE &&
       (Int32)getRETDesc()->getDegree() != 0))) &&
     (child(0)->getOperatorType() != REL_UNION ||
     (!((Union *) (RelExpr *) child(0))->getUnionForIF())) &&
      outputVarCntValid() &&
      outputVarCnt() != (Int32)getRETDesc()->getDegree() &&
     (outputVarCnt() ||
      CmpCommon::context()->GetMode() != STMT_DYNAMIC)) {
      // 4093 The number of output parameters ($0) must equal the number of cols
      // 4094 The number of output host vars  ($0) must equal the number of cols
      Lng32 sqlcode = (CmpCommon::context()->GetMode() == STMT_DYNAMIC) ?
      -4093 : -4094;
      *CmpCommon::diags() << DgSqlCode(sqlcode)
#pragma nowarn(1506)   // warning elimination
      << DgInt0(outputVarCnt()) << DgInt1(getRETDesc()->getDegree());
#pragma warn(1506)  // warning elimination
      bindWA->setErrStatus();
      return NULL;
    }

  ItemExpr *inputVarTree = removeInputVarTree();
  if (inputVarTree) {
    inputVarTree->convertToValueIdList(inputVars(), bindWA, ITM_ITEM_LIST);
    if (bindWA->errStatus()) return NULL;

    // If DYNAMIC SQL compilation, then
    // remove from the input var list (list of HostVars and DynamicParams)
    // any env vars that were found to have a equivalence value which is
    // valid (parseable) for the context it appears in
    // (i.e., we've already bound the env var name's dynamic value,
    // so we no longer need the env var name at all).
    // Right now, this means that in sqlci you can say
    //	 set envvar xyz cat.sch.tbl;
    //	 select * from $xyz;
    //
    if (CmpCommon::context()->GetMode() == STMT_DYNAMIC) {
      for (CollIndex i = inputVars().entries(); i--; ) {
        HostVar *hostVar = (HostVar *)inputVars()[i].getItemExpr();
        if (hostVar->getOperatorType() == ITM_HOSTVAR &&
            hostVar->isPrototypeValid() &&
            (hostVar->isEnvVar() ||
             hostVar->isDefine()))
          inputVars().removeAt(i);
      }
    } // STMT_DYNAMIC
  } // inputVarTree

  // add to the inputVars, any user functions that are to be treated
  // like input values, that is, evaluated once and used therafter.
  // Do not insert duplicate value ids.
  for (CollIndex i = 0; i < bindWA->inputFunction().entries(); i++ ) {
    if (NOT inputVars().contains(bindWA->inputFunction()[i]))
      inputVars().insert(bindWA->inputFunction()[i]);
  }

  // If aggregate functions have been found in the select list, then
  // create a groupby node with an empty groupby list, if the child is not
  // already a groupby node.
  //
  resolveAggregates(bindWA);
  if (bindWA->errStatus()) return NULL;

  // Add the unresolvedSequenceFunctions to the Sequence node for this
  // scope.  If there are sequence functions, but no sequence node, it
  // is an error.  Also if there is a sequence node, but no sequence
  // functions, it is an error.
  // If OLAP Window functions exist for this scope, they will have been
  // translated into sequence functions by this point and so will be added
  // to the Sequence node here.
  //
  resolveSequenceFunctions(bindWA);
  if (bindWA->errStatus()) return NULL;

  BindScope *prevScope   = bindWA->getPreviousScope(currScope);
  NABoolean inRowSubquery   = FALSE;
  if (prevScope)
    inRowSubquery = prevScope->context()->inRowSubquery();

  if (inRowSubquery && (CmpCommon::getDefault(COMP_BOOL_137) == DF_OFF))
      addOneRowAggregates(bindWA);

  returnedRoot = 
    transformGroupByWithOrdinalPhase2(bindWA);
  if (! returnedRoot)
    return NULL;

  ItemExpr *orderByTree = removeOrderByTree();
  if (orderByTree) {
    //
    // Tandem extension to ANSI (done only if source table is not grouped!):
    // Allow the ORDER BY clause to reference columns in the source table even
    // if the columns are not referenced in the select list.  Treat the extra
    // columns as *system* columns so that they can be referenced by name
    // (ORDER BY name) but not by position in select list (ORDER BY n).
    // Thus, select-list columns have precedence, as they should since ANSI
    // allows only them in ORDER BY to begin with!
    //
    // Add all source columns to system column list of temporary orderBy;
    // remove select-list columns from this system column list;
    // insert select-list columns into the *user* column list
    // (these must be in separate loops to set up the orderBy XCNM correctly!).
    // Then bind the temporary (convert to ValueId list), reset the RETDesc.
    //
    bindWA->getCurrentScope()->context()->inOrderBy() = TRUE;
    CollIndex i;
    RETDesc orderBy;
    const RETDesc &select = *getRETDesc();
    const RETDesc &source = *child(0)->getRETDesc();

    // if the source is grouped, then the ORDER BY columns must be in
    // the select list.  So, don't add any other columns that aren't
    // in the select list...
    if (source.isGrouped()) {
      orderBy.setGroupedFlag();
      //10-031125-1549 -begin
      //Since we are processing a groupby we should
      //certainly have some node below it. Futher if
      //that node is a REL_ROOT we will certainly have
      //a child. So this rather unusual call sequence
      //is safe. We are actually looking for a Pattern
      //like REL_GROUPBY(REL_ROOT(*)) introduced to handle
      //Distint qualifier.
      //for example if we have a query like
      //select distinct j as jcol from t1 order by j;
      //the tree will look like
      //REL_ROOT(REL_GROUPBY(REL_ROOT(REL_SCAN(t1))))
      //In this is a NON-ANSI query. To support queries like this
      //we need to expose "J" as a system column. To do that we need
      //to get hold of the RetDesc of the node below the REL_ROOT
      //(not the actual REL_ROOT).
      RETDesc *src = NULL;
      if(child(0)->child(0)&&
         child(0)->child(0)->getOperatorType() == REL_ROOT)
      {
         src = child(0)->child(0)->child(0)->getRETDesc();
      }
      else
      {
        src = child(0)->getRETDesc();
      }

      const ColumnDescList &sysColList = *src->getSystemColumnList();
      const ColumnDescList &usrColList = *src->getColumnList();
      ValueId vid;

      for(i = 0; i < select.getDegree(); i++) {
        vid = select.getValueId(i);
        for(CollIndex j = 0; j < sysColList.entries(); j++){
          if( vid == sysColList[j]->getValueId()){
               orderBy.addColumn(bindWA, sysColList[j]->getColRefNameObj()
                                 , sysColList[j]->getValueId()
                                 , SYSTEM_COLUMN);
          }
        }
        for(CollIndex k = 0; k < usrColList.entries(); k++){
          if(vid ==  usrColList[k]->getValueId()){
               orderBy.addColumn(bindWA, usrColList[k]->getColRefNameObj()
                                 , usrColList[k]->getValueId()
                                 , SYSTEM_COLUMN);
              }
        }
      }
      //10-031125-1549 -end

      NABoolean specialMode = TRUE;
      

      // In specialMode, we want to support order by on columns
      // which are not explicitely specified in the select list.
      // Ex: select a+1 from t group by a order by a;
      // Find all the column references in the orderByTree which are
      // also in the group by list but are not explicitely specified
      // in the select list.
      // This code path is for cases when both GROUP BY and ORDER BY are
      // specified.
      // If order by is specified without the group by, then that case
      // is already covered in the 'else' portion.
      if ((specialMode) &&
          (child(0)->getOperatorType() == REL_GROUPBY) &&
          (allOrderByRefsInGby_)) // already validated that all order by cols
                                  // are also in group by clause
        {
          ItemExprList orderByList(orderByTree, bindWA->wHeap());
          GroupByAgg * grby=(GroupByAgg *)(child(0)->castToRelExpr());
          for (CollIndex ii = 0; ii < orderByList.entries(); ii++)
            {
              ItemExpr * colRef = orderByList[ii];
              if (colRef->getOperatorType() == ITM_INVERSE)
                colRef = colRef->child(0)->castToItemExpr();
              if (colRef && colRef->getOperatorType() == ITM_REFERENCE)
                {
                  ColReference * obyColRef = (ColReference*)colRef;

                  for (CollIndex k = 0; k < usrColList.entries(); k++)
                    {
                      if (obyColRef->getColRefNameObj().getColName() ==
                          usrColList[k]->getColRefNameObj().getColName())
                        {
                          orderBy.delColumn(bindWA,
                                            usrColList[k]->getColRefNameObj(),
                                            SYSTEM_COLUMN);

                          orderBy.addColumn(bindWA, 
                                            usrColList[k]->getColRefNameObj(),
                                            usrColList[k]->getValueId(),
                                            SYSTEM_COLUMN);
                          break;
                        } // if
                    } // for
                  
                } // if
            } // for
        }
      
      for (i = 0; i < select.getDegree(); i++)
        orderBy.delColumn(bindWA, select.getColRefNameObj(i), SYSTEM_COLUMN);
    }
    else {
      // add the potential ORDER BY columns... omitting the ones that will
      // in the select list anyway.
      orderBy.addColumns(bindWA, *source.getColumnList(),       SYSTEM_COLUMN);
      orderBy.addColumns(bindWA, *source.getSystemColumnList(), SYSTEM_COLUMN);

      for (i = 0; i < select.getDegree(); i++)
        orderBy.delColumn(bindWA, select.getColRefNameObj(i),   SYSTEM_COLUMN);
    }

    for (i = 0; i < select.getDegree(); i++)
      orderBy.addColumn(bindWA, select.getColRefNameObj(i),
                                select.getValueId(i),           USER_COLUMN);

    bindWA->getCurrentScope()->setRETDesc(&orderBy);

    // fix for defect 10-010522-2978
    // If we need to move this OrderBy to the RelRoot above this one...
    //   move it to the rowsetReqdOrder_ of that RelRoot, otherwise keep
    //   it at this level... in the current RelRoot's reqdOrder_

    ValueIdList & pRRO = getParentForRowsetReqdOrder() ?
                         getParentForRowsetReqdOrder()->rowsetReqdOrder_ :
                         reqdOrder();

      // Replace any selIndexies in the orderByTree with what it refers to
      // before we expand it.
      // This is done so that we can deal with subqueries with degree > 1
      // and MVFs.

    ItemExpr *sPtr = orderByTree, *ePtr = orderByTree;
    
    Int32 childIdx = 0;
    NABoolean onlyOneEntry(TRUE);

    CollIndex selListCount = compExpr().entries();

    while (sPtr != NULL) 
    {
      
      if (sPtr->getOperatorType() == ITM_ITEM_LIST)
      {
        ePtr = sPtr;
        sPtr = ePtr->child(0);
        childIdx = 0;
        onlyOneEntry = FALSE;
      }
      if (sPtr->getOperatorType() == ITM_SEL_INDEX)
      {
        SelIndex * si = (SelIndex*)(sPtr);

        CollIndex selIndex = si->getSelIndex();
        if(selIndex == 0 || selIndex > selListCount)
        {
          *CmpCommon::diags() << DgSqlCode(-4007) 
                              << DgInt0((Lng32)si->getSelIndex()) 
                              << DgInt1(selListCount);
           bindWA->setErrStatus();
           return NULL;
        }

        ValueId orderById = compExpr()[si->getSelIndex()-1];
        if (ePtr->getOperatorType() == ITM_ITEM_LIST)
          ePtr->child(childIdx) = orderById.getItemExpr();
        else
          ePtr = orderById.getItemExpr();

        orderById.getItemExpr()->setInOrderByOrdinal(TRUE);
      }
      if ((ePtr->getArity() == 2) && ePtr->child(1) != NULL && 
          ePtr->child(1)->getOperatorType() != ITM_ITEM_LIST &&
          childIdx != 1)
        childIdx = 1;
      else
        childIdx = 0;
      sPtr = (childIdx == 1) ? ePtr->child(1) : NULL;
    }

    if (onlyOneEntry)
      orderByTree =  ePtr;

      // If we had any ordinal expressions expand them in case there
      // are any UDFs or subquery of degree > 1.
      // Also expand any directly referenced UDFs and subqueries of degree > 1.
    ItemExprList origOrderByList(orderByTree, bindWA->wHeap());

    origOrderByList.convertToItemExpr()->
      convertToValueIdList(pRRO, bindWA, ITM_ITEM_LIST);
    
    // end fix for defect 10-010522-2978

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

    bindWA->getCurrentScope()->setRETDesc(getRETDesc());
    bindWA->getCurrentScope()->context()->inOrderBy() = FALSE;
  }

  // validate that select list doesn't contain any expressions that cannot be
  // grouped or ordered.
  for (Lng32 selIndex = 0; selIndex < compExpr().entries(); selIndex++)
    {
      ItemExpr * ie = compExpr()[selIndex].getItemExpr();
      if ((ie->inGroupByOrdinal()) || (ie->inOrderByOrdinal()))
        {
          if (NOT ie->canBeUsedInGBorOB(TRUE))
            {
              return NULL;
            }
        }
    }

  if (hasPartitionBy())
  {
    ItemExpr *partByTree = removePartitionByTree();
    partByTree->convertToValueIdSet(partArrangement_, bindWA, ITM_ITEM_LIST);
    if (bindWA->errStatus()) return NULL;
  }

  // fix for defect 10-010522-2978
  // If we're the upper level RelRoot, we must check to see if we have
  // any entries that need to be added to reqdOrder() and add them if
  // there are any...

  if ( rowsetReqdOrder_.entries() ) {
     // We never expect for reqdOrder to contain any entries.  But
     // if it ever does, we want to be able to take a look at this
     // code again to decide whether we should be appending to the
     // reqdOrder list.  Currently the code is written to append to
     // the end of the reqdOrder list, which is likely to be the correct
     // behavior even if there are entries in reqdOrder; we just think
     // that someone should have the chance to rethink this in the event
     // there are entries in reqdOrder and so we're making it fail here
     // to allow/force someone to make the decision.
     CMPASSERT(reqdOrder().entries() == 0);

     // note: NAList<ValueIdList>::insert(const NAList<ValueIdList> &)
     //       actually does an append to the END of the list (not an
     //       insert at the head or after the current position).
     reqdOrder().insert( rowsetReqdOrder_ );
  }

  // end fix for defect 10-010522-2978

  // Bind the update column specification of a cursor declaration.
  // Don't remove the tree: leave it for possible error 4118 in NormRelExpr.
  if (updateColTree_) {
    updateColTree_->convertToValueIdList(updateCol(), bindWA, ITM_ITEM_LIST);
    if (bindWA->errStatus()) {
      if (CmpCommon::diags()->contains(-4001))
        *CmpCommon::diags() << DgSqlCode(-4117);
      return NULL;
    }

    if (getGroupAttr()->isEmbeddedDelete()) {   // QSTUFF
      *CmpCommon::diags() << DgSqlCode(-4169);
      bindWA->setErrStatus() ;
      return NULL;
    }
  }


  // check whether a CONTROL QUERY SHAPE statement is in effect.
  // Do not do if this is a control query statement.
  if (ActiveControlDB()->getRequiredShape()) {
    OperatorTypeEnum op = child(0)->getOperatorType();
    if (!child(0)->isAControlStatement() &&
        op != REL_DESCRIBE &&
        op != REL_EXPLAIN &&
        op != REL_DDL &&
        op != REL_LOCK &&
        op != REL_UNLOCK &&
        op != REL_SET_TIMEOUT &&  
        op != REL_STATISTICS &&
        op != REL_TRANSACTION &&
        op != REL_EXE_UTIL)
      reqdShape_ = ActiveControlDB()->getRequiredShape()->getShape();
  }

  // If this is a parallel extract producer query:
  // * the number of requested streams must be greater than one and
  //   not more than the number of configured CPUs
  // * force a shape with an ESP exchange node immediately below
  //   the root
  ComUInt32 numExtractStreams = getNumExtractStreams();
  if (numExtractStreams_ > 0)
  {
    // Check the number of requested streams
    NADefaults &defs = bindWA->getSchemaDB()->getDefaults();

    NABoolean fakeEnv = FALSE;
    ComUInt32 numConfiguredESPs = defs.getTotalNumOfESPsInCluster(fakeEnv);
    
    if ((numExtractStreams == 1) || (numExtractStreams > numConfiguredESPs))
    {
      *CmpCommon::diags() << DgSqlCode(-4119)
                          << DgInt0((Lng32) numConfiguredESPs);
      bindWA->setErrStatus();
      return NULL;
    }

    // Force the shape. There are three cases to consider:
    // a. there is no required shape in the ControlDB
    // b. there is a required shape and it is acceptable for this
    //    parallel extract.
    // c. there is a required shape and it is not acceptable.

    if (reqdShape_ == NULL)
    {
      // Case a.
      // Manufacture an esp_exchange(cut,N) shape
      reqdShape_ = new (bindWA->wHeap())
        ExchangeForceWildCard(new (bindWA->wHeap()) CutOp(0),
                              ExchangeForceWildCard::FORCED_ESP_EXCHANGE,
                              ExchangeForceWildCard::ANY_LOGPART,
                              (Lng32) numExtractStreams_);
    }
    else
    {
      NABoolean reqdShapeIsOK = FALSE;
      if (reqdShape_->getOperatorType() == REL_FORCE_EXCHANGE)
      {
        ExchangeForceWildCard *exch = (ExchangeForceWildCard *) reqdShape_;
        ExchangeForceWildCard::forcedExchEnum whichType = exch->getWhich();
        Lng32 howMany = exch->getHowMany();
        if (whichType == ExchangeForceWildCard::FORCED_ESP_EXCHANGE &&
            howMany == (Lng32) numExtractStreams_)
        {
          reqdShapeIsOK = TRUE;
        }
      }

      if (reqdShapeIsOK)
      {
        // Case b.
        // Do nothing
      }
      else
      {
        // Case c.
        // Add an esp_exchange to the top of the required shape
        RelExpr *child = reqdShape_;
        reqdShape_ = new (bindWA->wHeap())
          ExchangeForceWildCard(child,
                                ExchangeForceWildCard::FORCED_ESP_EXCHANGE,
                                ExchangeForceWildCard::ANY_LOGPART,
                                (Lng32) numExtractStreams_);
      }

    } // if (reqdShape_ == NULL) else ...
  } // if (numExtractStreams_ > 0)

  // Bind the base class.
  //
  RelExpr *boundExpr = bindSelf(bindWA);
  if (bindWA->errStatus()) return boundExpr;

  // If we have dynamic rowsets, we want to replace
  // dynamic parameters with available inputs.
  if (isTrueRoot() && bindWA->hasDynamicRowsetsInQuery()) {
    ValueIdSet inputs = getGroupAttr()->getCharacteristicInputs();
    UInt32 j = 0;
    // this for loop is over the list of available inputs. We are replacing array
    // parameters with hostvars introduced during HostArraysWA::processArrayHostVar
    // The hostvars introduced in that method are contained in the inputs() list.
    for (ValueId id = inputs.init(); inputs.next(id); inputs.advance(id)) {
      if (id.getItemExpr()->getOperatorType() == ITM_DYN_PARAM) {
        continue;
      }
      // We are assuming here that the hostvars introduced are in the same order as
      // the parameter arrays in inputVars(), i.e. (hv_A, hv_B) corresponds to
      // (?,?,?(as A), ?(as B))
      while (j < inputVars().entries()) {
        ItemExpr *ie = inputVars()[j].getItemExpr() ;
        OperatorTypeEnum ieType = ie->getOperatorType() ;
        if (( ieType != ITM_DYN_PARAM) ||
            (((DynamicParam *) ie)->getRowsetSize() == 0))
             {
          // if an ie is not a dynamicParam or it is a scalar dynamic Param do not remove
          // it from inputVars_. From embedded SQL it is possible to have scalar and array
          // dynamic params in the same statement. This is not possible from ODBC.
               j++;
             }
        else
          break ;
      }
      if (j < inputVars().entries()) {
        inputVars().removeAt(j);
        inputVars().insertAt(j, id);
        j++;
      }
    }
  }

  // RelRoot::codeGen() and Statement::execute() use TOPMOST root's accessOpts.
  //
  if (bindWA->getCurrentScope()->context()->stmtLevelAccessOptions())
    if (!accessOptions().userSpecified()) // seems redundant
      accessOptions() = *bindWA->getCurrentScope()->context()->stmtLevelAccessOptions();

  // Update operations currently require SERIALIZABLE (== MP REPEATABLE_)
  // locking level -- the QSTUFF-enabled DP2 now does this, supporting a true
  // READ_COMMITTED that is STABLE rather than merely CLEAN.
  if (!containsGenericUpdate(this)) {
    // Genesis 10-990114-6293:
    // This flag tells RelRoot::codeGen to set a flagbit in the root-tdb which
    // cli/Statement::execute + compareTransModes() will look at --
    //   if set, then this "read-write" stmt will be allowed to execute
    //   in a run-time transmode of read-only W/O HAVING TO BE RECOMPILED.
    readOnlyTransIsOK() = TRUE;
  }

  if (isTrueRoot()) {
    if (updateCurrentOf()) {
      // add child genericupdate's primary key hostvars to pkeyList.
      // The getLeftmostScanNode() method will return the leftmost Scan node
      // as the original scan node may have moved due to the IM tree.
      pkeyList().insert(child(0)->castToRelExpr()->getLeftmostScanNode()->pkeyHvarList());
    }

    for(Int32 st=0; st < (Int32)bindWA->getStoiList().entries(); st++)
    {
      if(bindWA->getStoiList()[st]->getStoi()->isView())
        viewStoiList_.insert(bindWA->getStoiList()[st]);
    }

    if(bindWA->inDDL())
      ddlStoiList_.insert(bindWA->getStoiList());

    // populate the list of all the routines open information of this query
    stoiUdrList_.insert(bindWA->getUdrStoiList());

    // populate the list of all the UDF information of this query
    udfList_.insert(bindWA->getUDFList());

    // check privileges
    if (!checkPrivileges(bindWA))
    {
      bindWA->setErrStatus();
      return NULL;
    }

    // store the trigger's list in the root
    if (bindWA->getTriggersList())
    {
      triggersList_ =
        new (bindWA->wHeap()) LIST(ComTimestamp)
                (bindWA->wHeap(), bindWA->getTriggersList()->entries());
      triggersList_->insert(*(bindWA->getTriggersList()));

      // Don't allow OLT optimization when triggers are involved.
      oltOptInfo().setOltOpt(FALSE);
    }


    // store the uninitialized mv list if there are any
    // entries    
    if( bindWA->getUninitializedMvList() )
    {    
        uninitializedMvList_ = new (bindWA->wHeap()) UninitializedMvNameList 
            (bindWA->wHeap(), bindWA->getUninitializedMvList()->entries());
        uninitializedMvList_->insert( *(bindWA->getUninitializedMvList()) );             
    } 
    
    
    DBG( if (getenv("TVUSG_DEBUG")) bindWA->tableViewUsageList().display(); )
  } // isTrueRoot

  // Don't allow OLT optimization when ON STATEMENT MV refresh is involved.
  if (bindWA->isBindingOnStatementMv())
    oltOptInfo().setOltOpt(FALSE);

  // disable esp parallelism for merge statements.
  // See class RelRoot for details about this.
  if ((isTrueRoot()) &&
      (bindWA->isMergeStatement()))
    {
      setDisableESPParallelism(TRUE);
    }

  // Remove the current scope.
  //
  if (!isDontOpenNewScope())  // -- Triggers
    bindWA->removeCurrentScope();

  // In case we have a query of the form
  //	SET <host var list> = <select statement>
  // we must update the value ids of the host variables in that list.
  // See Assignment Statement Internal Spec (a project of Compound Statements).
  if (assignmentStTree() &&
      bindWA->getAssignmentStArea() &&
      bindWA->getAssignmentStArea()->getAssignmentStHostVars() &&
     !bindWA->getAssignmentStArea()->getAssignmentStHostVars()->
                              updateValueIds(compExpr(), assignmentStTree())) {
    bindWA->setErrStatus();
    return NULL;
  }

  if (getPredExprTree())
    {
      CMPASSERT(isTrueRoot());

      ItemExpr * ie = removePredExprTree();
      ie = ie->bindNode(bindWA);
      if (bindWA->errStatus())
        return NULL;
      
      addPredExprTree(ie);
    }

  if (getFirstNRowsParam())
    {
      firstNRowsParam_ = firstNRowsParam_->bindNode(bindWA);
      if (bindWA->errStatus())
        return this;

      const SQLInt si(FALSE, FALSE);
      ValueId vid = firstNRowsParam_->castToItemExpr()->getValueId();
      vid.coerceType(si, NA_NUMERIC_TYPE);

      if (vid.getType().getTypeQualifier() != NA_NUMERIC_TYPE)
        {
          // 4045 must be numeric.
          *CmpCommon::diags() << DgSqlCode(-4045) << DgString0(getTextUpper());
          bindWA->setErrStatus();
          return this;
        }
    }

  if ((NOT hasOrderBy()) &&
      ((getFirstNRows() != -1) ||
       (getFirstNRowsParam())))
    {
      // create a firstN node to retrieve firstN rows.
      FirstN * firstn = new(bindWA->wHeap())
        FirstN(child(0), getFirstNRows(), getFirstNRowsParam());
      firstn->bindNode(bindWA);
      if (bindWA->errStatus())
        return NULL;

      setChild(0, firstn);

      // reset firstN indication in the root node.
      setFirstNRows(-1);
      setFirstNRowsParam(NULL);
    }

  // if we have no user-specified access options then
  // get it from nearest enclosing scope that has one (if any)
  if (!accessOptions().userSpecified()) {
    StmtLevelAccessOptions *axOpts = bindWA->findUserSpecifiedAccessOption();
    if (axOpts) {
      accessOptions() = *axOpts;
    }
  }

  if (bindWA->getHoldableType() == SQLCLIDEV_ANSI_HOLDABLE)
  {
    if (accessOptions().accessType() != ACCESS_TYPE_NOT_SPECIFIED_)
    {
      if (accessOptions().accessType() == REPEATABLE_)
      {
        *CmpCommon::diags() << DgSqlCode(-4381);
        bindWA->setErrStatus();
        return NULL;
      }
    }
    else
    {
      TransMode::IsolationLevel il=CmpCommon::transMode()->getIsolationLevel();
      if (CmpCommon::transMode()->ILtoAT(il) == REPEATABLE_ )
      {
        *CmpCommon::diags() << DgSqlCode(-4381);
        bindWA->setErrStatus();
        return NULL;
      }
    }
  }

  // The above code is in Scan::bindNode also.
  // It would be nice to refactor this common code; someday.
             
  return boundExpr;
} // RelRoot::bindNode()

// Present the select list as a tree of Item Expressions
ItemExpr *RelRoot::selectList()
{
  return compExpr().rebuildExprTree(ITM_ITEM_LIST);
} // RelRoot::selectList()

// Returns current place that assignmentStTree_ points to and
// sets that pointer to NULL
// LCOV_EXCL_START - cnu
ItemExpr * RelRoot::removeAssignmentStTree()
{
  ItemExpr* tempTree = assignmentStTree_;
  assignmentStTree_ = NULL;
  return tempTree;
}
// LCOV_EXCL_STOP

bool OptSqlTableOpenInfo::checkColPriv(const PrivType privType,
                                       const PrivMgrUserPrivs *pPrivInfo)
{
  CMPASSERT (pPrivInfo);

  NATable* table = getTable();
  NAString columns = "";

  if (!isColumnPrivType(privType))
  {
    *CmpCommon::diags() << DgSqlCode(-4481)
                        << DgString0(PrivMgrUserPrivs::convertPrivTypeToLiteral(privType).c_str())
                        << DgString1(table->getTableName().getQualifiedNameAsAnsiString())
                        << DgString2(columns);
    return false;  
  }

  bool hasPriv = true;

  // initialize to something, gets set appropriately below
  LIST (Lng32) * colList = NULL ;
  switch (privType)
  {
    case INSERT_PRIV:
    {
      colList = (LIST (Lng32) *)&(getInsertColList());
      break;
    }
    case UPDATE_PRIV:
    {
      colList = (LIST (Lng32) *)&(getUpdateColList());
      break;
    }
    case SELECT_PRIV:
    {
      colList = (LIST (Lng32) *)&(getSelectColList());
      break;
    }
    default:
      CMPASSERT(FALSE); // delete has no column privileges.
  }

  bool collectColumnNames = false;
  if (pPrivInfo->hasAnyColPriv(privType))
  {
    collectColumnNames = true;
    columns += "(columns:" ; 
  }
  bool firstColumn = true;
  for(size_t i = 0; i < colList->entries(); i++)
  {
    size_t columnNumber = (*colList)[i];
    if (!(pPrivInfo->hasColPriv(privType,columnNumber)))
    {
      hasPriv = false;
      if (firstColumn && collectColumnNames)
      {
        columns += " ";
        firstColumn = false;
      }
      else 
        if (collectColumnNames)
          columns += ", ";

      if (collectColumnNames)
        columns += table->getNAColumnArray()[columnNumber]->getColName();
    }
  }

  if (collectColumnNames)
    columns += ")" ;

  // (colList->entries() == 0) ==> we have a select count(*) type query or a
  // select 1 from T type query. In other words the table needs to be accessed
  // but no column has been explicitly referenced.
  // For such queries if the user has privilege on any one column that is 
  // sufficient. collectColumnNames indicates whether the user has privilege
  // on at least one column. The following if statement applies only to selects
  // For update and insert we do not expect colList to be empty.

  if ((colList->entries() == 0)&& !collectColumnNames)
  {
    hasPriv = false;
    columns = "";
  }

  if (!hasPriv)
    *CmpCommon::diags() << DgSqlCode(-4481)
                        << DgString0(PrivMgrUserPrivs::convertPrivTypeToLiteral(privType).c_str())
                        << DgString1(table->getTableName().getQualifiedNameAsAnsiString())
                        << DgString2(columns);

  return hasPriv;
  
}


NABoolean RelRoot::checkFirstNRowsNotAllowed(BindWA *bindWA)
{
  // do not call this method on a true root.
  CMPASSERT(NOT isTrueRoot());
 
  //***************************************************************** 
  // FirstNRows >= 0 (for FirstN)
  //            == -2 For Last 0
  //            == -3 For Last 1
  // These values are set in parser; see the code SqlParser.y under
  // Non-Terminal querySpecification when fisrtN is specified
  //******************************************************************

  if ( (getFirstNRows() >= 0 || 
        getFirstNRows() == -2 ||
        getFirstNRows() == -3) &&  // this root has firstn
      (!((getInliningInfo().isEnableFirstNRows()) ||
      (getHostArraysArea() && getHostArraysArea()->getHasSelectIntoRowsets()) || //firstn is allowed with a rowset subroot
      (assignmentStTree()))))  // first n is allowed in a CS. Presence of assignmentStTree
                               // on a non true root implies presence of select into statement
                               // within a cs
        {
          // 4102 The [FIRST/ANY n] syntax can only be used in an outermost SELECT statement.
          if (CmpCommon::getDefault(ALLOW_FIRSTN_IN_SUBQUERIES) == DF_OFF)
            return TRUE;
        }
   return FALSE;
}

// ----------------------------------------------------------------------------
// Method:  checkPrivileges
//
// This method:
//   - Verifies that the user executing the query has the necessary privileges
//   - Adds security keys to RelRoot class  that need to be checked when priv
//     changes (revokes) are performed.  Security keys are part of the Query 
//     Invalidation feature.
//   - Also, removes any previously cached entries if the user has no priv
//
// Input: pointer to the binder work area
// Output:  result of the check
//   TRUE  - user has priv
//   FALSE - user does not have priv or unexpected error occurred
//
// The ComDiags area is populated with error details
// The BindWA flag setFailedForPrivileges is set to TRUE if priv check fails 
// ----------------------------------------------------------------------------
NABoolean RelRoot::checkPrivileges(BindWA* bindWA)
{
  // If internal caller and not part of explain, then return 
  if (Get_SqlParser_Flags(INTERNAL_QUERY_FROM_EXEUTIL)) 
    return TRUE;

  // If qiPath (used for testing) is not 0, skip root user check
  NAString qiPath = "";
  CmpCommon::getDefault(QI_PATH, qiPath, FALSE);
  if (qiPath.length() == 0 && ComUser::isRootUserID())
    return TRUE;

  // See if there is anything to check
  //  StoiList contains any tables used in the query
  //  UdrStoiList contains any routines used in the query
  //  CoProcAggrList contains any queries using the aggregate co-processor
  //  SeqValList contains any sequences
  if (bindWA->getStoiList().entries() == 0 &&
      bindWA->getUdrStoiList().entries() == 0 &&
      bindWA->getCoProcAggrList().entries() == 0 &&
      bindWA->getSeqValList().entries() == 0)
    return TRUE;

  // If authorization is not enabled, then return TRUE
  if (!CmpCommon::context()->isAuthorizationEnabled())
    return TRUE;

  ComBoolean QI_enabled = (CmpCommon::getDefault(CAT_ENABLE_QUERY_INVALIDATION) == DF_ON);
  NABoolean RemoveNATableEntryFromCache = FALSE ;

  // Have the ComSecurityKey constructor compute the hash value for the the User's ID.
  // Note: The following code doesn't care about the object's hash value or the resulting 
  // ComSecurityKey's ActionType....we just need the hash value for the User's ID.
  int64_t objectUID = 12345;
  Int32 thisUserID = ComUser::getCurrentUser();
  ComSecurityKey userKey( thisUserID , objectUID
                         , SELECT_PRIV
                         , ComSecurityKey::OBJECT_IS_OBJECT
                        );
  uint32_t userHashValue = userKey.getSubjectHashValue();


  // Set up a PrivMgrCommands class in case we need to get privilege information
  NAString privMDLoc;
  CONCAT_CATSCH(privMDLoc,CmpSeabaseDDL::getSystemCatalogStatic(),SEABASE_PRIVMGR_SCHEMA);
  PrivMgrCommands privInterface(privMDLoc.data(), CmpCommon::diags(), PrivMgr::PRIV_INITIALIZED);
  PrivStatus retcode = STATUS_GOOD;

  // ==> Check privileges for tables used in the query.
  SqlTableOpenInfo * stoi = NULL ;
  OptSqlTableOpenInfo * optStoi = NULL;
  for(Int32 i=0; i<(Int32)bindWA->getStoiList().entries(); i++)
  {
    RemoveNATableEntryFromCache = FALSE ;  // Initialize each time through loop
    optStoi = (bindWA->getStoiList())[i];
    stoi = optStoi->getStoi();
    NATable* tab = optStoi->getTable();

    // System metadata tables do not, by default, have privileges stored in the
    // NATable structure.  Go ahead and retrieve them now. 
    PrivMgrUserPrivs *pPrivInfo = tab->getPrivInfo();
    PrivMgrUserPrivs privInfo;
    if (!pPrivInfo)
    {
      CmpSeabaseDDL cmpSBD(STMTHEAP);
      if (cmpSBD.switchCompiler(CmpContextInfo::CMPCONTEXT_TYPE_META))
      {
        if (CmpCommon::diags()->getNumber(DgSqlCode::ERROR_) == 0)
          *CmpCommon::diags() << DgSqlCode( -4400 );
        return FALSE;
      }
      retcode = privInterface.getPrivileges( tab, thisUserID, privInfo);
      cmpSBD.switchBackCompiler();

      if (retcode != STATUS_GOOD)
      {
        tab->setRemoveFromCacheBNC(TRUE);
        bindWA->setFailedForPrivileges(TRUE);
        *CmpCommon::diags() << DgSqlCode( -1034 );
        return FALSE;
      }
      pPrivInfo = &privInfo;
    }

    // Check each primary DML privilege to see if the query requires it. If 
    // so, verify that the user has the privilege
    bool insertQIKeys = (QI_enabled && tab->getSecKeySet().entries() > 0);
    for (int_32 i = FIRST_DML_PRIV; i <= LAST_PRIMARY_DML_PRIV; i++)
    {
      if (stoi->getPrivAccess((PrivType)i))
      {
        if (!pPrivInfo->hasPriv((PrivType)i) && !optStoi->checkColPriv((PrivType)i, pPrivInfo))
          RemoveNATableEntryFromCache = TRUE;
        else
          if (insertQIKeys)    
            findKeyAndInsertInOutputList(tab->getSecKeySet(),userHashValue,(PrivType)(i));
      }
    }

    // wait until all the primary DML privileges have been checked before
    // setting failure information
    if ( RemoveNATableEntryFromCache )
    {
       bindWA->setFailedForPrivileges( TRUE );
       tab->setRemoveFromCacheBNC(TRUE); // To be removed by CmpMain before Compilation retry
    }
  }  // for loop over tables in stoi list

  // ==> Check privileges for functions and procedures used in the query.
  NABoolean RemoveNARoutineEntryFromCache = FALSE ;
  if (bindWA->getUdrStoiList().entries())
  {
    for(Int32 i=0; i<(Int32)bindWA->getUdrStoiList().entries(); i++)
    {
      // Privilege info for the user/routine combination is stored in the 
      // NARoutine object.
      OptUdrOpenInfo *udrStoi = (bindWA->getUdrStoiList())[i];
      NARoutine* rtn = udrStoi->getNARoutine();
      PrivMgrUserPrivs *pPrivInfo = rtn->getPrivInfo();

      NABoolean insertQIKeys = FALSE;
      if (QI_enabled && (rtn->getSecKeySet().entries() > 0))
       insertQIKeys = TRUE;

      if (pPrivInfo == NULL) 
      {
        RemoveNARoutineEntryFromCache = TRUE ; 
        *CmpCommon::diags() << DgSqlCode( -1034 );
      }

      // Verify that the user has execute priv
      else
      {
        if (pPrivInfo->hasPriv(EXECUTE_PRIV))
        {
          // do this only if QI is enabled and object has security keys defined
          if ( insertQIKeys )
            findKeyAndInsertInOutputList(rtn->getSecKeySet(), userHashValue, EXECUTE_PRIV);
        }

        // plan requires privilege but user has none, report an error
        else
        {
          RemoveNARoutineEntryFromCache = TRUE ; 
          *CmpCommon::diags() 
            << DgSqlCode( -4482 )
            << DgString0( "EXECUTE" )
            << DgString1( udrStoi->getUdrName() );
        }
      }

      if ( RemoveNARoutineEntryFromCache )
      {
        bindWA->setFailedForPrivileges(TRUE);

        // If routine exists in cache, add it to the list to remove
        NARoutineDB *pRoutineDBCache  = bindWA->getSchemaDB()->getNARoutineDB();
        NARoutineDBKey key(rtn->getSqlName(), bindWA->wHeap());
        NARoutine *cachedNARoutine = pRoutineDBCache->get(bindWA, &key);
        if (cachedNARoutine != NULL)
          pRoutineDBCache->moveRoutineToDeleteList(cachedNARoutine, &key);
      }
    }  // for loop over UDRs
  }  // end if any UDRs.

  // ==> Check privs on any CoprocAggrs used in the query.
  for (Int32 i=0; i<(Int32)bindWA->getCoProcAggrList().entries(); i++)
  {
    RemoveNATableEntryFromCache = FALSE ;  // Initialize each time through loop
    ExeUtilHbaseCoProcAggr *coProcAggr = (bindWA->getCoProcAggrList())[i];
    NATable* tab = bindWA->getSchemaDB()->getNATableDB()->
                                   get(coProcAggr->getCorrName(), bindWA, NULL);

    Int32 numSecKeys = 0;

    // Privilege info for the user/table combination is stored in the NATable
    // object.
    PrivMgrUserPrivs* pPrivInfo = tab->getPrivInfo();
    PrivMgrUserPrivs privInfo;

    // System metadata tables do not, by default, have privileges stored in the
    // NATable structure.  Go ahead and retrieve them now. 
    if (!pPrivInfo)
    {
      CmpSeabaseDDL cmpSBD(STMTHEAP);
      if (cmpSBD.switchCompiler(CmpContextInfo::CMPCONTEXT_TYPE_META))
      {
        if (CmpCommon::diags()->getNumber(DgSqlCode::ERROR_) == 0)
          *CmpCommon::diags() << DgSqlCode( -4400 );
        return FALSE;
      }
      retcode = privInterface.getPrivileges( tab, thisUserID, privInfo);
      cmpSBD.switchBackCompiler();

      if (retcode != STATUS_GOOD)
      {
        bindWA->setFailedForPrivileges( TRUE );
        tab->setRemoveFromCacheBNC(TRUE); // To be removed by CmpMain before Compilation retry
        *CmpCommon::diags() << DgSqlCode( -1034 );
        return FALSE;
      }
      pPrivInfo = &privInfo;
    }

    // Verify that the user has select priv
    // Select priv is needed for EXPLAIN requests, so no special check is done
    NABoolean insertQIKeys = FALSE; 
    if (QI_enabled && (tab->getSecKeySet().entries()) > 0)
      insertQIKeys = TRUE;
    if (pPrivInfo->hasPriv(SELECT_PRIV))
    {
      // do this only if QI is enabled and object has security keys defined
      if ( insertQIKeys )
        findKeyAndInsertInOutputList(tab->getSecKeySet(), userHashValue, SELECT_PRIV );
    }

    // plan requires privilege but user has none, report an error
    else
    {
       bindWA->setFailedForPrivileges( TRUE );
       tab->setRemoveFromCacheBNC(TRUE); // To be removed by CmpMain before Compilation retry
       *CmpCommon::diags()
         << DgSqlCode( -4481 )
         << DgString0( "SELECT" )
         << DgString1( tab->getTableName().getQualifiedNameAsAnsiString() );
    }
  }  // for loop over coprocs

  // ==> Check privs on any sequence generators used in the query.
  for (Int32 i=0; i<(Int32)bindWA->getSeqValList().entries(); i++)
  {
    RemoveNATableEntryFromCache = FALSE ;  // Initialize each time through loop
    SequenceValue *seqVal = (bindWA->getSeqValList())[i];
    NATable* tab = const_cast<NATable*>(seqVal->getNATable());
    CMPASSERT(tab);

    // get privilege information from the NATable structure
    PrivMgrUserPrivs *pPrivInfo = tab->getPrivInfo();
    PrivMgrUserPrivs privInfo;
    if (!pPrivInfo)
    {
      CmpSeabaseDDL cmpSBD(STMTHEAP);
      if (cmpSBD.switchCompiler(CmpContextInfo::CMPCONTEXT_TYPE_META))
      {
        if (CmpCommon::diags()->getNumber(DgSqlCode::ERROR_) == 0)
          *CmpCommon::diags() << DgSqlCode( -4400 );
        return FALSE;
      }
      retcode = privInterface.getPrivileges(tab, thisUserID, privInfo);
      cmpSBD.switchBackCompiler();
      if (retcode != STATUS_GOOD)
      {
        bindWA->setFailedForPrivileges(TRUE);
        tab->setRemoveFromCacheBNC(TRUE); // Not used until sequences stored in table cache
        *CmpCommon::diags() << DgSqlCode( -1034 );
        return FALSE;
      }
      pPrivInfo = &privInfo;
    }

    // Verify that the user has usage priv
    NABoolean insertQIKeys = FALSE; 
    if (QI_enabled && (tab->getSecKeySet().entries()) > 0)
      insertQIKeys = TRUE;
    if (pPrivInfo->hasPriv(USAGE_PRIV))
    {
      // do this only if QI is enabled and object has security keys defined
      if ( insertQIKeys )
        findKeyAndInsertInOutputList(tab->getSecKeySet(), userHashValue, USAGE_PRIV );
    }

    // plan requires privilege but user has none, report an error
    else
    {
      bindWA->setFailedForPrivileges( TRUE );
      tab->setRemoveFromCacheBNC(TRUE); // To be removed by CmpMain before Compilation retry
      *CmpCommon::diags()
        << DgSqlCode( -4491 )
        << DgString0( "USAGE" )
        << DgString1( tab->getTableName().getQualifiedNameAsAnsiString());
    }
  }  // for loop over sequences

  return !bindWA->failedForPrivileges() ;
}

// ****************************************************************************
// method: findKeyAndInsertInOutputList
//
// This method searches through the list of security keys associated with the
// object to find the best candidate to save in the plan based on the
// privilege required.  If it finds a candidate, it inserts the best candidate 
// into securityKeySet_ member of the RelRoot class.
//
// Security key types currently include:
//   COM_QI_OBJECT_<priv>:   privileges granted directly to the user
//   COM_QI_USER_GRANT_ROLE: privileges granted to the user via a role 
//   COM_QI_USER_GRANT_SPECIAL_ROLE: privileges granted to PUBLIC
//
// COM_QI_OBJECT_<priv> types are preferred over COM_QI_USER_GRANT_ROLE.
// ****************************************************************************
void RelRoot::findKeyAndInsertInOutputList( ComSecurityKeySet KeysForTab
                                          , const uint32_t userHashValue
                                          , const PrivType which
                                          )
{
   // If no keys associated with object, just return
   if (KeysForTab.entries() == 0)
     return;

   ComSecurityKey * UserObjectKey = NULL;
   ComSecurityKey * RoleObjectKey = NULL;
   ComSecurityKey * UserObjectPublicKey = NULL;
   
   // These may be implemented at a later time
   ComSecurityKey * UserSchemaKey = NULL; //privs granted at schema level to user
   ComSecurityKey * RoleSchemaKey = NULL; //privs granted at schema level to role

   // Get action type for UserObjectKey based on the privilege (which)
   // so if (which) is SELECT, then the objectActionType is COM_QI_OBJECT_SELECT
   ComSecurityKey  dummyKey;
   ComQIActionType objectActionType =
                   dummyKey.convertBitmapToQIActionType ( which, ComSecurityKey::OBJECT_IS_OBJECT );

   ComSecurityKey * thisKey = NULL;

   // NOTE: hashValueOfPublic will be the same for all keys, so we generate it only once.
   uint32_t hashValueOfPublic = ComSecurityKey::SPECIAL_OBJECT_HASH;

   // Traverse List looking for ANY appropriate ComSecurityKey 
   for ( Int32 ii = 0; ii < (Int32)(KeysForTab.entries()); ii++ )
   {
      thisKey = &(KeysForTab[ii]);
  
      // See if the key is object related
      if ( thisKey->getSecurityKeyType() == objectActionType )
      {
         if ( thisKey->getSubjectHashValue() == userHashValue )
         {
            // Found a security key for the objectActionType
            if ( ! UserObjectKey ) 
               UserObjectKey = thisKey;
         }
      }
     
      // See if the security key is role related
      else if (thisKey->getSecurityKeyType() == COM_QI_USER_GRANT_ROLE) 
      {
         if ( thisKey->getSubjectHashValue() == userHashValue )
         {
            if (! RoleObjectKey ) 
               RoleObjectKey = thisKey;
         }
      }

      else if (thisKey->getSecurityKeyType() == COM_QI_USER_GRANT_SPECIAL_ROLE)
      {
         if (thisKey->getObjectHashValue() == hashValueOfPublic )
         {
            if (! UserObjectPublicKey )
               UserObjectPublicKey = thisKey;
         }
      }

      else {;} // Not right action type, just continue traversing.
   }

   // Determine best key, UserObjectKeys are better than RoleObjectKeys
   ComSecurityKey * BestKey = (UserObjectKey) ? UserObjectKey : RoleObjectKey;

   if ( BestKey != NULL)
      securityKeySet_.insert(*BestKey);

   // Add public if it exists
   if ( UserObjectPublicKey != NULL )
     securityKeySet_.insert(*UserObjectPublicKey); 
}


// -----------------------------------------------------------------------
// member functions for class GroupByAgg
// -----------------------------------------------------------------------

RelExpr *GroupByAgg::bindNode(BindWA *bindWA)
{
  if (nodeIsBound())
  {
    bindWA->getCurrentScope()->setRETDesc(getRETDesc());
    return this;
  }

  //
  // add any aggregate functions found in the parent node(s)
  //
  BindScope *currScope = bindWA->getCurrentScope();
  aggregateExpr_ += currScope->getUnresolvedAggregates();
  currScope->getUnresolvedAggregates().clear();
  //
  // Bind the child nodes.
  //
  currScope->context()->lookAboveToDecideSubquery() = TRUE;
  bindChildren(bindWA);
  currScope->context()->lookAboveToDecideSubquery() = FALSE;
  if (bindWA->errStatus()) return this;
  bindWA->getCurrentScope()->setRETDesc(getRETDesc());

  // QSTUFF
  NAString fmtdList(bindWA->wHeap());
  LIST(TableNameMap*) xtnmList(bindWA->wHeap());
  bindWA->getTablesInScope(xtnmList, &fmtdList);

  // can be removed when supporting aggregates on streams
  if (getGroupAttr()->isStream()){
    *CmpCommon::diags() << DgSqlCode(-4162) << DgString0(fmtdList);
    bindWA->setErrStatus();
    return this;
  }

  if ((getGroupAttr()->isEmbeddedUpdateOrDelete()) ||
      (bindWA->isEmbeddedIUDStatement())) {
    *CmpCommon::diags() << DgSqlCode(-4163) << DgString0(fmtdList)
      << (getGroupAttr()->isEmbeddedUpdate() ?
         DgString1("UPDATE"):DgString1("DELETE"));
    bindWA->setErrStatus();
    return this;
  }
  // QSTUFF

  // if unresolved aggregate functions have been found in the children of the
  // Groupby node, that would mean that we are referencing aggregates before
  // the groupby operation is performed
  //
  if (checkUnresolvedAggregates(bindWA))
    return this;
  //
  // Detach the item expression tree for the grouping column list, bind it,
  // convert it to a ValueIdSet, and attach it to the GroupByAgg node.
  //
  ItemExpr *groupExprTree = removeGroupExprTree();
  if (groupExprTree) {
    currScope->context()->inGroupByClause() = TRUE;
    groupExprTree->convertToValueIdSet(groupExpr(), bindWA, ITM_ITEM_LIST);

    if (isRollup())
      groupExprTree->convertToValueIdList(
           rollupGroupExprList(), bindWA, ITM_ITEM_LIST);

    currScope->context()->inGroupByClause() = FALSE;
    if (bindWA->errStatus()) return this;

    ValueIdList groupByList(groupExpr());
 
    for (CollIndex i = 0; i < groupByList.entries(); i++)
    {
      ValueId vid = groupByList[i];
      vid.getItemExpr()->setIsGroupByExpr(TRUE);
    }

    if ((groupExprTree != NULL) &&
        (getParentRootSelectList() != NULL))
      {
        RETDesc * childRETDesc = child(0)->getRETDesc();
        ItemExprList origSelectList(getParentRootSelectList(), bindWA->wHeap());
        
        for (CollIndex i = 0; i < groupByList.entries(); i++)
          {
            ValueId vid = groupByList[i];
            if((vid.getItemExpr()->getOperatorType() == ITM_SEL_INDEX)&&
               (((SelIndex*)(vid.getItemExpr()))->renamedColNameInGrbyClause()))
              {
                ULng32 indx = ((SelIndex*)(vid.getItemExpr()))->getSelIndex() - 1;
                if (origSelectList.entries() > indx && 
                    origSelectList[indx]->getOperatorType() == ITM_RENAME_COL) 
                  {
                    const ColRefName &selectListColRefName = 
                      *((RenameCol *)origSelectList[indx])->getNewColRefName();
                    ColumnNameMap *baseColExpr = 
                      childRETDesc->findColumn(selectListColRefName);
                    if (baseColExpr)
                      {
                        groupExpr().remove(vid);
                        groupExpr().insert(baseColExpr->getValueId());

                        if (isRollup())
                          {
                            CollIndex idx = rollupGroupExprList().index(vid);
                            rollupGroupExprList()[idx] = baseColExpr->getValueId();
                          }
 
                        baseColExpr->getColumnDesc()->setGroupedFlag();
                        origSelectList[indx]->setInGroupByOrdinal(FALSE);
                      }
                  }
              }
          }
        
        if (getSelPredTree()) 
          {
            ItemExpr * havingPred = (ItemExpr *) getSelPredTree();
            
            // see if having expr refers to any renamed col in the select list.
            // that is NOT a name exposed by child RETDesc. 
            // If it does, replace it with SelIndex.
            // For now, do this for special1 mode and only if the having
            // is a simple pred of the form:  col <op> value.
            // Later, we can extend this to all kind of having pred by 
            // traversing the having pred tree and replacing renamed cols.
            NABoolean replaced = FALSE;
            NABoolean notAllowedWithSelIndexInHaving = FALSE;
            replaceRenamedColInHavingWithSelIndex(
                 bindWA, havingPred, origSelectList, replaced,
                 notAllowedWithSelIndexInHaving,child(0)->getRETDesc());
            if (bindWA->errStatus())
              return this;
            if (replaced)
              {
                if (notAllowedWithSelIndexInHaving)
                  {
                    *CmpCommon::diags() << DgSqlCode(-4196) ;
                    bindWA->setErrStatus();
                    return this;
                  }
                
                setSelIndexInHaving(TRUE);
              }
          }
        setParentRootSelectList(NULL);
      }
    
    // Indicate that we are not in a scalar groupby.  Any aggregate
    // functions found in the select list or having clause cannot
    // evaluate to NULL unless their argument is null.
    currScope->context()->inScalarGroupBy() = FALSE;
  }
  //
  // bind the having predicates and attach the resulting value id set
  // to the node (as a selection predicate on the groupby node)
  //
  ItemExpr *havingPred = removeSelPredTree();
  if (havingPred && NOT selIndexInHaving()) 
  {
    currScope->context()->inHavingClause() = TRUE;
    havingPred->convertToValueIdSet(selectionPred(), bindWA, ITM_AND);
    currScope->context()->inHavingClause() = FALSE;
    if (bindWA->errStatus()) 
      return this;
  }

  //
  // Bind the base class.
  //
  RelExpr *boundExpr = bindSelf(bindWA);
  if (bindWA->errStatus()) return boundExpr;

  if ((havingPred) &&
    (selIndexInHaving())) 
  {
    addSelPredTree(havingPred);
  }

  //
  // Get the aggregate expressions from the list that has accumulated
  // in the current bind scope and clear the list in the bind scope --
  //   but first, if Tuple::bindNode()/checkTupleElementsAreAllScalar()
  //   created this node, add the subquery aggregate expr
  //   (Genesis 10-000221-6676).
  //
  if (aggregateExprTree_) { // only Binder, not Parser, should put anything here
    //	CMPASSERT(bindWA->getCurrentScope()->context()->inTupleList());
    CMPASSERT(aggregateExprTree_->nodeIsBound() ||
              aggregateExprTree_->child(0)->nodeIsBound());
    aggregateExprTree_ = aggregateExprTree_->bindNode(bindWA);
    if (bindWA->errStatus()) return boundExpr;
    aggregateExpr_    += aggregateExprTree_->getValueId();
    aggregateExprTree_ = NULL;
  }
  aggregateExpr_ += currScope->getUnresolvedAggregates();
  currScope->getUnresolvedAggregates().clear();
  getRETDesc()->setGroupedFlag();

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

// -----------------------------------------------------------------------
// member functions for class Scan
// -----------------------------------------------------------------------


////////////////////////////////////////////////////////////////////////
// A list of 'fabricated' hostvar representing the hostvars is generated
// that will contain the primary key values. These primary key
// values are retrieved at runtime from the cursor statement
// specified in the 'current of' clause. A predicate of the
// form 'where pkey1 = :pkey1 and pkey2 = :pkey2...' is attached
// to the selection pred of this node. The hostvar values are
// then passed in by the root node to its child and they reach
// this node at runtime where the 'where' predicate is evaluated.
////////////////////////////////////////////////////////////////////////
void Scan::bindUpdateCurrentOf(BindWA *bindWA, NABoolean updateQry)
{
  ValueIdList keyList = getTableDesc()->getClusteringIndex()->getIndexKey();
  ItemExpr * rootPtr = NULL;
  char hvName[30];
  CollIndex i = 0;
  for (i = 0; i < keyList.entries(); i++)
    {
      ValueId vid = keyList[i];

      // Fabricate a name for the i'th host variable,
      // make a hostvar,add it to pkeyHvarList.
      sprintf(hvName,"_upd_pkey_HostVar%d",i);

      HostVar *hv = new(bindWA->wHeap()) HostVar(hvName, &vid.getType(), TRUE);
      hv->bindNode(bindWA);

      pkeyHvarList().insert(hv->getValueId());

      // Build a 'pkey = pkey_hvar' predicate.
      ItemExpr * eqPred = new(bindWA->wHeap())
                            BiRelat(ITM_EQUAL, vid.getItemExpr(), hv);

      if (!rootPtr)
        rootPtr = eqPred;
      else
        rootPtr = new(bindWA->wHeap()) BiLogic(ITM_AND, rootPtr, eqPred);
    } // loop over all pkey columns

  if (updateQry)
    {
      ItemExpr * updCheckPtr = NULL;
      ValueIdList nonKeyColList;
      getTableDesc()->getClusteringIndex()->getNonKeyColumnList(nonKeyColList);
      for (i = 0; i < nonKeyColList.entries(); i++)
        {
          ValueId vid = nonKeyColList[i];

          // Fabricate a name for the i'th host variable,
          // make a hostvar,add it to pkeyHvarList.
          sprintf(hvName,"_upd_col_HostVar%d",i);

          HostVar *hv = new(bindWA->wHeap()) HostVar(hvName, &vid.getType(), TRUE);
          hv->bindNode(bindWA);

          pkeyHvarList().insert(hv->getValueId());

          // Build a 'col = col_hvar' predicate.
          ItemExpr * eqPred = new(bindWA->wHeap())
            BiRelat(ITM_EQUAL, vid.getItemExpr(), hv, TRUE);

          if (!updCheckPtr)
            updCheckPtr = eqPred;
          else
            updCheckPtr =
              new(bindWA->wHeap()) BiLogic(ITM_AND, updCheckPtr, eqPred);
        } // loop over all pkey columns

      if (updCheckPtr)
        {
          updCheckPtr = new (bindWA->wHeap())
            Case(NULL,
                 new (bindWA->wHeap())
                   IfThenElse(updCheckPtr,
                              new (bindWA->wHeap()) BoolVal(ITM_RETURN_TRUE),
                              new (bindWA->wHeap())
                                BoolVal(ITM_RETURN_TRUE,
                                        new (bindWA->wHeap())
                                          RaiseError(-(Lng32)EXE_CURSOR_UPDATE_CONFLICT))));

          rootPtr = new(bindWA->wHeap()) BiLogic(ITM_AND, rootPtr, updCheckPtr);
        }
    }

//  rootPtr->bindNode(bindWA);

  // add this new tree to the existing selection predicate
  addSelPredTree(rootPtr);

  bindSelf(bindWA);   // just in case

} // Scan::bindUpdateCurrentOf()

// Every Scan and every GenericUpdate has its own stoi,
// plus copies of some of these stoi's are copied to the BindWA
//
// The scan/gu stoi's will become ex_partn_access stoi's
//
// The stoiList copies in BindWA will have their security
// checked in the binder, in RelRoot::checkPrivileges
//
// Stoi's must exist for every table/view/MV/index.
// Stoi's that are not copied to the BindWA are those for which Ansi mandates
// that no security checking be done (e.g., indexes).
//
OptSqlTableOpenInfo *setupStoi(OptSqlTableOpenInfo *&optStoi_,
                               BindWA *bindWA,
                               const RelExpr *re,
                               const NATable *naTable,
                               const CorrName &corrName,
                               NABoolean noSecurityCheck)
{
  // Get the PHYSICAL (non-Ansi/non-delimited) filename of the table or view.
  CMPASSERT(!naTable->getViewText() || naTable->getViewFileName());
  NAString fileName( naTable->getViewText() ?
                      (NAString)naTable->getViewFileName() :
                       naTable->getClusteringIndex()->
                          getFileSetName().getQualifiedNameAsString(),
                     bindWA->wHeap());

  SqlTableOpenInfo * stoi_ = new (bindWA->wHeap()) SqlTableOpenInfo;

  optStoi_ = new(bindWA->wHeap()) OptSqlTableOpenInfo(stoi_,
                                                      corrName,
                                                      bindWA->wHeap());

  stoi_->setFileName(convertNAString(fileName, bindWA->wHeap()));

  if (naTable->getIsSynonymTranslationDone())
  {
     stoi_->setAnsiName(convertNAString(
                         naTable->getSynonymReferenceName(),
                         bindWA->wHeap())); 
  }
  else
  {
     stoi_->setAnsiName(convertNAString(
                         naTable->getTableName().getQualifiedNameAsAnsiString(),
                         bindWA->wHeap()));
  }

  if(naTable->isUMDTable() || naTable->isSMDTable()
    || naTable->isMVUMDTable() || naTable->isTrigTempTable())
  {
    stoi_->setIsMXMetadataTable(1);
  }

  if (NOT corrName.getCorrNameAsString().isNull())
    {
      NABoolean corrNameSpecified = TRUE;
      if (corrNameSpecified)
        {
          stoi_->setCorrName(convertNAString(
               corrName.getCorrNameAsString(),
               bindWA->wHeap()));
        }
    }

  // Materialized-View is considered as a regular table
  stoi_->setSpecialTable(naTable->getSpecialType() != ExtendedQualName::NORMAL_TABLE &&
    naTable->getSpecialType() != ExtendedQualName::MV_TABLE);
  stoi_->setIsView(naTable->getViewText() ? TRUE : FALSE);

  if (naTable->isHbaseTable())
    stoi_->setIsHbase(TRUE);

  stoi_->setLocationSpecified(corrName.isLocationNameSpecified() || 
    corrName.isPartitionNameSpecified() );

  stoi_->setUtilityOpen(corrName.isUtilityOpenIdSpecified());
  stoi_->setUtilityOpenId(corrName.getUtilityOpenId());

  stoi_->setIsNSAOperation(corrName.isNSAOperation());


  if (! naTable->getViewText())
    stoi_->setIsAudited(naTable->getClusteringIndex()->isAudited());

  switch (re->getOperatorType())
  {
    case REL_UNARY_INSERT:
    case REL_LEAF_INSERT:
      stoi_->setInsertAccess();
      break;
    case REL_UNARY_UPDATE:
      {
        stoi_->setUpdateAccess();
        if (((GenericUpdate*)re)->isMerge())
          stoi_->setInsertAccess();
      }
      break;
    case REL_UNARY_DELETE:
    case REL_LEAF_DELETE:
      {
        stoi_->setDeleteAccess();
        if (((GenericUpdate*)re)->isMerge())
          stoi_->setInsertAccess();
        if (((Delete*)re)->isFastDelete())
          stoi_->setSelectAccess();
      }
      break;
    case REL_SCAN:
    case REL_LOCK:
    case REL_UNLOCK:
    case REL_HBASE_COPROC_AGGR:
      stoi_->setSelectAccess();
      break;
    case REL_EXE_UTIL:

      stoi_->setSelectAccess();
      stoi_->setInsertAccess();
      stoi_->setUpdateAccess();
      stoi_->setDeleteAccess();
      break;
    default:
      CMPASSERT(FALSE);
  }

  NABoolean validateTS = TRUE;

  if ((naTable->getClusteringIndex() &&
       naTable->getClusteringIndex()->isSystemTable()) ||
      (NOT validateTS))
    stoi_->setValidateTimestamp(FALSE);
  else
    stoi_->setValidateTimestamp(TRUE);


  // MV --
  // For INTERNAL REFRESH statements, leave only the insert on the MV itself.
  if (re->getInliningInfo().isAvoidSecurityCheck() ||
      (bindWA->isBindingMvRefresh() &&
       (!naTable->isAnMV() || !stoi_->getInsertAccess())))
  {
    return NULL;
  }

  
  // In a SCAN, only the topmost view is inserted into BindWA StoiList
  // (thus there will be no security check on underlying views/basetables,
  // as Ansi says there shouldn't).
  if (re->getOperatorType() == REL_SCAN && bindWA->viewCount())
  {
    return NULL;
  }

  // Genesis 10-980306-4309:
  // Ansi says not supposed to be any security check on referenced tables,
  // nor of course on indexes, RIs and temp tables which are not an Ansi
  // notion to begin with.
  if ((naTable->getSpecialType() == ExtendedQualName::TRIGTEMP_TABLE) ||
      (naTable->getSpecialType() == ExtendedQualName::IUD_LOG_TABLE) ||
      (naTable->getSpecialType() == ExtendedQualName::INDEX_TABLE) ||
      (naTable->getSpecialType() == ExtendedQualName::RESOURCE_FORK))
  {
    return NULL;
  }

  if (noSecurityCheck)
  {
    return NULL;
  }

  if (re->getOperator().match(REL_ANY_GEN_UPDATE)&& 
      (((GenericUpdate*)re)->getUpdateCKorUniqueIndexKey()))
  {
    return NULL;
  }

  OptSqlTableOpenInfo *stoiInList = NULL;

  for (CollIndex i=0; i < bindWA->getStoiList().entries(); i++)
    if (strcmp(bindWA->getStoiList()[i]->getStoi()->fileName(), fileName) == 0) {
      stoiInList = bindWA->getStoiList()[i];
      break;
    }
  
  if (!stoiInList) {
    stoiInList =
      new(bindWA->wHeap()) OptSqlTableOpenInfo(
					       new (bindWA->wHeap()) SqlTableOpenInfo(*stoi_),
					       corrName,
					       bindWA->wHeap());
    
    stoiInList->setTable((NATable*)naTable);
    bindWA->getStoiList().insert(stoiInList);

    bindWA->hbaseColUsageInfo()->insert((QualifiedName*)&naTable->getTableName());

  } else {
    // This is conceptually equivalent to
    //	stoiInList->AccessFlags |= stoi_->AccessFlags :
    if (stoi_->getInsertAccess()) stoiInList->getStoi()->setInsertAccess();
    if (stoi_->getUpdateAccess()) stoiInList->getStoi()->setUpdateAccess();
    if (stoi_->getDeleteAccess()) stoiInList->getStoi()->setDeleteAccess();
    if (stoi_->getSelectAccess()) stoiInList->getStoi()->setSelectAccess();
  }
  
  return stoiInList;
  
} // setupStoi()

//----------------------------------------------------------------------------
RelExpr *Scan::bindNode(BindWA *bindWA)
{
  if (nodeIsBound())
  {
    bindWA->getCurrentScope()->setRETDesc(getRETDesc());
      return this;
  }

  // -- Triggers
  // Is this a Scan on a temporary table inside the action of a statement trigger?
  if (getTableName().isATriggerTransitionName(bindWA))
    return buildTriggerTransitionTableView(bindWA); // Located in Inlining.cpp

  // -- MV
  // Is this a Scan on a log inside the select statement of a Materialized View?
  // If so - maybe we need to replace this Scan with some other RelExpr tree.
  // Ignore when inDDL() because the log may not exist yet.
  if (!bindWA->inDDL() &&
      getTableName().getSpecialType() == ExtendedQualName::NORMAL_TABLE)
  {
    const MvBindContext *pMvBindContext = bindWA->getClosestMvBindContext();
    if (NULL != pMvBindContext)
    {
      RelExpr *replacementTree =
        pMvBindContext->getReplacementFor(getTableName().getQualifiedNameObj());

      if (replacementTree != NULL)
      {
        // We need to replace the Scan on the base table by some other tree.
        // Make sure this tree has the same name as the Scan.
        const CorrName& baseCorrName = getTableName();
        replacementTree = new(bindWA->wHeap())
          RenameTable(TRUE, replacementTree, baseCorrName);

        // Move any selection predicates on the Scan to the tree.
        replacementTree->addSelPredTree(removeSelPredTree());

        // Bind the tree and return instead of the tree.
        return replacementTree->bindNode(bindWA);
      }
    }
  }

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

  // Get the NATable for this object.
  //
  NATable *naTable = bindWA->getNATable(getTableName());
  if (bindWA->errStatus()) 
    return this;

  // Set up stoi.  bindWA->viewCount is altered during expanding the view.
  setupStoi(stoi_, bindWA, this, naTable, getTableName(), noSecurityCheck());

  // If the object is a view, expand the view.
  //
  if (naTable->getViewText()) {

    // Allow view on exception_table or any other special_table_name objects  
    ComBoolean specialTableFlagOn = Get_SqlParser_Flags(ALLOW_SPECIALTABLETYPE);
    if (specialTableFlagOn == FALSE)
    {
        Set_SqlParser_Flags(ALLOW_SPECIALTABLETYPE);
        SQL_EXEC_SetParserFlagsForExSqlComp_Internal(ALLOW_SPECIALTABLETYPE);
    }

    RelExpr * boundView = bindWA->bindView(getTableName(),
                            naTable,
                            accessOptions(),
                            removeSelPredTree(),
                            getGroupAttr(),
                            TRUE/*catmanCollectUsages*/);

    // QSTUFF
    // First we checked whether its a view and if so it must be updatable
    // when using it for stream access or an embedded update or delete
    if (!naTable->isUpdatable() && getGroupAttr()->isEmbeddedUpdateOrDelete()){
      *CmpCommon::diags() << DgSqlCode(-4206)
        << DgTableName(naTable->getTableName().getQualifiedNameAsAnsiString())
        << (getGroupAttr()->isEmbeddedUpdate() ?
        DgString0("UPDATE") : DgString0("DELETE"));
      bindWA->setErrStatus();

//    restore ALLOW_SPECIALTABLETYPE setting
      if (specialTableFlagOn == FALSE)
          Reset_SqlParser_Flags(ALLOW_SPECIALTABLETYPE);
      return NULL;
    }

    if (!naTable->isUpdatable() && getGroupAttr()->isStream()){
      *CmpCommon::diags() << DgSqlCode(-4151)
        << DgTableName(naTable->getTableName().getQualifiedNameAsAnsiString());
      bindWA->setErrStatus();
      if (specialTableFlagOn == FALSE) 
          Reset_SqlParser_Flags(ALLOW_SPECIALTABLETYPE);
      return NULL;
    }


    // Second we make sure the the underlying base table is key sequenced
    // in case of embedded d/u and streams
    if (boundView->getLeftmostScanNode()) {
      // this is not a "create view V(a) as values(3)" kind of a view
      const NATable * baseTable =
        boundView->getLeftmostScanNode()->getTableDesc()->getNATable();

      if (getGroupAttr()->isStream()) {
        if (!baseTable->getClusteringIndex()->isKeySequenced()) {
          *CmpCommon::diags() << DgSqlCode(-4204)
            << DgTableName(
                 baseTable->getTableName().getQualifiedNameAsAnsiString());
          bindWA->setErrStatus();
          if (specialTableFlagOn == FALSE)
            Reset_SqlParser_Flags(ALLOW_SPECIALTABLETYPE);

          return NULL;
        }
      }

      if (getGroupAttr()->isEmbeddedUpdateOrDelete()){
        if (!baseTable->getClusteringIndex()->isKeySequenced()){
          *CmpCommon::diags() << DgSqlCode(-4205)
            << DgTableName(
                 baseTable->getTableName().getQualifiedNameAsAnsiString())
            << (getGroupAttr()->isEmbeddedUpdate() ?
                DgString0("UPDATE") : DgString0("DELETE"));
          bindWA->setErrStatus();
          if (specialTableFlagOn == FALSE)
            Reset_SqlParser_Flags(ALLOW_SPECIALTABLETYPE);

          return NULL;
        }
      }
    }
    // QSTUFF

//    restore ALLOW_SPECIALTABLETYPE setting
    if (specialTableFlagOn == FALSE)
        Reset_SqlParser_Flags(ALLOW_SPECIALTABLETYPE);

    return boundView;
  }


  // -- MV
  // If this is the expanded tree pass during CREATE MV, expand the MV into
  // its SELECT tree, just like a regular view.
  // Do this only for incremental MVs, otherwise they may introduce unsupported
  // operators such as Union.
  if (naTable->isAnMV() && 
      bindWA->isExpandMvTree() &&
      naTable->getMVInfo(bindWA)->isIncremental())
  {
    CMPASSERT(bindWA->inDDL());
    return bindExpandedMaterializedView(bindWA, naTable);
  }

  // Do not allow to select from an un initialized MV
  if (naTable->isAnMV() && !bindWA->inDDL() && !bindWA->isBindingMvRefresh())
  {
    if (naTable->verifyMvIsInitializedAndAvailable(bindWA))
      return NULL;
  }

  // Allocate a TableDesc and attach it to the Scan node.
  // This call also allocates a RETDesc, attached to the BindScope,
  // which we want to attach also to the Scan.
  //
  // disable override schema for synonym
  NABoolean os = FALSE;
  if ( ( bindWA->overrideSchemaEnabled() ) 
    && ( ! naTable->getSynonymReferenceName().isNull() ) )
  { 
    os = bindWA->getToOverrideSchema();
    bindWA->setToOverrideSchema(FALSE);  
  }

  TableDesc * tableDesc = NULL;

  if ((NOT isHbaseScan()) || (! getTableDesc()))
    {
      tableDesc = bindWA->createTableDesc(naTable, getTableName(), 
					  FALSE, getHint());
    }
  else
    tableDesc = getTableDesc();

  // restore override schema setting
  if ( ( bindWA->overrideSchemaEnabled() ) 
    && ( ! naTable->getSynonymReferenceName().isNull() ) )
    bindWA->setToOverrideSchema(os);  

  // before attaching set the selectivity hint defined by the user for this
  // table

  if (tableDesc && getHint() &&
      getTableName().getSpecialType() == ExtendedQualName::NORMAL_TABLE)
  {
    double s;
    s = getHint()->getSelectivity();
    if (0.0 <= s && s <= 1.0) {
      SelectivityHint *selHint = new (STMTHEAP) SelectivityHint();
      selHint->setScanSelectivityFactor(s);
      tableDesc->setSelectivityHint(selHint);
    }
    if (getHint()->getCardinality() >= 1.0) {
      s = getHint()->getCardinality();
      CostScalar scanCard(s);
      if((scanCard.getValue() - floor(scanCard.getValue())) > 0.00001)
        scanCard = ceil(scanCard.getValue());

      CardinalityHint *cardHint = new (STMTHEAP) CardinalityHint();
      cardHint->setScanCardinality(scanCard);
      tableDesc->setCardinalityHint(cardHint);
    }
  }

  setTableDesc(tableDesc);
  if (bindWA->errStatus()) return this;
  setRETDesc(bindWA->getCurrentScope()->getRETDesc());

  if ((CmpCommon::getDefault(ALLOW_DML_ON_NONAUDITED_TABLE) == DF_OFF) &&
      (naTable && naTable->getClusteringIndex() && !naTable->getClusteringIndex()->isAudited()))
  {
     *CmpCommon::diags() << DgSqlCode(-4211)
       << DgTableName(
           naTable->getTableName().getQualifiedNameAsAnsiString());
     bindWA->setErrStatus();
     return NULL;
  }
 
  // restricted partitions for HBase table
  if (naTable->isHbaseTable() &&
      (naTable->isPartitionNameSpecified() ||
       naTable->isPartitionRangeSpecified()))
    {
      PartitioningFunction * partFunc = naTable->getClusteringIndex()->getPartitioningFunction();

      // find the salt column and apply a predicate on the salt column.
      // For Hash2, since the partittion key columns are columns used to build
      // the _SALT_ column, we need to search all columns for the _SALT_ column.
      const NAColumnArray &ccCols = 
           (partFunc && partFunc->castToHash2PartitioningFunction())?
            naTable->getClusteringIndex()->getAllColumns()
              :
            naTable->getClusteringIndex()->getPartitioningKeyColumns();

      NABoolean saltColFound = FALSE;

      for (CollIndex i=0; i<ccCols.entries() && !saltColFound; i++)
        {
          if (ccCols[i]->isComputedColumn() &&
              ccCols[i]->getColName() == 
              ElemDDLSaltOptionsClause::getSaltSysColName())
            {
              saltColFound = TRUE;
              // create a predicate "_SALT_" = <num> or
              // "_SALT_" between <num> and <num>
              Int32 beginPartNum = partFunc->getRestrictedBeginPartNumber() - 1;
              Int32 endPartNum = partFunc->getRestrictedEndPartNumber() - 1;
              
              // fill in defaults, indicated by -1 (-2 after subtraction above)
              if (beginPartNum < 0)
                beginPartNum = 0;
              if (endPartNum < 0)
                endPartNum = partFunc->getCountOfPartitions() - 1;
              
              ItemExpr *partPred = NULL;
              ColReference *saltColRef = new(bindWA->wHeap()) ColReference(
                   new(bindWA->wHeap()) ColRefName(
                        ccCols[i]->getFullColRefName(), bindWA->wHeap()));
              
              if (beginPartNum == endPartNum)
                {
                  partPred = new(bindWA->wHeap()) BiRelat
                    (ITM_EQUAL,
                     saltColRef,
                     new(bindWA->wHeap()) ConstValue(beginPartNum,bindWA->wHeap()));
                }
              else
                {
                  partPred = new(bindWA->wHeap()) Between
                    (saltColRef,
                     new(bindWA->wHeap()) ConstValue(beginPartNum,bindWA->wHeap()),
                     new(bindWA->wHeap()) ConstValue(endPartNum,bindWA->wHeap()));
                }
              
              ItemExpr *newSelPred = removeSelPredTree();
              if (newSelPred)
                newSelPred = new(bindWA->wHeap()) BiLogic(ITM_AND,
                                                          newSelPred,
                                                          partPred);
              else
                newSelPred = partPred;
              
              // now add the partition predicates
              addSelPredTree(newSelPred->bindNode(bindWA));
            }
        }
      
      if (!saltColFound)
        {
          // not allowed to select individual partitions from HBase tables
          // unless they are salted
          char buf[20];
          snprintf(buf, 20, "%d", partFunc->getRestrictedBeginPartNumber());
          *CmpCommon::diags() << DgSqlCode(-1276)
                              << DgString0(buf)
                              << DgTableName(
                                   naTable->getTableName().getQualifiedNameAsAnsiString());
          bindWA->setErrStatus();
          return NULL;
        }
    }

   if (naTable->isHiveTable() && 
       !(naTable->getClusteringIndex()->getHHDFSTableStats()->isOrcFile() ||
	 naTable->getClusteringIndex()->getHHDFSTableStats()
	 ->isSequenceFile()) &&
       (CmpCommon::getDefaultNumeric(HDFS_IO_BUFFERSIZE_BYTES) == 0) && 
       (naTable->getRecordLength() >
	CmpCommon::getDefaultNumeric(HDFS_IO_BUFFERSIZE)*1024))
     {
       // do not raise error if buffersize is set though buffersize_bytes.
       // Typically this setting is used for testing alone.
       *CmpCommon::diags() << DgSqlCode(-4226)
			   << DgTableName(
					  naTable->getTableName().
					  getQualifiedNameAsAnsiString())
			   << DgInt0(naTable->getRecordLength());
       bindWA->setErrStatus();
       return NULL;
     }
  // Bind the base class.
  //
  RelExpr *boundExpr = bindSelf(bindWA);
  if (bindWA->errStatus()) return this;
  //
  // Assign the set of columns that belong to the table to be scanned
  // as the output values that can be produced by this scan.
  //
  getGroupAttr()->addCharacteristicOutputs(getTableDesc()->getColumnList());
  getGroupAttr()->addCharacteristicOutputs(getTableDesc()->hbaseTSList());

   // MV --
  if (getInliningInfo().isMVLoggingInlined())
    projectCurrentEpoch(bindWA);

  // QSTUFF
  // Second we make sure the the underlying base table is key sequenced in case
  // of embedded d/u and streams
  if (getGroupAttr()->isStream()){

    if (!naTable->getClusteringIndex()->isKeySequenced() ||
        naTable->hasVerticalPartitions()){
      *CmpCommon::diags() << DgSqlCode(-4204)
        << DgTableName(naTable->getTableName().getQualifiedNameAsAnsiString());
      bindWA->setErrStatus();
      return NULL;
    }
    if (!getTableDesc()->getClusteringIndex()->getNAFileSet()->isAudited()) {
      // Stream access not allowed on a non-audited table
      *CmpCommon::diags() << DgSqlCode(-4215)
        << DgTableName(
            naTable->getTableName().getQualifiedNameAsAnsiString());
      bindWA->setErrStatus();
      return NULL;
    }
  }

  if (getGroupAttr()->isEmbeddedUpdateOrDelete()){
    if (!naTable->getClusteringIndex()->isKeySequenced()
      || naTable->hasVerticalPartitions()){
      *CmpCommon::diags() << DgSqlCode(-4205)
        << DgTableName(naTable->getTableName().getQualifiedNameAsAnsiString())
        << (getGroupAttr()->isEmbeddedUpdate() ?
            DgString0("UPDATE") : DgString0("DELETE"));
      bindWA->setErrStatus();
      return NULL;
    }
  }
  // QSTUFF

  // Fix "browse access mode incorrectly starts transaction" genesis case
  // 10-021111-1080. Here's a glimpse at what may have been the original
  // intent of the old code (taken from RelExpr.h comment for the now
  // defunct RelExpr::propagateAccessOptions):
  //
  // At parse time, user can specify statement level access options.
  // (See SQL/ARK Language spec). These options are attached to the
  // RelRoot node and could be different for different Scans in the query.
  // All Scan and Update nodes under a RelRoot have the same Access
  // type and the Lock Mode.
  //
  // The problem is propagateAccessOptions did not visit all the Scans,
  // eg, it did not propagate to subquery Scans, and it did not propagate
  // to internal RelRoots. This "push" model seems harder to understand
  // and to do correctly.
  //
  // So, we go with the "pull" model. An interesting node such as a Scan,
  // GenericUpdate, RelRoot that needs a user-specified access/lock mode
  // can "pull" one from BindWA. BindWA already implements SQL scoping
  // and visibility rules. It's easier to explain also. Each table
  // reference inherits the user-specified access/lock mode of the
  // nearest SQL scope, going from the table outwards. If the entire
  // query has no user-specified access/lock mode, then it uses the
  // session-level default access/lock mode.
  //
  // if we have no user-specified access options then
  // get it from nearest enclosing scope that has one (if any)
  if (!accessOptions().userSpecified()) {
    StmtLevelAccessOptions *axOpts = bindWA->findUserSpecifiedAccessOption();
    if (axOpts) {
      accessOptions() = *axOpts;
    }
  }
  // The above code is in RelRoot::bindNode also.
  // It would be nice to refactor this common code; someday.

  // See Halloween handling code in GenericUpdate::bindNode
  if (accessOptions().userSpecified()) {
    if ( accessOptions().accessType() == REPEATABLE_ ||
         accessOptions().accessType() == STABLE_     ||
         accessOptions().accessType() == BROWSE_
      ) {
        naTable->setRefsIncompatibleDP2Halloween();
    }
  }
  else {
    TransMode::IsolationLevel il = CmpCommon::transMode()->getIsolationLevel();
    if((CmpCommon::transMode()->ILtoAT(il) == REPEATABLE_ ) ||
       (CmpCommon::transMode()->ILtoAT(il) == STABLE_     ) ||
       (CmpCommon::transMode()->ILtoAT(il) == BROWSE_     )) {
        naTable->setRefsIncompatibleDP2Halloween();
    }
  }

  const NAString * tableLockVal = 
      ActiveControlDB()->getControlTableValue(
            getTableName().getUgivenName(), "TABLELOCK");
  if (*tableLockVal == "ON")
        naTable->setRefsIncompatibleDP2Halloween();

  //Embedded update/delete queries on partitioned table
  //generates assertion when ATTEMPT_ASYNCHRONOUS_ACCESS
  //flag is OFF.This is because split operator is used.
  //Removing of split top operator causes some problems.
  //Error 66 from file system is one of them.
  //So, for now compiler will generate error if these
  //conditions occur.
  if (getGroupAttr()->isEmbeddedUpdateOrDelete() &&
       naTable->getClusteringIndex()->isPartitioned() &&
       (CmpCommon::getDefault(ATTEMPT_ASYNCHRONOUS_ACCESS) == DF_OFF)) {

     *CmpCommon::diags() << DgSqlCode(-4321)
       << DgTableName(naTable->getTableName().getQualifiedNameAsAnsiString());
     bindWA->setErrStatus();
     return NULL;
  }
  // Stream access not allowed on a multi-partioned access paths, when
  // CQD ATTEMPT_ASYNCHRONOUS_ACCESS is set to OFF.If we find 
  // that all access paths are partitioned we give an error.

   if (getGroupAttr()->isStream() &&
      (CmpCommon::getDefault(ATTEMPT_ASYNCHRONOUS_ACCESS) == DF_OFF)) {
    NABoolean atleastonenonpartitionedaccess = FALSE;
    NAFileSetList idescList = naTable->getIndexList();
 
    for(CollIndex i = 0; 
        i < idescList.entries() && !atleastonenonpartitionedaccess; i++)
       if(!(idescList[i]->isPartitioned()) )
        atleastonenonpartitionedaccess = TRUE;
 
    if (!atleastonenonpartitionedaccess) {
     *CmpCommon::diags() << DgSqlCode(-4320)
       << DgTableName(naTable->getTableName().getQualifiedNameAsAnsiString());
     bindWA->setErrStatus();
     return NULL;
    }
  }

   if (hbaseAccessOptions_)
     {
       if (hbaseAccessOptions_->isMaxVersions())
         {
           hbaseAccessOptions_->setHbaseVersions
             (
              getTableDesc()->getClusteringIndex()->getNAFileSet()->numMaxVersions()
              );
         }
     }

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

//----------------------------------------------------------------------------
RelExpr *Scan::bindExpandedMaterializedView(BindWA *bindWA, NATable *naTable)
{
  CollHeap *heap = bindWA->wHeap();
  MVInfoForDML *mvInfo = naTable->getMVInfo(bindWA);
  QualifiedName mvName(mvInfo->getNameOfMV(), 3, heap, bindWA);
  CorrName mvCorrName(mvName, heap, getTableName().getCorrNameAsString());

  RelExpr *viewTree = mvInfo->buildMVSelectTree();
  viewTree = new(heap) RenameTable(TRUE, viewTree, mvCorrName);
  viewTree->addSelPredTree(removeSelPredTree());
  RelExpr *boundExpr = viewTree->bindNode(bindWA);
  if (bindWA->errStatus())
    return this;

  if (naTable->getClusteringIndex()->hasSyskey())
  {
    // In case the MV on top of this MV is an MJV, it needs the SYSKEY
    // column of this MV. Since the SYSKEY column is not projected from
    // the select list of this MV, just fake it. It's value will never be
    // used anyway - just it's existance.
    ConstValue *dummySyskey = new(heap) ConstValue(0);
    dummySyskey->changeType(new(heap) SQLLargeInt());
    ItemExpr *dummySyskeyCol = dummySyskey->bindNode(bindWA);
    if (bindWA->errStatus())
      return this;

    ColRefName syskeyName("SYSKEY", mvCorrName);
    boundExpr->getRETDesc()->addColumn(bindWA,
                                       syskeyName,
                                       dummySyskeyCol->getValueId(),
                                       SYSTEM_COLUMN);
  }

  bindWA->getCurrentScope()->setRETDesc(boundExpr->getRETDesc());
  return boundExpr;
}

//----------------------------------------------------------------------------
// This Scan needs to project the CurrentEpoch column.
// Create and bind the CurrentEpoch function
void Scan::projectCurrentEpoch(BindWA *bindWA)
{
  ItemExpr *currEpoch =
    new(bindWA->wHeap()) GenericUpdateOutputFunction(ITM_CURRENTEPOCH);
  currEpoch->bindNode(bindWA);

  // Add it to the RETDesc
  ColRefName virtualColName(InliningInfo::getEpochVirtualColName());
  getRETDesc()->addColumn(bindWA, virtualColName, currEpoch->getValueId());

  // And force the generator to project it even though it is not
  // a column in the IndexDesc.
  ValueIdSet loggingCols;
  loggingCols.insert(currEpoch->getValueId());
  setExtraOutputColumns(loggingCols);
}

// -----------------------------------------------------------------------
// methods for class Tuple
// -----------------------------------------------------------------------

// Genesis 10-990226-4329 and 10-000221-6676.
static RelExpr *checkTupleElementsAreAllScalar(BindWA *bindWA, RelExpr *re)
{
  if (!re) return NULL;
  RETDesc *rd = re->getRETDesc();
  CMPASSERT(rd);

  // an empty tuple is okay (dummy for Triggers, e.g.)
  const ColumnDescList &cols = *rd->getColumnList();
  for (CollIndex i = cols.entries(); i--; ) {
    ColumnDesc *col = cols[i];
    Subquery *subq = (Subquery *)cols[i]->getValueId().getItemExpr();
    if (subq->isASubquery()) {
      if (cols.entries() > 1 && subq->getDegree() > 1) {
        // 4125 The select list of a subquery in a VALUES clause must be scalar.
        *CmpCommon::diags() << DgSqlCode(-4125);
        bindWA->setErrStatus();
        return NULL;
      }      
      else if (cols.entries() == 1) {  // if cols.entries() > 1 && subq->getDegree() > 1
          // we do not want to make the transformation velow. We want to keep the 
         // values clause, so that it cann be attached by a tsj to the subquery 
        // during transform.
        CMPASSERT(subq->isARowSubquery());
        if (CmpCommon::getDefault(COMP_BOOL_137) == DF_ON)
        {
          ValueIdList subqSelectList;
          RETDesc *subqRD = subq->getSubquery()->getRETDesc()->nullInstantiate(
            bindWA, TRUE/*forceCast for GenRelGrby*/, subqSelectList);
          subq->getSubquery()->setRETDesc(subqRD);
          ItemExpr *agg = new(bindWA->wHeap())
            Aggregate(ITM_ONE_ROW, subqSelectList.rebuildExprTree());
          RelExpr * gby = new(bindWA->wHeap())
            GroupByAgg(subq->getSubquery(), REL_GROUPBY, NULL, agg);
          NABoolean save = bindWA->getCurrentScope()->context()->inTupleList();
          bindWA->getCurrentScope()->context()->inTupleList() = TRUE;
          gby = gby->bindNode(bindWA);
          bindWA->getCurrentScope()->context()->inTupleList() = save;
          return gby;
        }
        else
        {
          return subq->getSubquery();
        }

      }
    }
  }
  return re;
}

RelExpr *Tuple::bindNode(BindWA *bindWA)
{
  if (nodeIsBound())
  {
    bindWA->getCurrentScope()->setRETDesc(getRETDesc());
    return this;
  }
  
  // Used by rowsets. We search for occurrences of arrays within this node to
  // replace them with scalar variables
  
  if (bindWA->getHostArraysArea() && !bindWA->getHostArraysArea()->done()) 
    {
      RelExpr *boundExpr = bindWA->getHostArraysArea()->modifyTupleNode(this);

      if (boundExpr)
        return checkTupleElementsAreAllScalar(bindWA, boundExpr);
    }

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

  // Detach the item expression tree for the value list and bind it.
  // We use counterForRowValues() and pass in parent, for DEFAULT processing
  // (Ansi 7.1 SR 1).
  //
  CollIndex counterRowVals = 0;
  CMPASSERT(!bindWA->getCurrentScope()->context()->counterForRowValues());
  bindWA->getCurrentScope()->context()->counterForRowValues() = &counterRowVals;
  //
  setRETDesc(bindRowValues(bindWA, removeTupleExprTree(), tupleExpr(), this, FALSE));
  if (bindWA->errStatus()) return this;
  //
  bindWA->getCurrentScope()->context()->counterForRowValues() = NULL;

  // Do NOT set currently scoped RETDesc to this VALUES(...) RETDesc --
  // makes  "select * from t where ((values(1)),a) = (1,2);"
  // fail with error 4001 "column A not found, no named tables in scope"
  //
  //	bindWA->getCurrentScope()->setRETDesc(getRETDesc());

  // Bind the base class.
  //
  RelExpr *boundExpr = bindSelf(bindWA);
  // -- Trigger
  if (bindWA->errStatus()) return this;

  //
  //for case 10-020716-5497
  RelExpr *newExpr = checkTupleElementsAreAllScalar(bindWA, boundExpr);

  //before doing anything with newExpr make sure it is not null it can
  //be null if there is an error incheckTupleElementsAreAllScalar.

  getGroupAttr()->addCharacteristicOutputs(tupleExpr());

  return newExpr;
} // Tuple::bindNode()

// -----------------------------------------------------------------------
// methods for class TupleList
// -----------------------------------------------------------------------

RelExpr *TupleList::bindNode(BindWA *bindWA)
{
  if (nodeIsBound())
  {
    bindWA->getCurrentScope()->setRETDesc(getRETDesc());
    return this;
  }

  RelExpr * boundExpr = NULL;
  bindChildren(bindWA);
  if (bindWA->errStatus()) return this;

  ExprValueId eVid(tupleExprTree());
  ItemExprTreeAsList tupleList(&eVid, ITM_ITEM_LIST);
  NABoolean castTo = castToList().entries() > 0;

  if (tupleExprTree()->containsSubquery() ||
      tupleExprTree()->containsUDF() 
      #ifndef NDEBUG
      ||
      getenv("UNIONED_TUPLES")
      #endif
     ) {

    // Make a union'ed tree of all the tuples in tupleList.	##
    // This is done coz TupleList doesn't handle transformation	##
    // of subqueries in tuples correctly yet.			##
    CollIndex nTupleListEntries = (CollIndex)tupleList.entries();
    for (CollIndex i = 0; i < nTupleListEntries ; i++) {

      ItemExpr *ituple = tupleList[i]->child(0)->castToItemExpr();
      RelExpr  *rtuple = new(bindWA->wHeap()) Tuple(ituple);
      rtuple = rtuple->bindNode(bindWA);
      if (bindWA->errStatus()) return this;

      // If INSERTing a TupleList, make some Assign's (even tmp's work!)
      // to do some error-checking for MP-NCHAR-as-single-byte target columns.
      //
      // Similar code exists in
      // (a) the loop further down, (b) TupleList::codeGen()
      // and yes, it needs to be in all three places.
      //
      // NOTE:  tmpAssign MUST BE ON HEAP --
      //   Cannot be done with a stack-allocated tmpAssign
      //   because ItemExpr destructor will delete children,
      //   which we (and parent) are still referencing!
      if (castTo) {
        const ColumnDescList &itms = *rtuple->getRETDesc()->getColumnList();
        for (CollIndex j = 0; j < (CollIndex)itms.entries(); j++) {
          ValueId src = itms[j]->getValueId();

          Assign *tmpAssign = new(bindWA->wHeap())
            Assign(castToList()[j].getItemExpr(), src.getItemExpr());
          tmpAssign = (Assign *)tmpAssign->bindNode(bindWA);
          if (bindWA->errStatus()) return this;
        }
      }

      if (!boundExpr)
        boundExpr = rtuple;
      else
        boundExpr = new(bindWA->wHeap()) Union(boundExpr, rtuple);
    } // for loop over tupleList

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

  } // containsSubquery

  // Detach the item expression tree for the value list and bind it.
  // We use counterForRowValues() and pass in parent, for DEFAULT processing
  // (Ansi 7.1 SR 1).
  //
  CollIndex counterRowVals = 0;
  CMPASSERT(!bindWA->getCurrentScope()->context()->counterForRowValues());
  bindWA->getCurrentScope()->context()->counterForRowValues() = &counterRowVals;

  // tupleExprTree() contains a list of tuples.
  // Each tuple is also a list of values (this list may contain one item).
  // Bind all values in all the tuples.
  // Check that the number of elements in each tuple is the same,
  // and that the types of corresponding elements are compatible.
  //
  numberOfTuples_ = tupleList.entries();
  CollIndex prevTupleNumEntries = NULL_COLL_INDEX;

  // A list of ValueIdUnions nodes.  Will create as many as there are
  // entries in each tuple.  The valIds from corresponding elements of
  // the tuples will be added so that each ValueIdUnion represents a
  // column of the tuple virtual table.  Used to determine the
  // union-compatible type to be used for the result type produced by
  // the tuplelist.
  // 
  ItemExprList vidUnions(bindWA->wHeap());
  ValueIdUnion *vidUnion;

  CollIndex i = 0;
  CollIndex nEntries = (CollIndex)tupleList.entries() ;
  for (i = 0; i < nEntries ; i++) {

    counterRowVals = 0;

    ValueIdList vidList;
    ItemExpr *tuple = tupleList[i]->child(0)->castToItemExpr();
    tuple->convertToValueIdList(vidList, bindWA, ITM_ITEM_LIST, this);
    if (bindWA->errStatus())
      return NULL;

    if (prevTupleNumEntries == NULL_COLL_INDEX) {
      prevTupleNumEntries = vidList.entries();
    }
    else if (prevTupleNumEntries != vidList.entries()) {
      // 4126 The row-value-ctors of a VALUES must be of equal degree.
      *CmpCommon::diags() << DgSqlCode(-4126);
      bindWA->setErrStatus();
      return NULL;
    }

    // Genesis 10-980611-7153
    if (castTo && prevTupleNumEntries != castToList().entries()) break;

    for (CollIndex j = 0; j < prevTupleNumEntries; j++) {
      // If any unknown type in the tuple, coerce it to the target type.
      // Also do same MP-NCHAR magic as above.
      if (castTo) {
        ValueId src = vidList[j];
        src.coerceType(castToList()[j].getType());

        // tmpAssign MUST BE ON HEAP -- see note above!
        Assign *tmpAssign = new(bindWA->wHeap())
          Assign(castToList()[j].getItemExpr(), src.getItemExpr());
        tmpAssign = (Assign *)tmpAssign->bindNode(bindWA);
        if (bindWA->errStatus()) 
          return this;

      }
 
      if(i == 0) {
        ValueIdList vids;

        // Create an empty ValueIdUnion.  Will create as many as there
        // are entries in each tuple.  Add the valIds from
        // corresponding elements of the tuples so that each
        // ValueIdUnion represents a column of the tuple virtual
        // table.
        //
        vidUnion = new(bindWA->wHeap()) 
          ValueIdUnion(vids, NULL_VALUE_ID);

        vidUnion->setWasDefaultClause(TRUE);

        vidUnions.insertAt(j, vidUnion);
      }

      // Add the valIds from corresponding elements of the tuples so
      // that each ValueIdUnion represents a column of the tuple
      // virtual table.
      //
      vidUnion = (ValueIdUnion *)vidUnions[j];
      vidUnion->setSource((Lng32)i, vidList[j]);
        
      if (NOT vidList[j].getItemExpr()->wasDefaultClause())
        vidUnion->setWasDefaultClause(FALSE);
    } // for loop over entries in tuple

  } // for loop over tupleList

  if (castTo && prevTupleNumEntries != castToList().entries()) 
  {

    // 4023 degree of row value constructor must equal that of target table
    *CmpCommon::diags() << DgSqlCode(-4023)
                        << DgInt0((Lng32)prevTupleNumEntries)
                        << DgInt1((Lng32)castToList().entries());
    bindWA->setErrStatus();
    return NULL;
  }

  // do INFER_CHARSET fixup
  if (!doInferCharSetFixup(bindWA, CharInfo::ISO88591, prevTupleNumEntries, 
                           tupleList.entries())) {
    return NULL;
  }

  ItemExpr * outputList = NULL;
  for (CollIndex j = 0; j < prevTupleNumEntries; j++) {

    // Get the ValueIdUnion node corresponding to this column of the
    // tuple list virtual table
    //
    vidUnion = (ValueIdUnion *)vidUnions[j];

    if (castTo) {
      // Make sure the place holder type can support all the values in
      // the tuple list and target column
      //
      vidUnion->setSource(numTuples(), castToList()[j]);
    }

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

    if (castTo) {
      // Check that the source and target types are compatible.
      //   Cannot be done with a stack-allocated tmpAssign
      //   because ItemExpr destructor will delete children,
      //   which we (and parent) are still referencing!
      Assign *tmpAssign = new(bindWA->wHeap())
        Assign(castToList()[j].getItemExpr(), vidUnion);

      if ( CmpCommon::getDefault(ALLOW_IMPLICIT_CHAR_CASTING) == DF_ON )
      {
        tmpAssign->tryToDoImplicitCasting(bindWA);
      }
      const NAType *targetType = tmpAssign->synthesizeType();
      if (!targetType) {
        bindWA->setErrStatus();
        return NULL;
      }
    }
  

    NAType *phType = vidUnion->getValueId().getType().newCopy(bindWA->wHeap());

    NATypeToItem *placeHolder = new(bindWA->wHeap()) NATypeToItem(phType);

    Cast * cnode;
    if (castTo)
      {
        cnode = new(bindWA->wHeap()) Cast(placeHolder, phType, ITM_CAST, TRUE);
        if (vidUnion->getValueId().getItemExpr()->wasDefaultClause())
          cnode->setWasDefaultClause(TRUE);
      }
    else
      cnode = new(bindWA->wHeap()) Cast(placeHolder, phType);
    cnode->setConstFoldingDisabled(TRUE);
    cnode->bindNode(bindWA);

    if (!outputList)
      outputList = cnode;
    else
      outputList = new(bindWA->wHeap()) ItemList(outputList, cnode);
  }

  setRETDesc(bindRowValues(bindWA, outputList, tupleExpr(), this, FALSE));

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

  bindWA->getCurrentScope()->context()->counterForRowValues() = NULL;

  // Bind the base class.
  //
  boundExpr = bindSelf(bindWA);
  if (bindWA->errStatus()) return this;

   // need to add system columns as well....?

  NABoolean inSubquery = FALSE;
  BindScope *currScope   = bindWA->getCurrentScope();
  BindScope *prevScope   = bindWA->getPreviousScope(currScope);
  if (prevScope)
    inSubquery = prevScope->context()->inSubquery();

  if (inSubquery)
  {
    // need to change tupleExpr() & make it null-instantiated as RETDesc stores
    // null instantiated columns (most probably these are constants, but not
    // necessarily)

    const ColumnDescList *viewColumns = getRETDesc()->getColumnList();

    tupleExpr().clear();
    for (CollIndex k=0; k < viewColumns->entries(); k++)
    {
      ValueId vid = (*viewColumns)[k]->getValueId();

      // Special logic in Normalizer to optimize away a LEFT JOIN is not to
      // be explored there, as this is not a LEFT JOIN
      // Genesis case: 10-010312-1675
      // If the query were to be a LEFT JOIN, we would not be here
      if (vid.getItemExpr()->getOperatorType() == ITM_INSTANTIATE_NULL)

        {
          ((InstantiateNull *)vid.getItemExpr())->NoCheckforLeftToInnerJoin
                       = TRUE;
        }

      tupleExpr().insert(vid);
    }
  }
  getGroupAttr()->addCharacteristicOutputs(tupleExpr());

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

// set vidlist = ith tuple of this tuplelist and return TRUE
RelExpr* TupleList::getTuple
(BindWA *bindWA, ValueIdList& vidList, CollIndex i)
{
  ExprValueId eVid(tupleExprTree());
  ItemExprTreeAsList tupleList(&eVid, ITM_ITEM_LIST);
  ItemExpr *tuple = tupleList[i]->child(0)->castToItemExpr();
  tuple->convertToValueIdList(vidList, bindWA, ITM_ITEM_LIST, this);
  return bindWA->errStatus() ? NULL : this;
}

// set needsFixup to TRUE iff tuplelist needs INFER_CHARSET fixup
RelExpr*
TupleList::needsCharSetFixup(BindWA *bindWA, 
                             CollIndex arity, 
                             CollIndex nTuples,
                             NAList<NABoolean> &strNeedsFixup,
                             NABoolean &needsFixup)
{
  // assume it needs no INFER_CHARSET fixup until proven otherwise
  needsFixup = FALSE;
  if (CmpCommon::wantCharSetInference()) {
    CollIndex t, x;
    for (x = 0; x < arity; x++) { // initialize
      strNeedsFixup.insert(FALSE); 
    }
    // go thru tuplelist looking for unprefixed string literals
    for (t = 0; t < nTuples; t++) {
      // get tuple
      ValueIdList tup;
      if (!getTuple(bindWA, tup, t)) {
        return NULL; // something wrong
      } 
      else {
        // go thru columns of tuple looking for unprefixed string literals
        for (x = 0; x < arity; x++) {
          if (!strNeedsFixup[x] && tup[x].inferableCharType()) {
            strNeedsFixup[x] = TRUE;
            needsFixup = TRUE;
          }
        }
      }
    }
  }
  return this; // all OK
}

// find fixable strings' inferredCharTypes
RelExpr*
TupleList::pushDownCharType(BindWA *bindWA,
                            enum CharInfo::CharSet cs,
                            NAList<const CharType*> &inferredCharType,
                            NAList<NABoolean> &strNeedsFixup,
                            CollIndex arity, 
                            CollIndex nTuples)
{
  // mimic CharType::findPushDownCharType() logic
  const CharType* dctp = CharType::desiredCharType(cs);
  NAList<const CharType*> sampleCharType(CmpCommon::statementHeap(),arity);
  NAList<Int32> total(CmpCommon::statementHeap(),arity);
  NAList<Int32> ct   (CmpCommon::statementHeap(),arity);
  CollIndex t, x;
  for (x = 0; x < arity; x++) { // initialize
    total.insert(0);
    ct.insert(0);
    sampleCharType.insert(NULL);
  }
  // go thru tuplelist looking for fixable strings' inferredCharType
  for (t = 0; t < nTuples; t++) {
    // get tuple
    ValueIdList tup;
    if (!getTuple(bindWA, tup, t)) {
      return NULL; // something wrong
    }
    else {
      // go thru tuple looking for fixable strings' inferredCharType
      for (x = 0; x < arity; x++) {
        if (strNeedsFixup[x]) {
          total[x] += 1;
          const CharType *ctp;
          if (tup[x].hasKnownCharSet(&ctp)) {
            ct[x] += 1;
            if (sampleCharType[x] == NULL) {
              sampleCharType[x] = ctp;
            }
          }
        }
      }
    }
  }
  for (x = 0; x < arity; x++) {
    if (ct[x] == total[x]) { 
      // all have known char set or none need fixup
      inferredCharType.insert(NULL); // nothing to fix
    }
    else {
      inferredCharType.insert(sampleCharType[x] ? sampleCharType[x] : dctp);
    }
  }
  return this; // all OK
}

// do INFER_CHARSET fixup
RelExpr*
TupleList::doInferCharSetFixup(BindWA *bindWA,
                               enum CharInfo::CharSet cs,
                               CollIndex arity, 
                               CollIndex nTuples)
{
  NABoolean needsFixup;
  NAList<NABoolean> strNeedsFixup(CmpCommon::statementHeap(),arity);
  RelExpr *result = needsCharSetFixup
    (bindWA, arity, nTuples, strNeedsFixup, needsFixup);
  if (!result || // something went wrong
      !needsFixup) { // no INFER_CHARSET fixup needed
    return result;
  }
  else { // some string literal needs INFER_CHARSET fixup
    NAList<const CharType*> inferredCharType(CmpCommon::statementHeap(),arity);
    if (!pushDownCharType(bindWA, cs, inferredCharType, 
                          strNeedsFixup, arity, nTuples)) {
      return NULL; // something went wrong
    }
    else {
      // go thru tuplelist fixing up literals' char sets
      CollIndex t, x;
      for (t = 0; t < nTuples; t++) {
        // get tuple
        ValueIdList tup;
        if (!getTuple(bindWA, tup, t)) {
          return NULL; // something went wrong
        }
        else {
          // go thru tuple fixing up literals' char sets
          for (x = 0; x < arity; x++) {
            if (strNeedsFixup[x] && tup[x].inferableCharType()) {
              // coerce literal to have column's inferred char set
              tup[x].coerceType(*(inferredCharType[x]), NA_CHARACTER_TYPE);
            }
          }
        }
      }
    }
  }
  return this;
}

// -----------------------------------------------------------------------
// member functions for class RenameTable
// -----------------------------------------------------------------------

RelExpr *RenameTable::bindNode(BindWA *bindWA)
{
  if (nodeIsBound())
  {
    bindWA->getCurrentScope()->setRETDesc(getRETDesc()); // -- Triggers
    return this;
  }

  //
  // Create a new table name scope.
  //
  bindWA->getCurrentScope()->xtnmStack()->createXTNM();

  // code to enforce the specification that if an index expression is specified
  // with a rowset and the index is included in the derived table, the index
  // must be the last column of the derived column list
  if((getTableName().getCorrNameAsString() != "Rowset___") && (getArity() != 0))
    {
       if(child(0)->getOperatorType() == REL_ROWSET)
         {
           NAString indexExpr(bindWA->wHeap());
           NAString lastString("", bindWA->wHeap());
           ItemExpr *tempPtr;

           indexExpr = ((Rowset *)getChild(0))->getIndexName();
           if((indexExpr != "") && newColNamesTree_)
             {
                for (tempPtr = newColNamesTree_; tempPtr; tempPtr=tempPtr->child(1))
                  {
                     Int32 arity = tempPtr->getArity();
                     if(arity == 1)
                       {
                          lastString = ((RenameCol *)tempPtr)->getNewColRefName()->getColName();
                       }
                  }
                if(indexExpr != lastString)
                  {
                     *CmpCommon::diags() << DgSqlCode(-30012)
                              << DgString0(indexExpr)
                              << DgString1(getTableName().getCorrNameAsString());
                     bindWA->setErrStatus();
                     return NULL;
                  }
             }
         }
    }

  //
  // Bind the child nodes.
  //
  bindChildren(bindWA);
  if (bindWA->errStatus()) return this;

  //
  // Remove the table name scope.
  //
  bindWA->getCurrentScope()->xtnmStack()->removeXTNM();
  //
  // Create the result table.
  //
  RETDesc *resultTable = new (bindWA->wHeap()) RETDesc(bindWA);
  const RETDesc &sourceTable = *child(0)->getRETDesc();
  const CorrName &tableName = getTableName();
  ItemExpr *derivedColTree = removeColNameTree();
  ItemExprList derivedColList(bindWA->wHeap());
  const NAString *simpleColNameStr;
  CollIndex i;
  //
  // Check that there are an equal number of columns to values.
  //
  if (derivedColTree) {
    derivedColList.insertTree(derivedColTree);
    if (derivedColList.entries() != sourceTable.getDegree()) {
      // 4016 The number of derived columns must equal the degree of the derived table.
      *CmpCommon::diags() << DgSqlCode(-4016)
#pragma nowarn(1506)   // warning elimination
        << DgInt0(derivedColList.entries()) << DgInt1(sourceTable.getDegree());
#pragma warn(1506)  // warning elimination
      bindWA->setErrStatus();
      delete resultTable;
      return this;
    }
  }
  //
  // Insert the derived column names into the result table.
  // By ANSI 6.3 SR 6 (applies to explicit derived column list),
  // duplicate names are not allowed.
  // If user did not specify a derived column name list,
  // expose the select list's column names (implicit derived column list);
  // ANSI does not say that these cannot be duplicates --
  // if there's a later (i.e. in an outer scope) reference to a duplicately
  // named column, ColReference::bindNode will issue an error
  // (in particular, if all references are to constants, e.g. "count(*)",
  // then duplicates are not disallowed in the implicit derived column list!).
  //
  // When Create View DDL uses this Binder, we must enforce
  // ANSI 11.19 SR 8 + 9, clearly disallowing dups/ambigs
  // (and disallowing implem-dependent names, i.e. our unnamed '(expr)' cols!).
  //
  for (i = 0; i < sourceTable.getDegree(); i++) {
    //
    if (derivedColTree) {      // explicit derived column list
      CMPASSERT(derivedColList[i]->getOperatorType() == ITM_RENAME_COL);
      simpleColNameStr = &((RenameCol *) derivedColList[i])->
                                     getNewColRefName()->getColName();
      if (*simpleColNameStr != "") {   // named column, not an expression
        if (resultTable->findColumn(*simpleColNameStr)) {
          ColRefName errColName(*simpleColNameStr, tableName);
          // 4017 Derived column name $ColumnName was specified more than once.
          *CmpCommon::diags() << DgSqlCode(-4017)
            << DgColumnName(errColName.getColRefAsAnsiString());
          bindWA->setErrStatus();
          delete resultTable;
          return this;
        }
      }
    } else            // implicit derived column list
      simpleColNameStr = &sourceTable.getColRefNameObj(i).getColName();
    //
    ColRefName colRefName(*simpleColNameStr, tableName);
    ValueId valId = sourceTable.getValueId(i);
    resultTable->addColumn(bindWA, colRefName, valId);
  } // for-loop
  //
  // Insert system columns similarly, completely ignoring dup names.
  //
  const ColumnDescList &sysColList = *sourceTable.getSystemColumnList();
  for (i = 0; i < sysColList.entries(); i++) {
    simpleColNameStr = &sysColList[i]->getColRefNameObj().getColName();
    if (NOT resultTable->findColumn(*simpleColNameStr)) {
      ColRefName colRefName(*simpleColNameStr, tableName);
      ValueId valId = sysColList[i]->getValueId();   // (slight diff from the
      resultTable->addColumn(bindWA, colRefName, valId, SYSTEM_COLUMN);   //above)
    }
  }
  setRETDesc(resultTable);

  // MVs --
  // When binding INTERNAL REFRESH commands, the SYSKEY and @OP columns should
  // be propageted to the scope above, even when they are not specified in the
  // select list.
  if (bindWA->isPropagateOpAndSyskeyColumns())
    getRETDesc()->propagateOpAndSyskeyColumns(bindWA, FALSE);

  bindWA->getCurrentScope()->setRETDesc(resultTable);
  //
  // Insert the table name into the XTNM,
  // casting away constness on the correlation name
  // in order to have default cat+sch filled in.
  //
  bindWA->getCurrentScope()->getXTNM()->insertNames(bindWA,
                                                    (CorrName &)tableName);

  if (bindWA->errStatus()) {
    delete resultTable;
    return this;
  }

  if (getViewNATable())
  {
    const NATable * natable = getViewNATable() ;
    const ColumnDescList &columnsRET = *(resultTable->getColumnList());
    for (i = 0; i < natable->getColumnCount(); i++)
    {
      columnsRET[i]->setViewColPosition(
        ((natable->getNAColumnArray())[i])->getPosition());
      columnsRET[i]->setViewFileName((const char*)natable->getViewFileName());
    }
  }

  //
  // Bind the base class.
  //
  return bindSelf(bindWA);
} // RenameTable::bindNode()

// -----------------------------------------------------------------------
// member functions for class RenameReference
// -----------------------------------------------------------------------

// This method replaces the RETDesc of the current scope, with a new RETDesc
// that contains the columns of the transition values (OLD@ and NEW@) but
// with correlation names specified by the user in the REFERENCING clause
// of the row trigger.
void RenameReference::prepareRETDescWithTableRefs(BindWA *bindWA)
{
  CollIndex  refsToFind = getRefList().entries();
  CollIndex  refsFound = 0;
  RETDesc   *retDesc;

  // First find the NEW@ and OLD@ tables in one of the scopes.
  BindScope *scope = bindWA->getCurrentScope();
  // For each BindScope,
  while ((scope!=NULL) && (refsToFind > refsFound))
  {    // until we find all the references.
    retDesc = scope->getRETDesc();
    // Skip if an empty RETDesc
    if ((retDesc!=NULL) && !retDesc->isEmpty())
    {
      // For each reference to change
      for (CollIndex i=0; i<refsToFind; i++)
        // Find the table name in the RETDesc, and save a pointer to it's
        // column list in the TableRefName object.
        if(getRefList().at(i).lookupTableName(retDesc))
          refsFound++;
    }

    // Get the next BindScope to search.
    scope = bindWA->getPreviousScope(scope);
  } // while not done

  RETDesc *resultTable = new (bindWA->wHeap()) RETDesc(bindWA);

  // Create an empty RETDesc for the current scope.
  bindWA->getCurrentScope()->setRETDesc(resultTable);

  // For each table reference, add to the RETDesc of the current scope, the
  // columns of the columns of the referenced tables with the new referencing
  // names as correlation names.
  for (CollIndex i=0; i<refsToFind; i++)
    getRefList()[i].bindRefColumns(bindWA);
}

// The RenaneReference node renames values flowing down through it.
// It is used above a row trigger body, to implement the REFERENCING clause
// of the trigger definition - renaming the OLD and NEW transition variables
// to user specified names.
//
// This bind is top-down, so we first prepare the RETDesc, and then bind
// the children using this RETDesc.
RelExpr *RenameReference::bindNode(BindWA *bindWA)
{
  if (nodeIsBound())
  {
    bindWA->getCurrentScope()->setRETDesc(getRETDesc());
    return this;
  }

  // Save the current RETDesc.
  RETDesc *prevRETDesc = bindWA->getCurrentScope()->getRETDesc();

  // Replace the RETDesc of the current scope with one that contains the user
  // names (MY_NEW, MY_OLD) instead of the reference names (NEW@, OLD@).
  prepareRETDescWithTableRefs(bindWA);

  // Bind the child nodes, in a new BindScope.
  // If we don't open a new scope here, the bindChildren() method will
  // overwrite the RETDesc of the current scope with NULL.
  bindWA->initNewScope();

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

  // Bind the base class.
  RelExpr *boundNode = bindSelf(bindWA);

  // Save this scope's outer references before removing the scope.
  const ValueIdSet myOuterRefs = bindWA->getCurrentScope()->getOuterRefs();

  setRETDesc(bindWA->getCurrentScope()->getRETDesc());

  bindWA->removeCurrentScope();
  bindWA->getCurrentScope()->setRETDesc(prevRETDesc);

  // Now merge the outer references into the previous scope.
  bindWA->getCurrentScope()->mergeOuterRefs(myOuterRefs, FALSE);

  return boundNode;
}  // RenameReference::bindNode()

// -----------------------------------------------------------------------
// member functions for class BeforeTrigger
// -----------------------------------------------------------------------

//////////////////////////////////////////////////////////////////////////////
// Find the name and position of a column SET to by this before Trigger.
// The targetColName is an output parameter, saving the bindSetClause()
// method the work of finding the column name.
// The naTable parameter is NULL during DML. and is only used for DDL
// semantic checks.
//////////////////////////////////////////////////////////////////////////////
Lng32 BeforeTrigger::getTargetColumn(CollIndex i,  // Index of Assign expr.
                                    ColRefName* targetColName,
                                    const NATable *naTable)
{
  ItemExpr *currentAssign = setList_->at(i);
  CMPASSERT(currentAssign->getOperatorType() == ITM_ASSIGN);

  ItemExpr *targetColReference = currentAssign->child(0);
  CMPASSERT(targetColReference->getOperatorType() == ITM_REFERENCE);
  ColRefName& targetColRefName =
    ((ColReference *)targetColReference)->getColRefNameObj();

  if (targetColName != NULL)  // return the column name to the binder.
    *targetColName = targetColRefName;

  const NAString& colName = targetColRefName.getColName();

  // If called during DML binding of the BeforeTrigger node, the
  // column position will not be used, because the check for duplicate
  // SET columns was done in DDL time.
  if (naTable == NULL)
    return 0;

  // We get here from DDL binding of the BeforeTrigger node, or from
  // the Inlining code.
  NAColumn *colObj  = naTable->getNAColumnArray().getColumn(colName);

  // If colObj is NULL, it's a bad column name.
  if (colObj == NULL)
    return -1;

  return colObj->getPosition();
}

//////////////////////////////////////////////////////////////////////////////
// This method is called only during DDL (CREATE TRIGGER) of a before trigger
// with a SET clause.
// Each of the columns updated by the SET clause goes through several
// semantic checks, that cannot be done in the parser.
//////////////////////////////////////////////////////////////////////////////
void BeforeTrigger::doSetSemanticChecks(BindWA *bindWA, RETDesc *origRETDesc)
{
  UpdateColumns localCols = UpdateColumns(FALSE);
  ColRefName currentCol;
  const NATable *scanNaTable = NULL;
  NABoolean isUpdateOp=FALSE;

  Scan *scanNode = getLeftmostScanNode();
  CMPASSERT(scanNode != NULL);
  scanNaTable = scanNode->getTableDesc()->getNATable();

  CorrName oldCorr(OLDCorr);
  if (origRETDesc->getQualColumnList(oldCorr))
    isUpdateOp = TRUE;

  for (CollIndex i=0; i<setList_->entries(); i++)
  {
    // Get the name and position of the Assign target column.
    Lng32 targetColPosition = getTargetColumn(i, &currentCol, scanNaTable);

    if (!currentCol.getCorrNameObj().isATriggerTransitionName(bindWA, TRUE))
    {
      // 11017 Left hand of SET assignment must be qualified with the name of the NEW transition variable
      *CmpCommon::diags() << DgSqlCode(-11017) ; // must be NEW name
      bindWA->setErrStatus();
      return;
    }

    if (targetColPosition == -1)
    {
      // 11022 Column $0~ColumnName is not a column in table $0~TableName
      NAString tableName = scanNaTable->getTableName().getQualifiedNameAsString();
      *CmpCommon::diags() << DgSqlCode(-11022)
        << DgColumnName(currentCol.getColName())
        << DgTableName(tableName);
      bindWA->setErrStatus();
      return;
    }

    // We need to check for duplicate SET columns in DDL time only.
    if (localCols.contains(targetColPosition))
    {
      // 4022 column specified more than once
      *CmpCommon::diags() << DgSqlCode(-4022)
        << DgColumnName(currentCol.getColName());
      bindWA->setErrStatus();
      return;
    }
    localCols.addColumn(targetColPosition);

    // Is this a SET into a column that is part of the clustering key?
    // This is only allowed on Inserts, not on Updates (Deletes never get here).
    if (isUpdateOp  &&
      scanNaTable->getNAColumnArray().getColumn(targetColPosition)->isClusteringKey())
    {
      // 4033 Column $0~ColumnName is a primary or clustering key column and cannot be updated.
      *CmpCommon::diags() << DgSqlCode(-4033)
        << DgColumnName(currentCol.getColName());
      bindWA->setErrStatus();
      return;
    }
  }
}

//////////////////////////////////////////////////////////////////////////////
// This method is called for before triggers that use the SET clause.
// For each column to be set using SET MYNEW.<colname> = <setExpr> do:
// 1. Find NEW@.<colname> in origRETDesc.
// 2. Verify that there is such a column, and that the user is allowd to
//    change it.
// 3. Get the column's ItemExpr expression, and save it in passThruExpr.
// 4. Create an ItemExpr tree as follows:
//                     case
//                       |
//                  IfThenElse
//                 /     |     \
//        condition    setExpr  passThruExpr
//
//    where condition is the WHEN clause expression.
// 5. Bind this new expression in the RETDesc of the current scope.
// 6. remove NEW@.<colname> from origRETDesc, and re-insert it as the new
//    expression.
//////////////////////////////////////////////////////////////////////////////
void BeforeTrigger::bindSetClause(BindWA *bindWA, RETDesc *origRETDesc, CollHeap *heap)
{
  // Semantic checks are only needed during DDL.
  if (bindWA->inDDL())
  {
    doSetSemanticChecks(bindWA, origRETDesc);
    if (bindWA->errStatus())
      return;
  }

  CorrName newCorr(NEWCorr);
  const TableRefName *newRefName = getRefList().findTable(newCorr);
  CMPASSERT(newRefName!=NULL);
  CorrName newRef = newRefName->getTableCorr();
  ColRefName currentCol;

  // For each Assign expression in the list.
  for (CollIndex i=0; i<setList_->entries(); i++)
  {
    // Get the name and position of the Assign target column.
    Lng32 targetColPosition = getTargetColumn(i, &currentCol, NULL);

    currentCol.getCorrNameObj() = newRef;
    ItemExpr *setExpr = setList_->at(i)->child(1);
    // Find the current value of this NEW@ column.
    ColumnNameMap *currentColExpr = origRETDesc->findColumn(currentCol);
    CMPASSERT(currentColExpr != NULL); // Otherwise we would have been thrown with error 11022 - see above.
    ItemExpr *passThruExpr = currentColExpr->getValueId().getItemExpr();

    ItemExpr *colExpr = NULL;
    if (whenClause_ == NULL)
      // After we add the support for reading the trigger status from
      // the resource fork, and adding it to the condition, we should
      // never get here.
      colExpr = setExpr;
    else
    {
      IfThenElse *ifExpr = new(heap)
        IfThenElse(whenClause_, setExpr, passThruExpr);
      colExpr = new(heap) Case(NULL, ifExpr);
    }
    colExpr = colExpr->bindNode(bindWA);
    if (bindWA->errStatus())
    return;

    // Now remove and re-insert the column to the original RETDesc,
    // that will be restored at the bottom of the method.
      currentCol.getCorrNameObj() = newCorr;
    origRETDesc->delColumn(bindWA, currentCol, USER_COLUMN);
    origRETDesc->addColumn(bindWA, currentCol, colExpr->getValueId());

          // force binding of the assign here so that type incompatability is caught
          // during DDL
          if (bindWA->inDDL())
          {
               ItemExpr *currentAssign = setList_->at(i);
               CMPASSERT(currentAssign->getOperatorType() == ITM_ASSIGN);
               currentAssign->bindNode(bindWA);
          }
  }
}

//////////////////////////////////////////////////////////////////////////////
// This method is called for before triggers that use the SIGNAL clause.
// 1. Find the "virtual execId column" in origRETDesc.
// 3. Get the column's ItemExpr expression, and save it in passThruExpr.
// 4. Create an ItemExpr tree as follows:
//                     case
//                       |
//                  IfThenElse
//                 /     |       \
//              AND  passThruExpr passThruExpr
//            /    \
//    condition     RaiseError
//
//    where condition is the WHEN clause expression, and RaiseError is the
//    SIGNAL expression.
// 5. Bind this new expression in the RETDesc of the current scope.
// 6. remove "virtual execId column" from origRETDesc, and re-insert it as
//    the new expression.
//
// The value of the expression is always the passThruExpr, for type
// compatibility. since if the SIGNAL fires, the actual value returned does
// not matter. The AND will evaluate the RaiseError only if the condition
// evaluates to TRUE.
//////////////////////////////////////////////////////////////////////////////
void BeforeTrigger::bindSignalClause(BindWA *bindWA, RETDesc *origRETDesc, CollHeap *heap)
{
  if (bindWA->inDDL())
  {
    // In DDL time (CREATE TRIGGER) all we need is to bind the signal
    // expression for semantic checks.
    signal_->bindNode(bindWA);
    if (bindWA->errStatus())
    return;
  }
  else
  {
    // The SIGNAL expression is piggy-backed on the Unique ExecuteID
    // value inserted into the temp table.
    ColumnNameMap *execIdCol =
      origRETDesc->findColumn(InliningInfo::getExecIdVirtualColName());
    CMPASSERT(execIdCol != NULL);
    const ColRefName& ExecIdColName = execIdCol->getColRefNameObj();
    ItemExpr *passThruExpr = execIdCol->getValueId().getItemExpr();
    ItemExpr *whenAndSignal = NULL;

    // Case 10-040604-5021:
    // General AND logic uses "short circuiting" as follows: if the
    // left side is FALSE, evaluation of the right side is skipped, and
    // the result returned is FALSE. The following expression depends on
    // evaluation of the right side being skipped whenever the left side
    // is NOT TRUE, (i.e., FALSE or NULL). Therefore, an IS TRUE unary
    // predicate must be placed above the actual WHEN condition. Otherwise,
    // the signal will fire when the WHEN condition evaluates to NULL.
    if (whenClause_ != NULL)
    {
         if (whenClause_->getOperatorType() == ITM_AND ||
             whenClause_->getOperatorType() == ITM_OR)
         {
             ItemExpr *isTrueExpr = new (heap) UnLogic(ITM_IS_TRUE, whenClause_);
             whenAndSignal = new(heap) BiLogic(ITM_AND, isTrueExpr, signal_);
         }
         else
         {
             whenAndSignal = new(heap) BiLogic(ITM_AND, whenClause_, signal_);
         }
    }

    else
      // After we add the support for reading the trigger status from
      // the resource fork, and adding it to the condition, we should
      // never get here.
      whenAndSignal = signal_;

    // For type compatibity, the original value is used whatever the
    // WHEN clause evaluates to. However, if it evaluates to TRUE, the
    // evaluation of the signal expression will throw an SQLERROR.
    ItemExpr *condSignalExpr = new(heap)
      Case(NULL, new(heap)
        IfThenElse(whenAndSignal, passThruExpr, passThruExpr));
    condSignalExpr = condSignalExpr->bindNode(bindWA);
    if (bindWA->errStatus())
      return;

    // Now delete the original "virtual column" from the RETDesc, and
    // re-insert it with the new value.
    origRETDesc->delColumn(bindWA, ExecIdColName, USER_COLUMN);
    origRETDesc->addColumn(bindWA, ExecIdColName, condSignalExpr->getValueId());
  }
}

//////////////////////////////////////////////////////////////////////////////
// This bind is bottom-up, so we first bind the children, and then use
// and change the RETDesc they created.
//////////////////////////////////////////////////////////////////////////////
RelExpr *BeforeTrigger::bindNode(BindWA *bindWA)
{
  if (nodeIsBound())
  {
    bindWA->getCurrentScope()->setRETDesc(getRETDesc());
    return this;
  }

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

  // Now we know that we have the columns of OLD@ and NEW@ in the RETDesc
  // of the current scope. Save this scope so we can update it and restore
  // it when we are done.
  RETDesc   *origRETDesc = bindWA->getCurrentScope()->getRETDesc();
  CollHeap  *heap = bindWA->wHeap();
  CollIndex  refsToFind = getRefList().entries();

  // For each reference to change, Find the table name in the RETDesc,
  // and save a pointer to it's column list in the TableRefName object.
  CollIndex i=0;
  for (i=0; i<refsToFind; i++)
    getRefList().at(i).lookupTableName(origRETDesc);

  // Create an empty RETDesc for the current scope.
  // It will contain the names the user specified (MY_NEW, MY_OLD) for the
  // OLD@ and NEW@ transition variables, and will be used to bind this
  // node only.
  bindWA->getCurrentScope()->setRETDesc(new(heap) RETDesc(bindWA));

  // For each table reference, add to the RETDesc of the current scope,
  // the columns of the referenced tables with the new referencing names
  // as correlation names.
  for (i=0; i<refsToFind; i++)
    getRefList().at(i).bindRefColumns(bindWA);

  // First bind the condition. The ValueId will be used later (possibly
  // multiple times) so that during execution, the expression will be
  // evaluated only once.
  if (whenClause_ != NULL)
  {
    whenClause_ = whenClause_->bindNode(bindWA);
    if (bindWA->errStatus())
      return this;
  }

  // Use the bound condition to prepare the conditional expression
  // for each column modified by the trigger (SET MY_NEW.a = ...)
  if (setList_ != NULL)
    bindSetClause(bindWA, origRETDesc, heap);

  // Use the bound condition to prepare the conditional SIGNAL
  // expression, on the ExecuteId "virtual column".
  if (signal_ != NULL)
    bindSignalClause(bindWA, origRETDesc, heap);

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

  // We don't need the RETDesc of the current scope anymore. Restore the
  // original RETDesc with the updated columns.
  bindWA->getCurrentScope()->setRETDesc(origRETDesc);
  if (parentTSJ_ != NULL)
  {
    // If this is the top most before trigger, save a copy of the RETDesc
    // for use by the transformNode() pass.
    RETDesc *savedRETDesc = new(heap) RETDesc(bindWA, *origRETDesc);
    setRETDesc(savedRETDesc);
  }
  //
  // Bind the base class.
  //
  RelExpr *boundNode = bindSelf(bindWA);

  return boundNode;
} // BeforeTrigger::bindNode()

// -----------------------------------------------------------------------
// member functions for class Insert
// -----------------------------------------------------------------------
// LCOV_EXCL_START - cnu
static void bindInsertRRKey(BindWA *bindWA, Insert *insert,
                            ValueIdList &sysColList, CollIndex i)
{
  // For a KS round-robin partitioned table, the system column
  // (for now there is only one, SYSKEY) is initialized via the expression
  // "ProgDistribKey(partNum, rowPos, totalNumParts)".
  //
  const NAFileSet *fs =
    insert->getTableDesc()->getClusteringIndex()->getNAFileSet();

  // For now, round-robin partitioned tables are always stored in
  // key-sequenced files, and there is only one system column (SYSKEY)
  // which is at the beginning of the record.
  CMPASSERT(fs->isKeySequenced() && i==0);

  CollHeap *heap = bindWA->wHeap();

  // Host variables that provide access to partition number,
  // row position, and total number of partitions --
  // supplied at run-time by the executor insert node.
  //
  ItemExpr *partNum = new (heap)
    HostVar("_sys_hostVarInsertPartNum",
      new (heap) SQLInt(FALSE,FALSE),   // int unsigned not null
      TRUE // is system-generated
     );
  partNum->synthTypeAndValueId();
  insert->partNumInput() = partNum->getValueId();  // for later use in codeGen

  ItemExpr *rowPos = new (heap)
    HostVar("_sys_hostVarInsertRowPos",
      new (heap) SQLInt(FALSE,FALSE),  // int unsigned not null
      TRUE // is system-generated
     );
  rowPos->synthTypeAndValueId();
  insert->rowPosInput() = rowPos->getValueId();  // for later use in codeGen

  ItemExpr *totNumParts = new (heap)
    HostVar("_sys_hostVarInsertTotNumParts",
      new (heap) SQLInt(FALSE,FALSE),  // int unsigned not null
      TRUE // is system-generated
     );
  totNumParts->synthTypeAndValueId();
  insert->totalNumPartsInput() = totNumParts->getValueId();   // for later use

  // Generate expression to compute a round-robin key.  Parameters to
  // ProgDistribKey are the partition number, the row position (which
  // is chosen randomly; the insert node will retry if a number is
  // selected that is already in use), and the total number of
  // partitions.
  ItemExpr *rrKey = new (heap) ProgDistribKey(partNum, rowPos, totNumParts);

  // Build and set round-robin key expression.
  Assign *assign = new (heap)
    Assign(sysColList[i].getItemExpr(), rrKey, FALSE /*not user-specified*/);
  assign->bindNode(bindWA);
  insert->rrKeyExpr() = assign->getValueId();
} // bindInsertRRKey
// LCOV_EXCL_STOP

RelExpr *Insert::bindNode(BindWA *bindWA)
{
  if (nodeIsBound())
  {
    bindWA->getCurrentScope()->setRETDesc(getRETDesc());
    return this;
  }

  // Set local binding flags
  setInUpdateOrInsert(bindWA, this, REL_INSERT);
  // The 8108 (unique constraint on an ID column) error must be raised
  // only for system generated IDENTITY values and not for
  // user generated ID values. We use the GenericUpdate::identityColumnUniqueIndex_
  // to indicate to the EID that 8108 should be raised in place of 8102.
  // This variable is used to indicate that there is an IDENTITY column
  // in the table for which the system is generating the value

  // This is NULL if "DEFAULT VALUES" was specified,
  // non-NULL if a query-expr child was specified:  VALUES.., TABLE.., SELECT..
  RelExpr *someNonDefaultValuesSpecified = child(0);

  // Set flag for firstN in context
  if (child(0) && child(0)->getOperatorType() == REL_ROOT) // Indicating subquery
    if (child(0)->castToRelExpr() && 
        child(0)->castToRelExpr()->getFirstNRows() >= 0)
      if (bindWA && 
          bindWA->getCurrentScope() && 
          bindWA->getCurrentScope()->context())
        bindWA->getCurrentScope()->context()->firstN() = TRUE;

  if (NOT someNonDefaultValuesSpecified) {  // "DEFAULT VALUES" specified
    // Kludge up a dummy child before binding the GenericUpdate tree
    setChild(0, new(bindWA->wHeap()) Tuple(new(bindWA->wHeap()) SystemLiteral(0)));
  }

  // Bind the GenericUpdate tree.
  //
  RETDesc *incomingRETDescForSource = bindWA->getCurrentScope()->getRETDesc();
  RelExpr *boundExpr = GenericUpdate::bindNode(bindWA);
  if (bindWA->errStatus()) 
    return boundExpr;

  const NAFileSet* fileset = getTableDesc()->getNATable()->getClusteringIndex();
  const NAColumnArray& partKeyCols = fileset->getPartitioningKeyColumns();

  if (getTableDesc()->getNATable()->isHiveTable())
  {
    if (partKeyCols.entries() > 0)
      {
        // Insert into partitioned tables would require computing the target
        // partition directory name, something we don't support yet.
        *CmpCommon::diags() << DgSqlCode(-4222)
                            << DgString0("Insert into partitioned Hive tables");
        bindWA->setErrStatus();
        return this;
      }

    // specifying a list of column names to insert to is not yet supported
    if (insertColTree_) {
      *CmpCommon::diags() << DgSqlCode(-4223)
                          << DgString0("Target column list for insert into Hive table");
      bindWA->setErrStatus();
      return this;
    }
     
    RelExpr *feResult = FastExtract::makeFastExtractTree(
         getTableDesc(),
         child(0).getPtr(),
         getOverwriteHiveTable(),
         TRUE,  // called from within binder
         FALSE, // not a common subexpr
         bindWA);

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

        return feResult;
      }
    else
      return this;
  }

  if(!(getOperatorType() == REL_UNARY_INSERT &&
       (child(0)->getOperatorType() == REL_TUPLE || // VALUES (1,'b')
        child(0)->getOperatorType() == REL_TUPLE_LIST || // VALUES (1,'b'),(2,'Y')
        child(0)->getOperatorType() == REL_UNION))  &&      // VALUES with subquery
     (getOperatorType() != REL_LEAF_INSERT))
    {
      setInsertSelectQuery(TRUE);
    }

  // if table has a lob column, then fix up any reference to LOBinsert
  // function in the source values list.
  //
  if ((getOperatorType() == REL_UNARY_INSERT) &&
      (getTableDesc()->getNATable()->hasLobColumn()) &&
      (child(0)->getOperatorType() == REL_TUPLE || // VALUES (1,'b')
       child(0)->getOperatorType() == REL_TUPLE_LIST)) // VALUES (1,'b'),(2,'Y')
    {
      if (child(0)->getOperatorType() == REL_TUPLE_LIST)
	{
	  TupleList * tl = (TupleList*)(child(0)->castToRelExpr());
	  for (CollIndex x = 0; x < (UInt32)tl->numTuples(); x++)
	    {
	      ValueIdList tup;
	      if (!tl->getTuple(bindWA, tup, x)) 
		{
		  bindWA->setErrStatus();

		  return boundExpr; // something went wrong
		}
	      
	      for (CollIndex n = 0; n < tup.entries(); n++)
		{
		  ItemExpr * ie = tup[n].getItemExpr();
		  if (ie->getOperatorType() == ITM_LOBINSERT)
		    {
		      // cannot have this function in a values list with multiple
		      // tuples. Use a single tuple.
		      *CmpCommon::diags() << DgSqlCode(-4483);
		      bindWA->setErrStatus();
		      
		      return boundExpr; 
   
		      LOBinsert * li = (LOBinsert*)ie;
		      li->insertedTableObjectUID() = 
			getTableDesc()->getNATable()->objectUid().castToInt64();
		      li->lobNum() = n;

		      li->insertedTableSchemaName() = 
			getTableDesc()->getNATable()->
			getTableName().getSchemaName();
		    }
		} // for
	    } // for
	} // if tuplelist

    } // if
 

  // Prepare for any IDENTITY column checking later on
  NAString identityColumnName;
  NABoolean identityColumnGeneratedAlways = FALSE;
  
  identityColumnGeneratedAlways =
    getTableDesc()->isIdentityColumnGeneratedAlways(&identityColumnName);
    
  if ((getTableName().isVolatile()) &&
      (CmpCommon::context()->sqlSession()->volatileSchemaInUse()) &&
      (getTableName().getSpecialType() == ExtendedQualName::NORMAL_TABLE) &&
      ((ActiveSchemaDB()->getDefaults()).getAsLong(IMPLICIT_UPD_STATS_THRESHOLD) > -1) &&
      (bindWA->isInsertSelectStatement()) &&
      (NOT getTableDesc()->getNATable()->isVolatileTableMaterialized()))
    {
      if (NOT Get_SqlParser_Flags(INTERNAL_QUERY_FROM_EXEUTIL))
        //      if (NOT Get_SqlParser_Flags(NO_IMPLICIT_VOLATILE_TABLE_UPD_STATS))
        {
          // treat this insert as a volatile load stmt.
          RelExpr * loadVolTab = 
            new (bindWA->wHeap()) 
            ExeUtilLoadVolatileTable(getTableName(),
                                     this,
                                     bindWA->wHeap());
          
          boundExpr = loadVolTab->bindNode(bindWA);
          if (bindWA->errStatus()) 
            return boundExpr;

          return boundExpr;
        }
      else
        {
          NATable * nat = (NATable*)(getTableDesc()->getNATable());
          nat->setIsVolatileTableMaterialized(TRUE);
        }
    }

  // Now we have to create the following three collections:
  //
  // - newRecExpr()
  //   An unordered set of Assign nodes of the form
  //   "col1 = value1, col2 = value2, ..." which is used by Norm/Optimizer.
  //
  // - newRecExprArray()
  //   An ordered array of Assign nodes of the same form,
  //   ordered by column position, which is used by Generator.
  //   This array must have the following properties:
  //
  //   - All columns not specified in the insert statement must be
  //     Assign'ed with their default values.
  //
  //   - If this is a key-sequenced table with a (non-RR) SYSKEY column,
  //     we must create the first entry in the newRecExprArray
  //     to be "SYSKEY_COL = 0".  This is a placeholder where the timestamp
  //     value will be moved at runtime.  Round-robin SYSKEY columns are
  //     initialized via an expression of the form "SYSKEY_COL =
  //     ProgDistribKey(..params..)".  SYSKEY columns for other table
  //     organizations are handled by the file system or disk process.
  //
  // - updateToSelectMap()
  //   A ValueIdMap that can be used to rewrite value ids of the
  //   target table in terms of the source table and vice versa.
  //   The top value ids are target value ids, the bottom value ids
  //   are those of the source.
  //

  NABoolean view = bindWA->getNATableInternal(getTableName())->getViewText() != NULL;

  ValueIdList tgtColList, userColList, sysColList, *userColListPtr;
  CollIndexList colnoList(STMTHEAP);
  CollIndex totalColCount, defaultColCount, i;

  getTableDesc()->getSystemColumnList(sysColList);

  //
  // Detach the column list and bind the columns to the target table.
  // Set up "colnoList" to map explicitly specified columns to where
  // in the ordered array we will be inserting later.
  //
  ItemExpr *columnTree = removeInsertColTree();
  CMPASSERT(NOT columnTree || someNonDefaultValuesSpecified);
  if (columnTree || (view && someNonDefaultValuesSpecified)) {
    //
    // INSERT INTO t(colx,coly,...) query-expr;
    // INSERT INTO v(cola,colb,...) query-expr;
    // INSERT INTO v query-expr;
    //  where  query-expr is VALUES..., TABLE..., or SELECT...,
    //  but not DEFAULT VALUES.
    //    userColList is the full list of columns in the target table
    //    colnoList contains, for those columns specified in tgtColList,
    //		their ordinal position in the target table user column list
    //		(i.e., not counting system columns, which can't be specified
    //		in the insert column list); e.g. '(Z,X,Y)' -> [3,1,2]
    //
    CMPASSERT(NOT columnTree ||
              columnTree->getOperatorType() == ITM_REFERENCE ||
              columnTree->getOperatorType() == ITM_ITEM_LIST);
    getTableDesc()->getUserColumnList(userColList);
    userColListPtr = &userColList;

    RETDesc *columnLkp;

    if (columnTree) {
      // bindRowValues will bind using the currently scoped RETDesc left in
      // by GenericUpdate::bindNode, which will be that of the naTableTop
      // (topmost view or table), *not* that of the base table (getTableDesc()).
      columnLkp = bindRowValues(bindWA, columnTree, tgtColList, this, FALSE);
      if (bindWA->errStatus()) return boundExpr;
    } 
    else 
    {
      columnLkp = bindWA->getCurrentScope()->getRETDesc();
      columnLkp->getColumnList()->getValueIdList(tgtColList);
    }

    if (GU_DEBUG) {
// LCOV_EXCL_START - dpm
      cerr << "columnLkp " << flush;
      columnLkp->display();
// LCOV_EXCL_STOP
    }

    for (i = 0; i < columnLkp->getDegree(); i++) {
      // Describes column in the base table:
      ValueId source = columnLkp->getValueId(i);
      const NAColumn *nacol = source.getNAColumn();

      // Gets name of the column in this (possibly view) table:
      const ColRefName colName = columnLkp->getColRefNameObj(i);
 
      // solution 10-081114-7315
      if (bindWA->inDDL() && bindWA->isInTrigger ())
      {
         if (!userColListPtr->contains(source))
         {
            // 4001 column not found
            *CmpCommon::diags() << DgSqlCode(-4001)
              << DgColumnName(colName.getColName())
              << DgString0(getTableName().getQualifiedNameObj().getQualifiedNameAsAnsiString())
              << DgString1(bindWA->getDefaultSchema().getSchemaNameAsAnsiString());
            bindWA->setErrStatus();
            delete columnLkp;
            return boundExpr;
         }
      }

      if (columnLkp->findColumn(colName)->isDuplicate()) {
        // 4022 column specified more than once
        *CmpCommon::diags() << DgSqlCode(-4022)
                            << DgColumnName(colName.getColName());
        bindWA->setErrStatus();
        delete columnLkp;
        return boundExpr;
      }

      colnoList.insert(nacol->getPosition());
      // Commented out this assert, as Assign::bindNode below emits nicer errmsg
      // CMPASSERT((long)nacol->getPosition() - (long)firstColNumOnDisk >= 0);
    }
    if (columnTree) {
      delete columnLkp;
      columnLkp = NULL;
    }
    bindWA->getCurrentScope()->setRETDesc(getRETDesc());
  }
  else {
    //
    // INSERT INTO t query-expr;
    // INSERT INTO t DEFAULT VALUES;
    // INSERT INTO v DEFAULT VALUES;
    //    userColListPtr points to tgtColList (which is the full list)
    //    userColList not used (because tgtColList already is the full list)
    //    colnoList remains empty (because tgtColList is already in order)
    //              if no system columns, set to list of user cols otherwise
    getTableDesc()->getUserColumnList(tgtColList);
    userColListPtr = &tgtColList;
    if (sysColList.entries()) {
      // set up colnoList to indicate the user columns, to help
      // binding DEFAULT clauses in DefaultSpecification::bindNode()
      for (CollIndex uc=0; uc<tgtColList.entries(); uc++) {
        colnoList.insert(tgtColList[uc].getNAColumn()->getPosition());
      }
    }
  }

  // Compute total number of columns. Note that there may be some unused
  // entries in newRecExprArray(), in the following case:
  // - For computed columns that are not stored on disk
  totalColCount = userColListPtr->entries() + sysColList.entries();
  newRecExprArray().resize(totalColCount);

  // Make sure children are bound -- GenericUpdate::bindNode defers
  // their binding to now if this is an INSERT..VALUES(..),
  // because only now do we have target column position info for
  // correct binding of INSERT..VALUES(..,DEFAULT,..)
  // in DefaultSpecification::bindNode.
  //
  // Save current RETDesc and XTNM.
  // Bind the source in terms of the original RETDesc,
  //   with target column position info available through
  //     bindWA->getCurrentScope()->context()->updateOrInsertNode()
  //   (see DefaultSpecification::bindNode, calls Insert::getColDefaultValue).
  // Restore RETDesc and XTNM.
  //
  RETDesc *currRETDesc = bindWA->getCurrentScope()->getRETDesc();
  bindWA->getCurrentScope()->setRETDesc(incomingRETDescForSource);
  bindWA->getCurrentScope()->xtnmStack()->createXTNM();
  setTargetUserColPosList(colnoList);

  // if my child is a TupleList, then all tuples are to be converted/cast
  // to the corresponding target type of the tgtColList.
  // Pass on the tgtColList to TupleList so it can generate the Cast nodes
  // with the target types during the TupleList::bindNode.
  TupleList *tl = NULL;
  if (child(0)->getOperatorType() == REL_TUPLE_LIST) {
    tl = (TupleList *)child(0)->castToRelExpr();
    tl->castToList() = tgtColList;
  }

  if (getTolerateNonFatalError() != RelExpr::UNSPECIFIED_) {
    HostArraysWA * arrayWA = bindWA->getHostArraysArea() ;
    if (arrayWA && arrayWA->hasHostArraysInTuple()) {
      if (getTolerateNonFatalError() == RelExpr::NOT_ATOMIC_)
        arrayWA->setTolerateNonFatalError(TRUE);
      else
        arrayWA->setTolerateNonFatalError(FALSE);  // Insert::tolerateNonfatalError == ATOMIC_
    }
    else if (NOT arrayWA->getRowwiseRowset()) {
      // NOT ATOMIC only for rowset inserts
      *CmpCommon::diags() << DgSqlCode(-30025) ;
      bindWA->setErrStatus();
      return boundExpr;
    }
  }

 


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

  // if this is an insert into native hbase table in _ROW_ format, then
  // validate that only REL_TUPLE or REL_TUPLE_LIST is being used.
  if ((getOperatorType() == REL_UNARY_INSERT) &&
      (getTableDesc()->getNATable()->isHbaseRowTable()))
    {
      NABoolean isError = FALSE;
      if (NOT (child(0)->getOperatorType() == REL_TUPLE || // VALUES (1,'b')
               child(0)->getOperatorType() == REL_TUPLE_LIST)) // VALUES (1,'b'),(2,'Y')
        {
          isError = TRUE;
        }

      // Also make sure that inserts into column_details field of _ROW_ format
      // hbase virtual table are being done through column_create function.
      //   For ex: insert into hbase."_ROW_".hb values ('1', column_create('cf:a', '100'))
      //
      if ((NOT isError) && (child(0)->getOperatorType() == REL_TUPLE))
	{
          ValueIdList &tup = ((Tuple*)(child(0)->castToRelExpr()))->tupleExpr();
          if (tup.entries() == 2) // can only have 2 entries
            {
              ItemExpr * ie = tup[1].getItemExpr();
              if (ie && ie->getOperatorType() != ITM_HBASE_COLUMN_CREATE)
                {
                  isError = TRUE;
                }
            }
          else
            isError = TRUE;
        }

      if ((NOT isError) && (child(0)->getOperatorType() == REL_TUPLE_LIST))
	{
	  TupleList * tl = (TupleList*)(child(0)->castToRelExpr());
	  for (CollIndex x = 0; x < (UInt32)tl->numTuples(); x++)
	    {
	      ValueIdList tup;
	      if (!tl->getTuple(bindWA, tup, x)) 
		{
                  isError = TRUE;
		}

              if (NOT isError)
                {
                  if (tup.entries() == 2) // must have 2 entries
                    {
                      ItemExpr * ie = tup[1].getItemExpr();
                      if (ie->getOperatorType() != ITM_HBASE_COLUMN_CREATE)
                        {
                          isError = TRUE;
                        }
                    }
                  else
                    isError = TRUE;
                } // if
            } // for
        } // if

      if (isError)
        {
          *CmpCommon::diags() << DgSqlCode(-1429);
          bindWA->setErrStatus();
          
          return boundExpr; 
        }
    }

  // the only time that tgtColList.entries()(Insert's colList) != tl->castToList().entries()
  // (TupleList's colList) is when DEFAULTS are removed in TupleList::bindNode() for insert
  // into table with IDENTITY column, where the system generates the values
  // for it using SG (Sequence Generator).
  // See TupleList::bindNode() for detailed comments.
  // When tgtColList.entries()(Insert's col list) is not
  // equal to  tl->castToList().entries() (TupleList's column list)
  // make sure the correct colList is used during binding.
  ValueIdList newTgtColList;
  if(tl && (tgtColList.entries() != tl->castToList().entries()))
    {
    newTgtColList = tl->castToList();
    CMPASSERT(newTgtColList.entries() == (tgtColList.entries() -1));
    }
  else
    newTgtColList = tgtColList;

  setTargetUserColPosList();
  bindWA->getCurrentScope()->xtnmStack()->removeXTNM();
  bindWA->getCurrentScope()->setRETDesc(currRETDesc);
  NABoolean bulkLoadIndex = bindWA->isTrafLoadPrep() && noIMneeded() ;

  if (someNonDefaultValuesSpecified) 
    // query-expr child specified
    {

      const RETDesc &sourceTable = *child(0)->getRETDesc();
      if ((sourceTable.getDegree() != newTgtColList.entries())&& !bulkLoadIndex) {
      // 4023 degree of row value constructor must equal that of target table
      *CmpCommon::diags() << DgSqlCode(-4023)
#pragma nowarn(1506)   // warning elimination
        << DgInt0(sourceTable.getDegree()) << DgInt1(tgtColList.entries());
#pragma warn(1506)  // warning elimination
      bindWA->setErrStatus();
      return boundExpr;
      }

    
    OptSqlTableOpenInfo* stoiInList = NULL;
    for (CollIndex ii=0; ii < bindWA->getStoiList().entries(); ii++)
    {
      if (getOptStoi() && getOptStoi()->getStoi())
	{
	  if (strcmp((bindWA->getStoiList())[ii]->getStoi()->fileName(), 
		     getOptStoi()->getStoi()->fileName()) == 0) 
	    {
	      stoiInList = bindWA->getStoiList()[ii];
	      break;
	    }
	}
    }

    // Combine the ValueIdLists for the column list and value list into a
    // ValueIdSet (unordered) of Assign nodes and a ValueIdArray (ordered).
    // Maintain a ValueIdMap between the source and target value ids.
    CollIndex i2 = 0;
    const ColumnDescList *viewColumns = NULL;
    if (getBoundView())
      viewColumns = getBoundView()->getRETDesc()->getColumnList();

     if (bulkLoadIndex) {
       setRETDesc(child(0)->getRETDesc());
      } 



    for (i = 0; i < tgtColList.entries() && i2 < newTgtColList.entries(); i++) {
      if(tgtColList[i] != newTgtColList[i2])
        continue;

      ValueId target = tgtColList[i];
      ValueId source ;
      if (!bulkLoadIndex)
        source = sourceTable.getValueId(i2);
      else {
        ColRefName & cname = ((ColReference *)(baseColRefs()[i2]))->getColRefNameObj();
        source = sourceTable.findColumn(cname)->getValueId();
      }
      CMPASSERT(target != source);

      const NAColumn *nacol = target.getNAColumn();

      const NAType &sourceType = source.getType();
      const NAType &targetType = target.getType();

      if ( DFS2REC::isFloat(sourceType.getFSDatatype())  &&
           DFS2REC::isNumeric(targetType.getFSDatatype()) &&
           (getTableDesc()->getNATable()->getPartitioningScheme()  ==
                                                COM_HASH_V1_PARTITIONING ||
            getTableDesc()->getNATable()->getPartitioningScheme()  ==
                                                COM_HASH_V2_PARTITIONING) )
      {
        const NAColumnArray &partKeyCols = getTableDesc()->getNATable()
                         ->getClusteringIndex()->getPartitioningKeyColumns();

        for (CollIndex j=0; j < partKeyCols.entries(); j++)
        {
          if (partKeyCols[j]->getPosition() == nacol->getPosition())
          {
            ItemExpr *ie = source.getItemExpr();
            ItemExpr *cast = new (bindWA->wHeap())
                                Cast(ie, &targetType, ITM_CAST);
            cast = cast->bindNode(bindWA);
            if (bindWA->errStatus()) 
              return NULL;

            source = cast->getValueId();

          }
        }
      }

      Assign *assign = new (bindWA->wHeap())
        Assign(target.getItemExpr(), source.getItemExpr());
      assign->bindNode(bindWA);

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

      if (stoiInList && !getUpdateCKorUniqueIndexKey())
      {
        if(!getBoundView())
          stoiInList->addInsertColumn(nacol->getPosition());
        else
        {
          NABoolean found = FALSE;
          for (CollIndex k=0; k < viewColumns->entries(); k++) {
            if ((*viewColumns)[k]->getValueId() == target) {
              stoiInList->addInsertColumn((Lng32) k);
              found = TRUE;
              // Updatable views cannot have any underlying basetable column
              // appear more than once, so it's safe to break out of the loop.
              break;
            }
          }  // loop k
          CMPASSERT(found);
        }
      }

      //
      // Check for automatically inserted TRANSLATE nodes.
      // Such nodes are inserted by the Implicit Casting And Translation feature.
      // If this node has a child TRANSLATE node, then that TRANSLATE node
      // is the real "source" that we must use from here on.
      //
      ItemExpr *assign_child = assign->child(1);
      if ( assign_child->getOperatorType() == ITM_CAST )
      {
         const NAType& type = assign_child->getValueId().getType();
         if ( type.getTypeQualifier() == NA_CHARACTER_TYPE )
         {
            ItemExpr *assign_grndchld = assign_child->child(0);
            if ( assign_grndchld->getOperatorType() == ITM_TRANSLATE )
            {
               source = assign_grndchld->getValueId();
               CMPASSERT(target != source);
            }
         }
      }

      const NAType *colType = nacol->getType();
      if (!colType->isSupportedType()) {
        *CmpCommon::diags() << DgSqlCode(-4027)     // 4027 table not insertable
        << DgTableName(nacol->getNATable()->getTableName().getQualifiedNameAsAnsiString());
        bindWA->setErrStatus();
      }

      if (bindWA->errStatus()) return boundExpr;
      newRecExprArray().insertAt(nacol->getPosition(), assign->getValueId());
      newRecExpr().insert(assign->getValueId());
    
      const NAType& assignSrcType = assign->getSource().getType();
      // if ( <we added some type of conversion> AND
      //      ( <tgt and src are both character> AND
      //        (<they are big and errors can occur> OR <charsets differ> OR <difference between tgt and src lengths is large>)))
      //      OR
      //      ( <we changed the basic type and we allow incompatible types> )
      //    )
      //   <then incorporate this added conversion into the updateToSelectMap>
      if ( source != assign->getSource() && 
           ((assignSrcType.getTypeQualifier() == NA_CHARACTER_TYPE &&
             sourceType.getTypeQualifier() == NA_CHARACTER_TYPE &&
             ((assign->getSource().getItemExpr()->getOperatorType() == ITM_CAST &&
               sourceType.errorsCanOccur(assignSrcType) && 
               sourceType.getNominalSize() > 
               CmpCommon::getDefaultNumeric(LOCAL_MESSAGE_BUFFER_SIZE)*1024) ||
              // Temporary code to fix QC4395 in M6. For M7, try to set source
              // to the right child of the assign after calling assign->bindNode.
              // We should then be able to eliminate this entire if statement
              // as well as the code to check for TRANSLATE nodes above.
              ((CharType &) assignSrcType).getCharSet() !=
              ((CharType &) sourceType).getCharSet() || 
              // The optimizer may ask for source data to be partitioned or sorted on original source columns
              // This is the reason we need to choose the else branch below unless we have a particular reason
              // to do otherwise. Each of the conditions in this if statement reflects one of those partcular
              // conditions. The bottomValues of updateToSelectMap will be placed in their entirety in the 
              // characteristic outputs of the source node. Outputs of the source node may be used to allocate
              // buffers at runtime and therefore we would like to keep the output as small as possible.
              // If the source cannot be partioned/sorted on a column because we have assign-getSource in the bottomValues
              // then the cost is that data will be repartitioned with an additional exchange node. If the difference in
              // length between source and assignSrc is large then the cost of repartition is less than the cost of 
              // allocating and using large buffers.
              sourceType.getNominalSize() > (assignSrcType.getNominalSize() + 
                                             (ActiveSchemaDB()->getDefaults()).getAsLong(COMP_INT_98))  // default value is 512
              ))
            ||
            // If we allow incompatible type assignments, also include the
            // added cast into the updateToSelectMap
            assignSrcType.getTypeQualifier() !=  sourceType.getTypeQualifier() &&
            CmpCommon::getDefault(ALLOW_INCOMPATIBLE_OPERATIONS) == DF_ON))
        {
          updateToSelectMap().addMapEntry(target,assign->getSource());
        }
      else
        {
          updateToSelectMap().addMapEntry(target,source);
        }

      i2++;
    }
  }
  setBoundView(NULL);

  // Is the table round-robin (horizontal) partitioned?
  PartitioningFunction *partFunc =
    getTableDesc()->getClusteringIndex()->getNAFileSet()->
    getPartitioningFunction();

  NABoolean isRRTable =
    partFunc && partFunc->isARoundRobinPartitioningFunction();

  // Fill in default values for any columns not explicitly specified.
  //
  if (someNonDefaultValuesSpecified)      // query-expr child specified, set system cols
    defaultColCount = totalColCount - newTgtColList.entries();
  else                  // "DEFAULT VALUES" specified
    defaultColCount = totalColCount;

  if (identityColumnGeneratedAlways)
    defaultColCount = totalColCount;

  NABoolean isAlignedRowFormat = getTableDesc()->getNATable()->isSQLMXAlignedTable();
  NABoolean omittedDefaultCols = FALSE;
  NABoolean omittedCurrentDefaultClassCols = FALSE;

  if (defaultColCount) {
    NAWchar zero_w_Str[2]; zero_w_Str[0] = L'0'; zero_w_Str[1] = L'\0';  // wide version
    CollIndex sysColIx = 0, usrColIx = 0;

    for (i = 0; i < totalColCount; i++) {

      ValueId target;
      NABoolean isASystemColumn = FALSE;
      const NAColumn *nacol = NULL;

      // find column on position i in the system or user column lists
      if (sysColIx < sysColList.entries() &&
          sysColList[sysColIx].getNAColumn()->getPosition() == i)
        {
          isASystemColumn = TRUE;
          target = sysColList[sysColIx];
        }
      else
        {
          CMPASSERT((*userColListPtr)[usrColIx].getNAColumn()->getPosition() == i);
          target = (*userColListPtr)[usrColIx];
        }
      nacol = target.getNAColumn();
      
      // if we need to add the default value, we don't have a new rec expr yet
      if (NOT newRecExprArray().used(i)) {
       
        const char* defaultValueStr = NULL;
        ItemExpr *  defaultValueExpr = NULL;
        NABoolean needToDeallocateColDefaultValueStr = FALSE;

        // Used for datetime columns with COM_CURRENT_DEFAULT.
        //
        NAType *castType = NULL;

        if (isASystemColumn) {
          if (isRRTable) {
            bindInsertRRKey(bindWA, this, sysColList, sysColIx);
            if (bindWA->errStatus()) return boundExpr;
          }

          if (nacol->isComputedColumn())
            {
              CMPASSERT(target.getItemExpr()->getOperatorType() == ITM_BASECOLUMN);
              ValueId defaultExprValId = ((BaseColumn *) target.getItemExpr())->
                getComputedColumnExpr();
              ValueIdMap updateToSelectMapCopy(updateToSelectMap());

              // Use a copy to rewrite the value, to avoid requesting additional
              // values from the child. We ask the child for all entries in this
              // map in GenericUpdate::pushdownCoveredExpr().
              updateToSelectMapCopy.rewriteValueIdDown(defaultExprValId, defaultExprValId);
              defaultValueExpr = defaultExprValId.getItemExpr();
            }
          else
            defaultValueStr = (char *)zero_w_Str;
        }
        else {            // a user column (cf. Insert::getColDefaultValue)
          CMPASSERT(NOT nacol->isComputedColumn()); // computed user cols not yet supported
          defaultValueStr = nacol->getDefaultValue();
        }
          
        if (NOT defaultValueStr && NOT defaultValueExpr) {
          // 4024 column has neither a default nor an explicit value.
          *CmpCommon::diags() << DgSqlCode(-4024) << DgColumnName(nacol->getColName());
          bindWA->setErrStatus();
          return boundExpr;
        }

        if (defaultValueStr) {
          // If the column has a default class of COM_CURRENT_DEFAULT,
          // cast the default value (which is CURRENT_TIMESTAMP) to
          // the type of the column.  Here we capture the type of the
          // column. COM_CURRENT_DEFAULT is only used for Datetime
          // columns.
          //
          if (nacol->getDefaultClass() == COM_CURRENT_DEFAULT) {
            castType = nacol->getType()->newCopy(bindWA->wHeap());
            omittedCurrentDefaultClassCols = TRUE;
            omittedDefaultCols = TRUE;
          }
          else if ((nacol->getDefaultClass() == COM_IDENTITY_GENERATED_ALWAYS) ||
                   (nacol->getDefaultClass() == COM_IDENTITY_GENERATED_BY_DEFAULT)) {
            setSystemGeneratesIdentityValue(TRUE);
          }
          else if (nacol->getDefaultClass() != COM_NO_DEFAULT)
            omittedDefaultCols = TRUE;

          // Bind the default value, make an Assign, etc, as above
          Parser parser(bindWA->currentCmpContext());

          // save the current parserflags setting
          ULng32 savedParserFlags = Get_SqlParser_Flags (0xFFFFFFFF);
          Set_SqlParser_Flags(INTERNAL_QUERY_FROM_EXEUTIL);
          Set_SqlParser_Flags(ALLOW_VOLATILE_SCHEMA_IN_TABLE_NAME);

          defaultValueExpr = parser.getItemExprTree(defaultValueStr);
          CMPASSERT(defaultValueExpr);

          // Restore parser flags settings to what they originally were
          Assign_SqlParser_Flags (savedParserFlags);
	} // defaultValueStr != NULL

	Assign *assign = NULL;
	
	// If the default value string was successfully parsed,
	// Create an ASSIGN node and bind.
        //
        if (defaultValueExpr) {

          // If there is a non-NULL castType, then cast the default
          // value to the castType.  This is used in the case of
          // datetime value with COM_CURRENT_DEFAULT.  The default
          // value will be CURRENT_TIMESTAMP for all datetime types,
          // so must cast the CURRENT_TIMESTAMP to the type of the
          // column.
          //
          if(castType) {
            defaultValueExpr = new (bindWA->wHeap())
              Cast(defaultValueExpr, castType);
          }

          // system generates value for IDENTITY column.
          if (defaultValueExpr->getOperatorType() == ITM_IDENTITY &&
              (CmpCommon::getDefault(COMP_BOOL_210) == DF_ON))
            {
              // SequenceGenerator::createSequenceSubqueryExpression()
              // is called for introducing the subquery in
              // defaultValueExpr::bindNode() (IdentityVar::bindNode()).
              // We bind here to make sure the correct subquery
              // is used.
              defaultValueExpr = defaultValueExpr->bindNode(bindWA);
            }

	  if (((isUpsertLoad()) ||
               ((isUpsert()) && (getTableDesc()->getNATable()-> isSQLMXAlignedTable()))) &&
              (NOT defaultValueExpr->getOperatorType() == ITM_IDENTITY) &&
	      (NOT isASystemColumn))
	    {
	      // for 'upsert using load' construct, all values must be specified so
	      // data could be loaded using inserts.
	      // If some values are missing, then it becomes an update.
	      *CmpCommon::diags() << DgSqlCode(-4246) ;
	      bindWA->setErrStatus();

	      return boundExpr;
	    }
          assign = new (bindWA->wHeap())
            Assign(target.getItemExpr(), defaultValueExpr,
                    FALSE /*Not user Specified */);
          if ((nacol->getDefaultClass() != COM_CURRENT_DEFAULT) &&
              (nacol->getDefaultClass() != COM_USER_FUNCTION_DEFAULT))
             assign->setToBeSkipped(TRUE);
          assign->bindNode(bindWA);
        }

        //
        // Note: Parser or Binder errors from MP texts are possible.
        //
        if (!defaultValueExpr || bindWA->errStatus()) {
            // 7001 Error preparing default on <column> for <table>.
            *CmpCommon::diags() << DgSqlCode(-7001)
                                << DgString0(defaultValueStr)
                                << DgString1(nacol->getFullColRefNameAsAnsiString());
            bindWA->setErrStatus();
            return boundExpr;
          }

	newRecExprArray().insertAt(i, assign->getValueId());
	newRecExpr().insert(assign->getValueId());
	updateToSelectMap().addMapEntry(target,defaultValueExpr->getValueId());

	if (needToDeallocateColDefaultValueStr && defaultValueStr != NULL)
	  {
	    NADELETEBASIC((NAWchar*)defaultValueStr, bindWA->wHeap());
	    defaultValueStr = NULL;
	  }

        if (--defaultColCount == 0)
          break;  // tiny performance hack

      }   // NOT newRecExprArray().used(i)
      else 
      {
        if (nacol->getDefaultClass() == COM_IDENTITY_GENERATED_ALWAYS)
          {
            Assign * assign = (Assign*)newRecExprArray()[i].getItemExpr();
            ItemExpr * ie = assign->getSource().getItemExpr();
            if (NOT ie->wasDefaultClause())
              {
                *CmpCommon::diags() << DgSqlCode(-3428)
                                    << DgString0(nacol->getColName());
                bindWA->setErrStatus();
                return boundExpr;
              }
          }
      }
      
      if (isASystemColumn)
        sysColIx++;
      else
        usrColIx++;
    }   // for i < totalColCount
  }   // defaultColCount

  // Now add the default values created as part of the Assigns above
  // to the charcteristic inputs. The user specified values are added
  // to the characteristic inputs during GenericUpdate::bindNode
  // executed earlier as part of this method.
  getGroupAttr()->addCharacteristicInputs(bindWA->
                                          getCurrentScope()->
                                          getOuterRefs());


  if (isRRTable) {
// LCOV_EXCL_START -
    const LIST(IndexDesc *) indexes = getTableDesc()->getIndexes();
    for(i = 0; i < indexes.entries(); i++) {
      indexes[i]->getPartitioningFunction()->setAssignPartition(TRUE);
    }
// LCOV_EXCL_STOP
  }

  // It is a system generated identity value if
  // identityColumn() != NULL_VALUE_ID. The identityColumn()
  // is set two places (1) earlier in this method.
  // (2) DefaultSpecification::bindNode()

  // The IDENTITY column of type GENERATED ALWAYS AS IDENTITY
  // must be specified in the values list as (DEFAULT) or
  // must be excluded from the values list forcing the default.

  if (identityColumnGeneratedAlways &&
      NOT systemGeneratesIdentityValue())
    {
      // The IDENTITY column type of GENERATED ALWAYS AS IDENTITY
      // can not be used with user specified values.
      // However, if the override CQD is set, then
      // allow user specified values to be added
      // for a GENERATED ALWAYS AS IDENTITY column.

      if (CmpCommon::getDefault(OVERRIDE_GENERATED_IDENTITY_VALUES) == DF_OFF)
        {
          *CmpCommon::diags() << DgSqlCode(-3428)
                              << DgString0(identityColumnName.data());
           bindWA->setErrStatus();
           return boundExpr;
        }
    }

  ItemExpr *orderByTree = removeOrderByTree();
  if (orderByTree) {
    bindWA->getCurrentScope()->context()->inOrderBy() = TRUE;
    bindWA->getCurrentScope()->setRETDesc(child(0)->getRETDesc());
    orderByTree->convertToValueIdList(reqdOrder(), bindWA, ITM_ITEM_LIST);

    bindWA->getCurrentScope()->context()->inOrderBy() = FALSE;
    if (bindWA->errStatus()) return NULL;
    bindWA->getCurrentScope()->setRETDesc(getRETDesc());
  }

  setInUpdateOrInsert(bindWA);

  // Triggers --
  NABoolean insertFromValuesList =
    getOperatorType() == REL_UNARY_INSERT &&
    (child(0)->getOperatorType() == REL_TUPLE || // VALUES (1,'b')
    child(0)->getOperatorType() == REL_TUPLE_LIST || // VALUES (1,'b'),(2,'Y')
    child(0)->getOperatorType() == REL_UNION);       // VALUES with subquery

  // Insert from values that gets input from above should not use flow,
  // for performance. Cases, other than TUPLE, should be investigated.
  if (bindWA->findNextScopeWithTriggerInfo() != NULL
      && (getGroupAttr()->getCharacteristicInputs() != NULL)
      && (insertFromValuesList))
    setNoFlow(TRUE);

  if (getUpdateCKorUniqueIndexKey())
  {
    SqlTableOpenInfo * scanStoi = getLeftmostScanNode()->getOptStoi()->getStoi();
    short updateColsCount = scanStoi->getColumnListCount();
    getOptStoi()->getStoi()->setColumnListCount(updateColsCount);
    getOptStoi()->getStoi()->setColumnList(new (bindWA->wHeap()) short[updateColsCount]);
      for (short i=0; i<updateColsCount; i++)
        getOptStoi()->getStoi()->setUpdateColumn(i,scanStoi->getUpdateColumn(i));
  }
   
  if ((getIsTrafLoadPrep()) &&
      (getTableDesc()->getCheckConstraints().entries() != 0 ||
          getTableDesc()->getNATable()->getRefConstraints().entries() != 0  ))
  {
    // enabling/disabling constraints is not supported yet
    //4486--Constraints not supported with bulk load. Disable the constraints and try again.
    *CmpCommon::diags() << DgSqlCode(-4486)
                        <<  DgString0("bulk load") ;
  }
  if (getIsTrafLoadPrep())
  {
    PartitioningFunction *pf = getTableDesc()->getClusteringIndex()->getPartitioningFunction();

    const NodeMap* np;
    Lng32 partns = 1;
    if ( pf && (np = pf->getNodeMap()) )
      {
        partns = np->getNumEntries();
        if(partns > 1  && CmpCommon::getDefault(ATTEMPT_ESP_PARALLELISM) == DF_OFF)
          // 4490 - BULK LOAD into a salted table is not supported if ESP parallelism is turned off
          *CmpCommon::diags() << DgSqlCode(-4490);
      }
  }
  NABoolean toMerge = FALSE;
  if (isUpsertThatNeedsTransformation(isAlignedRowFormat, omittedDefaultCols, omittedCurrentDefaultClassCols,toMerge)) {
    if ((CmpCommon::getDefault(TRAF_UPSERT_TO_EFF_TREE) == DF_OFF) ||toMerge)	
      {
	boundExpr = xformUpsertToMerge(bindWA);  
	return boundExpr;
      }
    else 
      boundExpr = xformUpsertToEfficientTree(bindWA);
    
    
  }
  if (NOT (isMerge() || noIMneeded()))
    boundExpr = handleInlining(bindWA, boundExpr);

  // turn OFF Non-atomic Inserts for ODBC if we have detected that Inlining is needed
  // necessary warnings have been generated in handleInlining method.
  if (CmpCommon::getDefault(ODBC_PROCESS) == DF_ON) {
    if (bindWA->getHostArraysArea() &&
	(NOT bindWA->getHostArraysArea()->getRowwiseRowset()) &&
	!(bindWA->getHostArraysArea()->getTolerateNonFatalError()))
      setTolerateNonFatalError(RelExpr::UNSPECIFIED_);
  }
  
  
  // When mtsStatement_ or bulkLoadIndex is set Insert needs to return rows;
  // so potential outputs are added (note that it's not replaced) to 
  // the Insert node. Currently mtsStatement_ is set
  // for MTS queries and embedded insert queries.
  if (isMtsStatement() || bulkLoadIndex)
    {
      if(isMtsStatement())
        setRETDesc(new (bindWA->wHeap()) RETDesc(bindWA, getTableDesc()));

      bindWA->getCurrentScope()->setRETDesc(getRETDesc());

      ValueIdList outputs;
      getRETDesc()->getValueIdList(outputs, USER_AND_SYSTEM_COLUMNS);
      ValueIdSet potentialOutputs;
      getPotentialOutputValues(potentialOutputs);
      potentialOutputs.insertList(outputs); 
      setPotentialOutputValues(potentialOutputs);

      // this flag is set to indicate optimizer not to pick the
      // TupleFlow operator
      setNoFlow(TRUE);
    }

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

/* Upsert into a table with an index is converted into a Merge to avoid
the problem described in Trafodion-14. An upsert may overwrite an existing row
in the base table (identical to the update when matched clause of Merge) or
it may insert a new row into the base table (identical to insert when not
matched clause of merge). If the upsert caused a row to be updated in the 
base table then the old version of the row will have to be deleted from 
indexes, and a new version inserted. Upsert is being transformed to merge
so that we can delete the old version of an updated row from the index.

Upsert is also converted into merge when TRAF_UPSERT_MODE is set to MERGE and 
there are omitted cols with default values in case of aligned format table or 
omitted current timestamp cols in case of non-aligned row format
*/
NABoolean Insert::isUpsertThatNeedsTransformation(NABoolean isAlignedRowFormat, 
                                                  NABoolean omittedDefaultCols,
                                                  NABoolean omittedCurrentDefaultClassCols,
                                                  NABoolean &toMerge) const
{
  toMerge = FALSE;
  // If the the table has an identity column in clustering key or has a syskey 
  // we dont need to do this transformation.The incoming row will always be 
  // unique. So first check if we any of the conditions are satisfied to 
  //even try the transform
  NABoolean mustTryTransform = FALSE;
  if (isUpsert() && 
      NOT ( getIsTrafLoadPrep() ||
            ( (getTableDesc()->isIdentityColumnGeneratedAlways() && 
               getTableDesc()->hasIdentityColumnInClusteringKey()))  || 
            ((getTableDesc()->getClusteringIndex()->getNAFileSet()->hasSyskey()))))
    {
      mustTryTransform = TRUE;
    }

  // Transform upsert to merge in case of special modes and
  // omitted default columns
  // Case 1 :  CQD is set to MERGE, omitted current(timestamp) default 
  //           columns with  non-aligned row format table or omitted 
  //           default columns with aligned row format tables 

  // Case 2 :  CQD is set to Optimal, for non-aligned row format with omitted 
  //           current(timestamp) columns, it is converted into merge 
  //           though it is not optimal for performance. This is done to ensure
  //           that when the CQD is set to optimal, non-aligned format would 
  //           behave like merge when any column is  omitted 
  if (isUpsert()  &&   
      mustTryTransform &&          
      ((CmpCommon::getDefault(TRAF_UPSERT_MODE) == DF_MERGE) &&     
       (((NOT isAlignedRowFormat) && omittedCurrentDefaultClassCols) ||
        (isAlignedRowFormat && omittedDefaultCols)))
      ||
      ((CmpCommon::getDefault(TRAF_UPSERT_MODE) == DF_OPTIMAL) &&
       ((NOT isAlignedRowFormat) && omittedCurrentDefaultClassCols)))
    {
      toMerge = TRUE;
      return TRUE;
    }

  // Transform upsert to efficient tree if none of the above conditions 
  // are true and the table has secondary indexes 
  if (isUpsert() &&  
      mustTryTransform &&
      (getTableDesc()->hasSecondaryIndexes()))
    {
      toMerge = FALSE;
      return TRUE;
    }
  
  return FALSE;
}

/** commenting the following method out for future work. This may be enabled 
as a further performance improvement if we can eliminate the sort node that 
gets geenrated as part of the Sequence Node. In case of no duplicates we won't
 need the Sequence node at all. 

// take an insert(src) node and transform it into
// a tuple_flow with old/new rows flowing to the IM tree.
// with a newly created input_scan
RelExpr* Insert::xformUpsertToEfficientTreeNoDup(BindWA *bindWA) 
{
  NATable *naTable = bindWA->getNATable(getTableName());
  if (bindWA->errStatus())
    return NULL;
  if ((naTable->getViewText() != NULL) && (naTable->getViewCheck()))		
    {		
      *CmpCommon::diags() << DgSqlCode(-3241) 		
			  << DgString0(" View with check option not allowed.");	    		
      bindWA->setErrStatus();		
      return NULL;		
    }

  RelExpr *topNode = this;
  // Create a new BindScope, to encompass the new nodes 
  // upsert(left_join(input_scan, tuple))
  // and any inlining nodes that will be created. Any values the upsert
  // and children will need from src will be marked as outer references in that
  // new BindScope. We assume that "src" is already bound.
  ValueIdSet currOuterRefs = bindWA->getCurrentScope()->getOuterRefs();

  CMPASSERT(child(0)->nodeIsBound());

  BindScope *upsertScope = bindWA->getCurrentScope();

  // columns of the target table
  const ValueIdList &tableCols = updateToSelectMap().getTopValues();
  const ValueIdList &sourceVals = updateToSelectMap().getBottomValues();

  // create a Join node - left join of the base table columns with the columns to be upserted.
  // columns of the target table
  CMPASSERT(child(0)->nodeIsBound());
  
  Scan * targetTableScan =
    new (bindWA->wHeap())
    Scan(CorrName(getTableDesc()->getCorrNameObj(), bindWA->wHeap()));

 
  //join predicate between source columns and target table.
  ItemExpr * keyPred = NULL;
  ItemExpr * keyPredPrev = NULL;
  BaseColumn* baseCol;
  ColReference * targetColRef;
  int predCount = 0;
  ValueIdSet newOuterRefs;
  ItemExpr * pkeyValPrev;
  ItemExpr * pkeyVals;
  for (CollIndex i = 0; i < tableCols.entries(); i++)
    {
      baseCol = (BaseColumn *)(tableCols[i].getItemExpr()) ;
      if (baseCol->getNAColumn()->isSystemColumn())
	continue;

      targetColRef = new(bindWA->wHeap()) ColReference(
						       new(bindWA->wHeap()) ColRefName(
										       baseCol->getNAColumn()->getFullColRefName(), bindWA->wHeap()));
    

      if (baseCol->getNAColumn()->isClusteringKey())
	{
	  // create a join/key predicate between source and target table,
	  // on the clustering key columns of the target table, making
	  // ColReference nodes for the target table, so that we can bind
	  // those to the new scan
	  keyPredPrev = keyPred;
	  keyPred = new (bindWA->wHeap())
	    BiRelat(ITM_EQUAL, targetColRef, 
		    sourceVals[i].getItemExpr(),
		    baseCol->getType().supportsSQLnull());
	  predCount++;
	  if (predCount > 1) 
	    {
	      keyPred = new(bindWA->wHeap()) BiLogic(ITM_AND,
						     keyPredPrev,
						     keyPred);  
	    }
	  pkeyValPrev = pkeyVals;
    
	  pkeyVals = tableCols[i].getItemExpr();
	  if (i > 0) 
	    {
	      pkeyVals = new(bindWA->wHeap()) ItemList(pkeyVals,pkeyValPrev);
      
	    }
	}
     
    }
 
  // Map the table's primary key values to the source lists key values
  ValueIdList tablePKeyVals = NULL;
  ValueIdList sourcePKeyVals = NULL;
  
  pkeyVals->convertToValueIdList(tablePKeyVals,bindWA,ITM_ITEM_LIST);
  updateToSelectMap().mapValueIdListDown(tablePKeyVals,sourcePKeyVals);
  
  Join *lj = new(bindWA->wHeap()) Join(child(0),targetTableScan,REL_LEFT_JOIN,keyPred);
  lj->doNotTransformToTSJ();	  
  lj->setTSJForWrite(TRUE);
   bindWA->getCurrentScope()->xtnmStack()->createXTNM();
  RelExpr *boundLJ = lj->bindNode(bindWA);
  if (bindWA->errStatus())
    return NULL;
  bindWA->getCurrentScope()->xtnmStack()->removeXTNM();
  setChild(0,boundLJ);
  topNode = handleInlining(bindWA,topNode);


  return topNode; 
}
*/

// take an insert(src) node and transform it into
// a tuple_flow with old/new rows flowing to the IM tree.
// with a newly created sequence node used to eliminate duplicates.
/*
               NJ
            /      \
         Sequence   NJ
        /            \  
     Left Join        IM Tree 
     /        \
    /          \
Input Tuplelist  Target Table Scan
or select list
*/
         
RelExpr* Insert::xformUpsertToEfficientTree(BindWA *bindWA) 
{
  NATable *naTable = bindWA->getNATable(getTableName());
  if (bindWA->errStatus())
    return NULL;
  if ((naTable->getViewText() != NULL) && (naTable->getViewCheck()))		
    {		
      *CmpCommon::diags() << DgSqlCode(-3241) 		
			  << DgString0(" View with check option not allowed.");	    		
      bindWA->setErrStatus();		
      return NULL;		
    }

  RelExpr *topNode = this;
 
  CMPASSERT(child(0)->nodeIsBound());

  BindScope *upsertScope = bindWA->getCurrentScope();
  // Create a new BindScope, to encompass the new nodes 
  // upsert(left_join(input_scan, tuple))
  // and any inlining nodes that will be created. Any values the upsert
  // and children will need from src will be marked as outer references in that
  // new BindScope. We assume that "src" is already bound.
  ValueIdSet currOuterRefs = bindWA->getCurrentScope()->getOuterRefs();
  // Save the current RETDesc.
  RETDesc *prevRETDesc = bindWA->getCurrentScope()->getRETDesc();

  // columns of the target table
  const ValueIdList &tableCols = updateToSelectMap().getTopValues();
  const ValueIdList &sourceVals = updateToSelectMap().getBottomValues();

  // create a Join node - left join of the base table columns with the columns to be upserted.
  // columns of the target table
  CMPASSERT(child(0)->nodeIsBound());
  
  Scan * targetTableScan =
    new (bindWA->wHeap())
    Scan(CorrName(getTableDesc()->getCorrNameObj(), bindWA->wHeap()));

   bindWA->getCurrentScope()->context()->inUpsertXform() = TRUE;
  //join predicate between source columns and target table.
  ItemExpr * keyPred = NULL;
  ItemExpr * keyPredPrev = NULL;
  BaseColumn* baseCol;
  ColReference * targetColRef;
  int predCount = 0;
  ValueIdSet newOuterRefs;
  ItemExpr * pkeyValPrev = NULL;
  ItemExpr * pkeyVals = NULL;
  for (CollIndex i = 0; i < tableCols.entries(); i++)
    {
      baseCol = (BaseColumn *)(tableCols[i].getItemExpr()) ;
      if (baseCol->getNAColumn()->isSystemColumn())
	continue;

      targetColRef = new(bindWA->wHeap()) ColReference(
           new(bindWA->wHeap()) ColRefName(
                baseCol->getNAColumn()->getFullColRefName(),
                bindWA->wHeap()));
    

      if (baseCol->getNAColumn()->isClusteringKey())
	{
	  // create a join/key predicate between source and target table,
	  // on the clustering key columns of the target table, making
	  // ColReference nodes for the target table, so that we can bind
	  // those to the new scan
	  keyPredPrev = keyPred;
	  keyPred = new (bindWA->wHeap())
	    BiRelat(ITM_EQUAL, targetColRef, 
		    sourceVals[i].getItemExpr(),
		    baseCol->getType().supportsSQLnull());
	  predCount++;
	  if (predCount > 1) 
	    {
	      keyPred = new(bindWA->wHeap()) BiLogic(ITM_AND,
						     keyPredPrev,
						     keyPred);  
	    }
          
          pkeyValPrev = pkeyVals;
    
	  pkeyVals = tableCols[i].getItemExpr();
	  
	  if (pkeyValPrev != NULL ) 
	    {
	      pkeyVals = new(bindWA->wHeap()) ItemList(pkeyVals,pkeyValPrev);
      
	    }
	}
     
    }
 
  // Map the table's primary key values to the source lists key values
  ValueIdList tablePKeyVals ;
  ValueIdList sourcePKeyVals ;
  
  pkeyVals->convertToValueIdList(tablePKeyVals,bindWA,ITM_ITEM_LIST);
  updateToSelectMap().mapValueIdListDown(tablePKeyVals,sourcePKeyVals);
  
  Join *lj = new(bindWA->wHeap()) Join(child(0),targetTableScan,REL_LEFT_JOIN,keyPred);

  bindWA->getCurrentScope()->xtnmStack()->createXTNM();

  
  RelExpr *boundLJ = lj->bindNode(bindWA);
  if (bindWA->errStatus())
    return NULL;
  bindWA->getCurrentScope()->xtnmStack()->removeXTNM();
 
  ValueId nullInstIndicator(
       lj->addNullInstIndicatorVar(
            bindWA,
            new(bindWA->wHeap()) SystemLiteral(
                 "U",
                 CharInfo::ISO88591)));
  ValueIdSet sequenceFunction ;		
 
  //Retrieve all the system and user columns of the left join output
  ValueIdList  ljOutCols = NULL;
  boundLJ->getRETDesc()->getValueIdList(ljOutCols);
  //Retrieve the null instantiated part of the LJ output
  ValueIdList ljNullInstColumns = lj->nullInstantiatedOutput();
  
  //Create the olap node and use the primary key of the table as the 
  //"partition by" columns for the olap node.
  CMPASSERT(!bindWA->getCurrentScope()->getSequenceNode());
  RelSequence *seqNode = new(bindWA->wHeap()) RelSequence(boundLJ, sourcePKeyVals.rebuildExprTree(ITM_ITEM_LIST),  (ItemExpr *)NULL);
 

  // Create a LEAD Item Expr for a random value 999. 
  // Use this to eliminate rows which have a NULL for this LEAD value within 
  // a particular partition range.
  ItemExpr *leadItem, *boundLeadItem = NULL;
  ItemExpr *constLead999 = new (bindWA->wHeap()) ConstValue( 999);

  leadItem = new(bindWA->wHeap()) ItmLeadOlapFunction(constLead999,1);
  ((ItmLeadOlapFunction *)leadItem)->setIsOLAP(TRUE);
  boundLeadItem = leadItem->bindNode(bindWA);
  if (bindWA->errStatus()) return this;
  boundLeadItem->convertToValueIdSet(sequenceFunction);
  seqNode->setSequenceFunctions(sequenceFunction);
  
  // Add a selection predicate (post predicate) to check if the LEAD item is NULL
  ItemExpr *selPredOnLead = NULL;
  selPredOnLead = new (bindWA->wHeap()) UnLogic(ITM_IS_NULL,leadItem);
  selPredOnLead = selPredOnLead->bindNode(bindWA);
  if (bindWA->errStatus()) return this;
  seqNode->selectionPred() += selPredOnLead->getValueId();
  seqNode->setChild(0,boundLJ);

  RelExpr *boundSeqNode = seqNode->bindNode(bindWA);  
   
  setChild(0,boundSeqNode);

  // Fixup the newRecExpr() and newRecExprArray() to refer to the new 
  // valueIds of the new child - i.e RelSequence. Use the saved off valueIdMap
  // from the current bindScope for this.
  ValueIdSet newNewRecExpr;
  ValueIdMap notCoveredMap = bindWA->getCurrentScope()->getNcToOldMap();
  notCoveredMap.rewriteValueIdSetUp(newNewRecExpr, newRecExpr());
  newRecExpr() = newNewRecExpr;
  
  ValueIdList oldRecArrList(newRecExprArray());
  ValueIdList newRecArrList;
  notCoveredMap.rewriteValueIdListUp(newRecArrList, oldRecArrList);
  ValueIdArray newNewRecArray(newRecArrList.entries());
  
  for (CollIndex i = 0; i < newRecArrList.entries(); i++)
    {
      newNewRecArray.insertAt(i,newRecArrList.at(i));
    }
  newRecExprArray() = newNewRecArray;

  ValueId notCoveredNullInstIndicator;

  notCoveredMap.rewriteValueIdUp(notCoveredNullInstIndicator,
                                 nullInstIndicator);
  ItemExpr *nvl = new(bindWA->wHeap()) BuiltinFunction(
         ITM_NVL,
         bindWA->wHeap(),
         2,
         notCoveredNullInstIndicator.getItemExpr(),
         new(bindWA->wHeap()) SystemLiteral("I",
                                            CharInfo::ISO88591));
  nvl = nvl->bindNode(bindWA);
  setProducedMergeIUDIndicator(nvl->getValueId());

  setXformedEffUpsert(TRUE);
  bindWA->getCurrentScope()->context()->inUpsertXform() =  FALSE;
  return topNode; 
}


// take an insert(src) node and transform it into
// tsj_flow(src, merge_update(input_scan))
// with a newly created input_scan
RelExpr* Insert::xformUpsertToMerge(BindWA *bindWA) 
{
  NATable *naTable = bindWA->getNATable(getTableName());
  if (bindWA->errStatus())
    return NULL;
  if ((naTable->getViewText() != NULL) && (naTable->getViewCheck()))		
  {		
    *CmpCommon::diags() << DgSqlCode(-3241) 		
			<< DgString0(" View with check option not allowed.");	    		
    bindWA->setErrStatus();		
    return NULL;		
  }

  // columns of the target table
  const ValueIdList &tableCols = updateToSelectMap().getTopValues();
  const ValueIdList &sourceVals = updateToSelectMap().getBottomValues();

  NABoolean isAlignedRowFormat = getTableDesc()->getNATable()->isSQLMXAlignedTable();
		    
  // Create a new BindScope, to encompass the new nodes merge_update(input_scan)
  // and any inlining nodes that will be created. Any values the merge_update
  // and children will need from src will be marked as outer references in that
  // new BindScope. We assume that "src" is already bound.
  ValueIdSet currOuterRefs = bindWA->getCurrentScope()->getOuterRefs();

  CMPASSERT(child(0)->nodeIsBound());
  bindWA->initNewScope();
  BindScope *mergeScope = bindWA->getCurrentScope();

  // create a new scan of the target table, to be used in the merge
  Scan * inputScan =
    new (bindWA->wHeap())
    Scan(CorrName(getTableDesc()->getCorrNameObj(), bindWA->wHeap()));

  ItemExpr * keyPred = NULL;
  ItemExpr * keyPredPrev = NULL;
  ItemExpr * setAssign = NULL;
  ItemExpr * setAssignPrev = NULL;
  ItemExpr * insertVal = NULL;
  ItemExpr * insertValPrev = NULL;
  ItemExpr * insertCol = NULL;
  ItemExpr * insertColPrev = NULL;
  BaseColumn* baseCol;
  ColReference * targetColRef;
  int predCount = 0;
  int setCount = 0;
  ValueIdSet newOuterRefs;

  // loop over the columns of the target table
  for (CollIndex i = 0; i<tableCols.entries(); i++)
  {
    baseCol = (BaseColumn *)(tableCols[i].getItemExpr()) ;
    if (baseCol->getNAColumn()->isSystemColumn())
      continue;

    targetColRef = new(bindWA->wHeap()) ColReference(
         new(bindWA->wHeap()) ColRefName(
              baseCol->getNAColumn()->getFullColRefName(), bindWA->wHeap()));
    if (baseCol->getNAColumn()->isClusteringKey())
    {
      // create a join/key predicate between source and target table,
      // on the clustering key columns of the target table, making
      // ColReference nodes for the target table, so that we can bind
      // those to the new scan
      keyPredPrev = keyPred;
      keyPred = new (bindWA->wHeap())
        BiRelat(ITM_EQUAL, targetColRef, 
                sourceVals[i].getItemExpr(),
                baseCol->getType().supportsSQLnull());
      predCount++;
      if (predCount > 1) 
      {
         keyPred = new(bindWA->wHeap()) BiLogic(ITM_AND,
                                                keyPredPrev,
                                                keyPred);  
      }

    }
    if (sourceVals[i].getItemExpr()->getOperatorType() != ITM_CONSTANT)
      {
        newOuterRefs += sourceVals[i];
        mergeScope->addOuterRef(sourceVals[i]);
      }

    // create the INSERT (WHEN NOT MATCHED) part of the merge for this column, again
    // with a ColReference that we will then bind to the MergeUpdate target table
    insertValPrev = insertVal;
    insertColPrev = insertCol ;
    insertVal = sourceVals[i].getItemExpr();
    insertCol =  new(bindWA->wHeap()) ColReference(
                     new(bindWA->wHeap()) ColRefName(
                          baseCol->getNAColumn()->getFullColRefName(), bindWA->wHeap()));
    if (i > 0) 
    {
      insertVal = new(bindWA->wHeap()) ItemList(insertVal,insertValPrev);
      insertCol = new(bindWA->wHeap()) ItemList(insertCol,insertColPrev);
    }
  }
  inputScan->addSelPredTree(keyPred);
  for (CollIndex i = 0 ; i < newRecExprArray().entries(); i++) 
  {
      const Assign *assignExpr = (Assign *)newRecExprArray()[i].getItemExpr();
      ValueId tgtValueId = assignExpr->child(0)->castToItemExpr()->getValueId();
      NAColumn *col = tgtValueId.getNAColumn( TRUE );
      NABoolean copySetAssign = FALSE;
      if (col->isSystemColumn())
         continue;
      else
      if (! col->isClusteringKey()) 
      {
         // Create the UPDATE (WHEN MATCHED) part of the new MergeUpdate for
         // a non-key column. We need to bind in the new = old values
         // in GenericUpdate::bindNode. So skip the columns that are not user
         // specified. Note that we had a discussion on whether such a transformed
         // UPSERT shouldn't update all columns.
         //
         if (assignExpr->isUserSpecified())
             copySetAssign = TRUE;
         // If copy the Default values in case of replace mode or optiomal mode with
         // aligned row tables
         else if ((CmpCommon::getDefault(TRAF_UPSERT_MODE) == DF_REPLACE) ||
                (isAlignedRowFormat && CmpCommon::getDefault(TRAF_UPSERT_MODE) == DF_OPTIMAL))
             copySetAssign = TRUE;
         if (copySetAssign)
         { 
            setAssignPrev = setAssign;
            setAssign = (ItemExpr *)assignExpr;
            setCount++;
            if (setCount > 1) 
               setAssign = new(bindWA->wHeap()) ItemList(setAssignPrev, setAssign);
         }
     }
  }
  MergeUpdate *mu = new (bindWA->wHeap())
    MergeUpdate(CorrName(getTableDesc()->getCorrNameObj(), bindWA->wHeap()),
                NULL,
                REL_UNARY_UPDATE,
                inputScan, // USING
                setAssign, // WHEN MATCHED THEN UPDATE
                insertCol, // WHEN NOT MATCHED THEN INSERT (cols) ...
                insertVal, // ... VALUES()
                bindWA->wHeap(),
                NULL);

  mu->setXformedUpsert();
  // Use mergeScope, the scope we created here, for the MergeUpdate. We are
  // creating some expressions with outer references here in this method, so
  // we need to control the scope from here.
  mu->setNeedsBindScope(FALSE);

  RelExpr *boundMU = mu->bindNode(bindWA);

  // remove the BindScope created earlier in this method
  bindWA->removeCurrentScope();

  // Remove the outer refs from the parent scope, they are provided
  // by the left child of the TSJ_FLOW, unless they were already outer refs
  // when we started this method. The binder logic doesn't handle
  // that well, since they come from a child scope, not the current one,
  // so we help a little.
  newOuterRefs -= currOuterRefs;
  bindWA->getCurrentScope()->removeOuterRefs(newOuterRefs);

  Join * jn = new(bindWA->wHeap()) Join(child(0), boundMU, REL_TSJ_FLOW, NULL);

  jn->doNotTransformToTSJ();
  jn->setTSJForMerge(TRUE);	
  jn->setTSJForMergeWithInsert(TRUE);
  jn->setTSJForMergeUpsert(TRUE);
  jn->setTSJForWrite(TRUE);

  RelExpr *result = jn->bindNode(bindWA);
  if (bindWA->errStatus())
    return NULL;
  // Copy the userSecified and canBeSkipped attribute to mergeUpdateInsertExprArray
  ValueIdList mergeInsertExprArray = mu->mergeInsertRecExprArray();
  for (CollIndex i = 0 ; i < newRecExprArray().entries(); i++) 
  {
      const Assign *assignExpr = (Assign *)newRecExprArray()[i].getItemExpr();
      ((Assign *)mergeInsertExprArray[i].getItemExpr())->setToBeSkipped(assignExpr->canBeSkipped());
      ((Assign *)mergeInsertExprArray[i].getItemExpr())->setUserSpecified(assignExpr->isUserSpecified());
  }
 
  return result;
}

RelExpr *HBaseBulkLoadPrep::bindNode(BindWA *bindWA)
{
  //CMPASSERT((CmpCommon::getDefault(TRAF_LOAD) == DF_ON &&
   //   CmpCommon::getDefault(TRAF_LOAD_HFILE) == DF_ON));
  if (nodeIsBound())
  {
    return this;
  }

  Insert * newInsert = new (bindWA->wHeap())
                            Insert(getTableName(),
                                   NULL,
                                   REL_UNARY_INSERT,
                                   child(0)->castToRelExpr());


  newInsert->setInsertType(UPSERT_LOAD);
  newInsert->setIsTrafLoadPrep(true);
  newInsert->setCreateUstatSample(getCreateUstatSample());

  // Pass the flag to bindWA to guarantee that a range partitioning is 
  // always used for all source and target tables.
  bindWA->setIsTrafLoadPrep(TRUE);

  RelExpr *boundNewInsert = newInsert->bindNode(bindWA);

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

  return boundNewInsert;



}

// This is a callback from DefaultSpecification::bindNode
// called from Insert::bindNode
// (you need to understand the latter to understand this).
//
const char *Insert::getColDefaultValue(BindWA *bindWA, CollIndex i) const
{
  CMPASSERT(canBindDefaultSpecification());

  CollIndexList &colnoList = *targetUserColPosList_;
  CollIndex pos = colnoList.entries() ? colnoList[i] : i;

  const ValueIdList &colList = getTableDesc()->getColumnList();

  if (colList.entries() <= pos) {
    // 4023 degree of row value constructor must equal that of target table
    *CmpCommon::diags() << DgSqlCode(-4023)
#pragma nowarn(1506)   // warning elimination
                        << DgInt0(++pos)
#pragma warn(1506)  // warning elimination
#pragma nowarn(1506)   // warning elimination
                        << DgInt1(colList.entries());
#pragma warn(1506)  // warning elimination
    bindWA->setErrStatus();
    return NULL;
  }

  ValueId target = colList[pos];
  const NAColumn *nacol = target.getNAColumn();
  const char* defaultValueStr = nacol->getDefaultValue();
  
  CharInfo::CharSet mapCS = CharInfo::ISO88591;
  NABoolean mapCS_hasVariableWidth = CharInfo::isVariableWidthMultiByteCharSet(mapCS);
  size_t defaultValueWcsLen = 0;
  NAWchar *defaultValueWcs = (NAWchar *) defaultValueStr;
  NABoolean ucs2StrLitPrefix = FALSE;

  if (nacol->getDefaultClass() == COM_USER_DEFINED_DEFAULT &&
      nacol->getType() &&
      nacol->getType()->getTypeQualifier() == NA_CHARACTER_TYPE &&
      ((CharType*)(nacol->getType()))->getCharSet() == CharInfo::ISO88591 &&
      mapCS_hasVariableWidth &&
      defaultValueWcs != NULL &&
      nacol->getNATable()->getObjectSchemaVersion() >= COM_VERS_2300 &&
      (defaultValueWcsLen = NAWstrlen(defaultValueWcs)) > 6 &&
      ( ( ucs2StrLitPrefix = ( NAWstrncmp(defaultValueWcs, NAWSTR("_UCS2\'"), 6) == 0 )) ||
        ( defaultValueWcsLen > 10 &&
          NAWstrncmp(defaultValueWcs, NAWSTR("_ISO88591\'"), 10) == 0 )) &&
      defaultValueWcs[defaultValueWcsLen-1] == NAWCHR('\''))
  {
    NAWcharBuf *pWcharBuf = NULL;
    if (ucs2StrLitPrefix)
    {
      // Strip the leading _UCS2 prefix.
      pWcharBuf =
        new (bindWA->wHeap()) NAWcharBuf(&defaultValueWcs[5],
                                         defaultValueWcsLen - 5,
                                         bindWA->wHeap());
    }
    else
    {
      // Keep the leading _ISO88591 prefix.
      pWcharBuf =
        new (bindWA->wHeap()) NAWcharBuf(defaultValueWcs,
                                         defaultValueWcsLen,
                                         bindWA->wHeap());
    }
    charBuf *pCharBuf = NULL; // must set this variable to NULL so the
                              // following function call will allocate
                              // space for the output literal string
    Int32 errorcode = 0;
    pCharBuf = unicodeTocset(*pWcharBuf, bindWA->wHeap(),
                             pCharBuf, mapCS, errorcode);
    // Earlier releases  treated the converted multibyte character
    // string, in ISO_MAPPING character set, as if it is a string of
    // ISO88591 characters and then convert it back to UCS-2 format;
    // i.e., for each byte in the string, insert an extra byte
    // containing the binary zero value.
    NADELETE(pWcharBuf, NAWcharBuf, bindWA->wHeap());
    pWcharBuf = NULL; // must set this variable to NULL to force the
                      // following call to allocate space for the
                      // the output literal string
    pWcharBuf = ISO88591ToUnicode(*pCharBuf, bindWA->wHeap(), pWcharBuf);
    // Prepare the converted literal string for the following CAST
    // function by setting pColDefaultValueStr to point to the string
    NAWchar *pWcs = NULL;
    if (ucs2StrLitPrefix)
    {
      pWcs = new (bindWA->wHeap()) NAWchar[10+NAWstrlen(pWcharBuf->data())];
      NAWstrcpy(pWcs, NAWSTR("_ISO88591"));
    }
    else
    {
      pWcs = new (bindWA->wHeap()) NAWchar[1+NAWstrlen(pWcharBuf->data())];
      pWcs[0] = NAWCHR('\0');
    }
    NAWstrcat(pWcs, pWcharBuf->data());
    defaultValueStr = (char *)pWcs;
    NADELETE(pWcharBuf, NAWcharBuf, bindWA->wHeap());
    NADELETE(pCharBuf, charBuf, bindWA->wHeap());
  }

  if (NOT defaultValueStr AND bindWA) {
    // 4107 column has no default so DEFAULT cannot be specified.
    *CmpCommon::diags() << DgSqlCode(-4107) << DgColumnName(nacol->getColName());
    bindWA->setErrStatus();
  }

  return defaultValueStr;
} // Insert::getColDefaultValue()


// -----------------------------------------------------------------------
// member functions for class Update
// -----------------------------------------------------------------------

RelExpr *Update::bindNode(BindWA *bindWA)
{
  if (nodeIsBound())
  {
    bindWA->getCurrentScope()->setRETDesc(getRETDesc());
    return this;
  }
  // Set flag for firstN in context 
  if (child(0) && child(0)->getOperatorType() == REL_SCAN)
    if (child(0)->castToRelExpr() && 
        ((Scan *)(child(0)->castToRelExpr()))->getFirstNRows() >= 0)
      if (bindWA && 
          bindWA->getCurrentScope() && 
          bindWA->getCurrentScope()->context())
        bindWA->getCurrentScope()->context()->firstN() = TRUE;

  setInUpdateOrInsert(bindWA, this, REL_UPDATE);

  RelExpr * boundExpr = GenericUpdate::bindNode(bindWA);
  if (bindWA->errStatus()) return NULL;
  setInUpdateOrInsert(bindWA);

  if (getTableDesc()->getNATable()->isHbaseCellTable())
    {
      *CmpCommon::diags() << DgSqlCode(-1425)
			  << DgTableName(getTableDesc()->getNATable()->getTableName().
					 getQualifiedNameAsAnsiString())
			  << DgString0("Reason: Cannot update an hbase table in CELL format. Use ROW format for this operation.");
    
      bindWA->setErrStatus();
      return this;
    }

  // QSTUFF
  if (getGroupAttr()->isStream() &&
     !getGroupAttr()->isEmbeddedUpdateOrDelete()) {
    *CmpCommon::diags() << DgSqlCode(-4173);
    bindWA->setErrStatus();
    return this;
  }
  // QSTUFF

  if (NOT bindWA->errStatus() AND
      NOT getTableDesc()->getVerticalPartitions().isEmpty())
    {
      // 4058 UPDATE query cannot be used on a vertically partitioned table.
      *CmpCommon::diags() << DgSqlCode(-4058) <<
        DgTableName(getTableDesc()->getNATable()->getTableName().
          getQualifiedNameAsAnsiString());
      bindWA->setErrStatus();
      return this;
    }

  // make sure scan done as part of an update runs in serializable mode so a
  // tsj(scan,update) implementation of a update runs as an atomic operation
  if (child(0)->getOperatorType() == REL_SCAN) {
    Scan *scanNode = (Scan*)(child(0)->castToRelExpr());
    if (!scanNode->accessOptions().userSpecified()) {
      scanNode->accessOptions().updateAccessOptions
        (TransMode::ILtoAT(TransMode::SERIALIZABLE_));
    }
  }

  // if FIRST_N is requested, insert a FirstN node.
  if ((getOperatorType() == REL_UNARY_UPDATE) &&
      (child(0)->getOperatorType() == REL_SCAN))
    {
      Scan * scanNode = (Scan *)(child(0)->castToRelExpr());
      if ((scanNode->getFirstNRows() != -1) &&
          (getGroupAttr()->isEmbeddedUpdateOrDelete()))
        {
          *CmpCommon::diags() << DgSqlCode(-4216);
          bindWA->setErrStatus();
          return NULL;
        }

      if (scanNode->getFirstNRows() >= 0)
        {
          FirstN * firstn = new(bindWA->wHeap())
            FirstN(scanNode, scanNode->getFirstNRows(), NULL);
          firstn->bindNode(bindWA);
          if (bindWA->errStatus())
            return NULL;

          setChild(0, firstn);
        }
    }

  // if rowset is used in set clause a direct rowset that is not in subquery 
  // must be present in the where clause
  if ((bindWA->getHostArraysArea()) &&
        (bindWA->getHostArraysArea()->hasHostArraysInSetClause()) &&
        (!(bindWA->getHostArraysArea()->hasHostArraysInWhereClause()))) {
      *CmpCommon::diags() << DgSqlCode(-30021) ;
      bindWA->setErrStatus();
      return this;
    }

  NABoolean transformUpdateKey = updatesClusteringKeyOrUniqueIndexKey(bindWA);
  if (bindWA->errStatus()) // error occurred in updatesCKOrUniqueIndexKey()
    return this;
  // To be removed when TRAFODION-1610 is implemented.
  NABoolean xnsfrmHbaseUpdate = FALSE;
  if ((hbaseOper()) && (NOT isMerge()))
    {      
      if (CmpCommon::getDefault(HBASE_TRANSFORM_UPDATE_TO_DELETE_INSERT) == DF_ON)
	{
	  xnsfrmHbaseUpdate = TRUE;
	}
      else if (getCheckConstraints().entries())
       {
         xnsfrmHbaseUpdate = TRUE;
       }
      else if (getTableDesc()->getNATable()->isHbaseMapTable())
       {
         xnsfrmHbaseUpdate = TRUE;
       }
     }  
  
  if (xnsfrmHbaseUpdate)
    {
      ULng32 savedParserFlags = Get_SqlParser_Flags (0xFFFFFFFF);
      Set_SqlParser_Flags(INTERNAL_QUERY_FROM_EXEUTIL);

      boundExpr = transformHbaseUpdate(bindWA);

      Assign_SqlParser_Flags (savedParserFlags);
    }
  else 
  // till here and remove the function transformHbaseUpdate also
  if ((transformUpdateKey) && (NOT isMerge()))
    {
      boundExpr = transformUpdatePrimaryKey(bindWA);
    }
  else
    boundExpr = handleInlining(bindWA, boundExpr);
  
  if (bindWA->errStatus()) // error occurred in transformUpdatePrimaryKey()
    return this;    // or handleInlining()
  
  return boundExpr;
} // Update::bindNode()

// -----------------------------------------------------------------------
// member functions for class MergeUpdate
// -----------------------------------------------------------------------

RelExpr *MergeUpdate::bindNode(BindWA *bindWA)
{
  if (nodeIsBound())
    {
      bindWA->getCurrentScope()->setRETDesc(getRETDesc());
      return this;
    }

  if (needsBindScope_)
    bindWA->initNewScope();

  // For an xformed upsert any UDF or subquery is guaranteed to be 
  // in the using clause. Upsert will not generate a merge without using 
  // clause. ON clause, when matched SET clause and when not matched INSERT
  // clauses all use expressions from the using clause. (same vid).
  // Therefore any subquery or UDF in the using clause will flow to the
  // rest of he tree through the TSJ and will be available. Each subquery
  // will be evaluated only once, and will be evaluated prior to the merge
  if (isMerge() && child(0) && !xformedUpsert())
  {
    ItemExpr *selPred = child(0)->castToRelExpr()->selPredTree();
    if (selPred || where_)
    {
      NABoolean ONhasSubquery = (selPred && selPred->containsSubquery());
      NABoolean ONhasAggr = (selPred && selPred->containsAnAggregate());
      NABoolean whrHasSubqry = FALSE;
      if (ONhasSubquery || ONhasAggr ||
	  (where_ && ((whrHasSubqry=where_->containsSubquery()) ||
                      where_->containsAnAggregate())))
      {
	*CmpCommon::diags() << DgSqlCode(-3241) 
			    << DgString0
	  (ONhasSubquery ? "Subquery in ON clause not allowed." :
           (ONhasAggr ? "aggregate function in ON clause not allowed." :
            (whrHasSubqry ?
             "subquery in UPDATE ... WHERE clause not allowed." :
             "aggregate function in UPDATE ... WHERE clause not allowed.")));  
	bindWA->setErrStatus();
	return this;
      }
      ItemExpr *ONhasUDF = (selPred ? selPred->containsUDF() : NULL);
      ItemExpr *whereHasUDF = (where_ ? where_->containsUDF() : NULL);
      if (ONhasUDF || whereHasUDF)
      {
	*CmpCommon::diags() << DgSqlCode(-4471)
			    << DgString0
	  (((UDFunction *)(ONhasUDF ? ONhasUDF : whereHasUDF))->
	   getFunctionName().getExternalName()); 
	bindWA->setErrStatus();
	return this;
      }
    }
  }

  if (isMerge() && recExprTree() && !xformedUpsert())
  {
    if (recExprTree()->containsSubquery())
    {
      *CmpCommon::diags() << DgSqlCode(-3241) 
                          << DgString0(" Subquery in SET clause not allowed.");
      bindWA->setErrStatus();
      return this;
    }
    if (recExprTree()->containsUDF())
    {
      *CmpCommon::diags() << DgSqlCode(-4471) 
                          << DgString0(((UDFunction *)recExprTree()->containsUDF())->
                                       getFunctionName().getExternalName());    
      bindWA->setErrStatus();
      return this;
    }
  }

  // if insertValues, then this is an upsert stmt.
  if (insertValues())
    {
      if (insertValues()->containsSubquery() && !xformedUpsert())
        {
          *CmpCommon::diags() << DgSqlCode(-3241) 
                              << DgString0(" Subquery in INSERT clause not allowed.");
          bindWA->setErrStatus();
          return this;
        }
      if (insertValues()->containsUDF() && !xformedUpsert())
        {
          *CmpCommon::diags() << DgSqlCode(-4471) 
                              << DgString0(((UDFunction *)insertValues()->containsUDF())->
                                           getFunctionName().getExternalName());
          bindWA->setErrStatus();
          return this;
        }

      Tuple * tuple = new (bindWA->wHeap()) Tuple(insertValues());
      Insert * ins = new (bindWA->wHeap())
        Insert(getTableName(),
               NULL,
               REL_UNARY_INSERT,
               tuple,
               insertCols(),
               NULL);
      ins->setInsertType(Insert::SIMPLE_INSERT);
      if (isMergeUpdate())
        ins->setIsMergeUpdate(TRUE);
      else
        ins->setIsMergeDelete(TRUE);

      ins->setTableDesc(getTableDesc());
      bindWA->getCurrentScope()->xtnmStack()->createXTNM();
      ins = (Insert*)ins->bindNode(bindWA);
      if (bindWA->errStatus()) 
        return NULL;
      bindWA->getCurrentScope()->xtnmStack()->removeXTNM();

      mergeInsertRecExpr() = ins->newRecExpr();
      mergeInsertRecExprArray() = ins->newRecExprArray();
    }

  NATable *naTable = bindWA->getNATable(getTableName());
  if (bindWA->errStatus())
    return NULL;
 
  if ((naTable->getViewText() != NULL) && (naTable->getViewCheck()))		
  {		
    *CmpCommon::diags() << DgSqlCode(-3241) 		
			<< DgString0(" View with check option not allowed.");	    		
    bindWA->setErrStatus();		
    return NULL;		
  }

  if ((naTable->isHbaseCellTable()) ||
      (naTable->isHbaseRowTable()))
    {
      *CmpCommon::diags() << DgSqlCode(-3241) 
			  << DgString0("Hbase tables not supported.");
      bindWA->setErrStatus();
      return NULL;
    }

  if (naTable->isHiveTable())
    {
      *CmpCommon::diags() << DgSqlCode(-3241) 
			  << DgString0("Hive tables not supported.");
      bindWA->setErrStatus();
      return NULL;
    }

  bindWA->setMergeStatement(TRUE);  

  // Create a merge IUD indicator, a CHAR(1) CHARACTER SET ISO88591
  // NOT NULL variable, that can be used by index maintenance and
  // other operations to find out what action the WHEN clause
  // indicated, insert (I), update (U) or delete (D). This will be
  // removed in GenericUpdate::normalizeNode() if nobody asked for
  // it. The actual value will be produced by the executor work
  // method, there is no expression for it.
  if (getProducedMergeIUDIndicator() == NULL_VALUE_ID)
    {
      ItemExpr *mergeIUDIndicator = new(bindWA->wHeap()) NATypeToItem(
           new(bindWA->wHeap()) SQLChar(
                1, FALSE, FALSE, FALSE, FALSE, CharInfo::ISO88591));

      mergeIUDIndicator = mergeIUDIndicator->bindNode(bindWA);
      if (bindWA->errStatus())
        return NULL;
      setProducedMergeIUDIndicator(mergeIUDIndicator->getValueId());
    }

  RelExpr * boundExpr = Update::bindNode(bindWA);
  if (bindWA->errStatus()) 
    return NULL;

  if (checkForMergeRestrictions(bindWA))
    return NULL;

  if (where_) {
    bindWA->getCurrentScope()->context()->inWhereClause() = TRUE;
    where_->convertToValueIdSet(mergeUpdatePred(), bindWA, ITM_AND);
    bindWA->getCurrentScope()->context()->inWhereClause() = FALSE;

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

    // any values added by where_ to Outer References Set should be
    // added to input values that must be supplied to this MergeUpdate
    getGroupAttr()->addCharacteristicInputs
      (bindWA->getCurrentScope()->getOuterRefs());
  }

  if (needsBindScope_)
    bindWA->removeCurrentScope();

  bindWA->setMergeStatement(TRUE);

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

// -----------------------------------------------------------------------
// member functions for class Delete
// -----------------------------------------------------------------------

RelExpr *Delete::bindNode(BindWA *bindWA)
{
  if (nodeIsBound())
  {
    bindWA->getCurrentScope()->setRETDesc(getRETDesc());
    return this;
  }
  // Save the current scope and node for children to peruse if necessary.
  BindContext *context = bindWA->getCurrentScope()->context();
  if (context) {
    context->deleteScope() = bindWA->getCurrentScope();
    context->deleteNode()  = this;
    if (getFirstNRows() >= 0) context->firstN() = TRUE;
  }

  RelExpr * boundExpr = GenericUpdate::bindNode(bindWA);
  if (bindWA->errStatus()) return boundExpr;

  if ((csl_) &&
      (NOT getTableDesc()->getNATable()->isHbaseRowTable()))
    {
      *CmpCommon::diags() << DgSqlCode(-1425)
			  << DgTableName(getTableDesc()->getNATable()->getTableName().
					 getQualifiedNameAsAnsiString());
    
      bindWA->setErrStatus();
      return this;
    }

  if (getTableDesc()->getNATable()->isHbaseCellTable())
    {
      *CmpCommon::diags() << DgSqlCode(-1425)
			  << DgTableName(getTableDesc()->getNATable()->getTableName().
					 getQualifiedNameAsAnsiString())
			  << DgString0("Reason: Cannot delete from an hbase table in CELL format. Use ROW format for this operation.");
    
      bindWA->setErrStatus();
      return this;
    }

  // QSTUFF
  if (getGroupAttr()->isStream() &&
     !getGroupAttr()->isEmbeddedUpdateOrDelete()) {
    *CmpCommon::diags() << DgSqlCode(-4180);
    bindWA->setErrStatus();
    return this;
  }
  // QSTUFF

  // Not only are check constraints on a DELETE nonsensical,
  // but they can cause VEGReference::replaceVEGReference to assert
  // with valuesToBeBound.isEmpty (Genesis 10-980202-0718).
  //
  // in case we are binding a generic update within a generic update
  // due to view expansion we would like to ensure that all constraints
  // are checked properly for the update operation performed on the
  // underlying base table
  if (NOT (bindWA->inViewExpansion() && bindWA->inGenericUpdate())) {  // QSTUFF
    getTableDesc()->checkConstraints().clear();
    checkConstraints().clear();
  }

  if (NOT getTableDesc()->getVerticalPartitions().isEmpty())
    {
      // 4029 DELETE query cannot be used on a vertically partitioned table.
      *CmpCommon::diags() << DgSqlCode(-4029) <<
        DgTableName(getTableDesc()->getNATable()->getTableName().
                      getQualifiedNameAsAnsiString());
      bindWA->setErrStatus();
      return this;
    }

  Scan *scanNode = NULL;
  // make sure scan done as part of a delete runs in serializable mode so a
  // tsj(scan,delete) implementation of a delete runs as an atomic operation
  if (child(0)->getOperatorType() == REL_SCAN) {
    scanNode = (Scan*)(child(0)->castToRelExpr());
    if (!scanNode->accessOptions().userSpecified()) {
      scanNode->accessOptions().updateAccessOptions
        (TransMode::ILtoAT(TransMode::SERIALIZABLE_));
    }
  }
  
  BindScope *prevScope   = NULL;
  BindScope *currScope   = bindWA->getCurrentScope();
  NABoolean inUnion = FALSE;

  while (currScope && !inUnion)
  {
    BindContext *currContext = currScope->context();
    if (currContext->inUnion())
    {
      inUnion = TRUE;
    }
    prevScope = currScope;
    currScope = bindWA->getPreviousScope(prevScope);
  }

  RelRoot *root =  bindWA->getTopRoot();

  if (getFirstNRows() >= 0)  // First N Delete
  {
    CMPASSERT(getOperatorType() == REL_UNARY_DELETE);

    // First N Delete on a partitioned table. Not considered a MTS delete.
    if (getTableDesc()->getClusteringIndex()->isPartitioned())
    {

      if (root->getCompExprTree() || inUnion ) // for unions we know there is a select
      {  // outer selectnot allowed for "non-MTS" first N delete
        *CmpCommon::diags() << DgSqlCode(-4216);
        bindWA->setErrStatus();
        return this;
      }

      RelExpr * childNode = child(0)->castToRelExpr();
      FirstN * firstn = new(bindWA->wHeap())
        FirstN(childNode, getFirstNRows(), NULL);
      firstn->bindNode(bindWA);
      if (bindWA->errStatus())
        return NULL;

      setChild(0, firstn);
      setFirstNRows(-1);

    }
    else
    {
      // First N delete on a single partition. This is considered a MTS Delete.
      if ((bindWA->getHostArraysArea()) &&
          ((bindWA->getHostArraysArea()->hasHostArraysInWhereClause()) ||
          (bindWA->getHostArraysArea()->getHasSelectIntoRowsets())))
      { // MTS delete not supported with rowsets
        *CmpCommon::diags() << DgSqlCode(-30037);
        bindWA->setErrStatus();
        return this;
      }

    
      if (scanNode && scanNode->getSelectionPred().containsSubquery())
      {
        // MTS Delete not supported with subquery in where clause
        *CmpCommon::diags() << DgSqlCode(-4138);

        bindWA->setErrStatus();
        return this;

      }

      if (root->hasOrderBy())
      { // mts delete not supported with order by
        *CmpCommon::diags() << DgSqlCode(-4189);
        bindWA->setErrStatus();
        return this;
      }
      if (root->getCompExprTree() || // MTS Delete has an outer select
          bindWA->isInsertSelectStatement() || // Delete inside an Insert Select statement, Soln:10-061103-0274
          inUnion )  // for unions we know there is a select
      {                                                                 
        if (root->getFirstNRows() < -1 || 
            inUnion) // for unions we wish to raise a union 
        {  // The outer select has a Last 1/0 clause      // specific error later, so set the flag now. 
          setMtsStatement(TRUE);  
        }
        else
        { // raise an error if no Last 1 clause is found.
          *CmpCommon::diags() << DgSqlCode(-4136);
          bindWA->setErrStatus();
          return this;
        }
      }
    }
  }

  // Triggers --
  
  if ((NOT isFastDelete()) && (NOT noIMneeded()))
    boundExpr = handleInlining(bindWA, boundExpr);
  else if (hbaseOper() && (getGroupAttr()->isEmbeddedUpdateOrDelete()))
  {
     setRETDesc(new (bindWA->wHeap()) RETDesc(bindWA));

     CorrName corrOLDTable (getScanNode(TRUE)->getTableDesc()->getCorrNameObj().getQualifiedNameObj(),
             bindWA->wHeap(),"OLD");

     // expose OLD table columns
     getRETDesc()->addColumns(bindWA, *child(0)->getRETDesc(), &corrOLDTable);

     ValueIdList outputs;
     getRETDesc()->getValueIdList(outputs, USER_AND_SYSTEM_COLUMNS);
     addPotentialOutputValues(outputs);

     bindWA->getCurrentScope()->setRETDesc(getRETDesc());
  }

  if (isMtsStatement())
    bindWA->setEmbeddedIUDStatement(TRUE);

   if (getFirstNRows() > 0) 
    {
      // create a firstN node to delete FIRST N rows, if no such node was created
      // during handleInlining. Occurs when DELETE FIRST N is used on table with no
      // dependent objects. 
      FirstN * firstn = new(bindWA->wHeap())
        FirstN(boundExpr, getFirstNRows());
      if (NOT(scanNode && scanNode->getSelectionPred().containsSubquery()))
        firstn->setCanExecuteInDp2(TRUE);
      firstn->bindNode(bindWA);
      if (bindWA->errStatus())
        return NULL;

      setFirstNRows(-1);
      boundExpr = firstn;
    }

   if (csl())
     {
       for (Lng32 i = 0; i < csl()->entries(); i++)
	 {
	   NAString * nas = (NAString*)(*csl())[i];
	   
	   bindWA->hbaseColUsageInfo()->insert
	     ((QualifiedName*)&getTableDesc()->getNATable()->getTableName(), nas);
	 }
     }

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

// -----------------------------------------------------------------------
// member functions for class MergeDelete
// -----------------------------------------------------------------------

RelExpr *MergeDelete::bindNode(BindWA *bindWA)
{
  if (nodeIsBound())
    {
      bindWA->getCurrentScope()->setRETDesc(getRETDesc());
      return this;
    }
  
  bindWA->initNewScope();

  if ((isMerge()) && 
      (child(0)) && 
      (child(0)->castToRelExpr()->selPredTree()))
  {
    if (child(0)->castToRelExpr()->selPredTree()->containsSubquery())
    {
      *CmpCommon::diags() << DgSqlCode(-3241) 
                          << DgString0(" Subquery in ON clause not allowed.");    
      bindWA->setErrStatus();
      return this;
    }
    if (child(0)->castToRelExpr()->selPredTree()->containsUDF())
    {
      *CmpCommon::diags() << DgSqlCode(-4471)
                          << DgString0(((UDFunction *)child(0)->
                                       castToRelExpr()->selPredTree()->
                                       containsUDF())->
                                       getFunctionName().getExternalName());
      bindWA->setErrStatus();
      return this;
    }
  }


  // if insertValues, then this is an upsert stmt.
  if (insertValues())
    {
      if (insertValues()->containsSubquery())
      {
        *CmpCommon::diags() << DgSqlCode(-3241) 
                            << DgString0(" Subquery in INSERT clause not allowed.");
        bindWA->setErrStatus();
        return this;
      }
      if (insertValues()->containsUDF())
      {
        *CmpCommon::diags() << DgSqlCode(-4471)
                            << DgString0(((UDFunction *)insertValues()->
                                          containsUDF())->
                                         getFunctionName().getExternalName());
        bindWA->setErrStatus();
        return this;
      }
      if (CmpCommon::getDefault(COMP_BOOL_175) == DF_OFF)
      {
        // MERGE DELETE + INSERT is buggy, so disallow it unless CQD is on. In
        // particular, the optimizer sometimes fails to produce a plan in phase 1.
        // JIRA TRAFODION-1509 covers completing the MERGE DELETE + INSERT feature.
	*CmpCommon::diags() << DgSqlCode(-3241)
			    << DgString0(" MERGE DELETE not allowed with INSERT.");

      }

      Tuple * tuple = new (bindWA->wHeap()) Tuple(insertValues());
      Insert * ins = new (bindWA->wHeap())
      Insert(getTableName(),
             NULL,
             REL_UNARY_INSERT,
             tuple,
             insertCols(),
             NULL);
      ins->setInsertType(Insert::SIMPLE_INSERT);
      ins->setIsMergeDelete(TRUE);

      ins->setTableDesc(getTableDesc());
      bindWA->getCurrentScope()->xtnmStack()->createXTNM();
      ins = (Insert*)ins->bindNode(bindWA);
      if (bindWA->errStatus()) 
        return NULL;
      bindWA->getCurrentScope()->xtnmStack()->removeXTNM();

      mergeInsertRecExpr() = ins->newRecExpr();
      mergeInsertRecExprArray() = ins->newRecExprArray();
    }

  NATable *naTable = bindWA->getNATable(getTableName());
  if (bindWA->errStatus())
    return NULL;
  
  if ((naTable->getViewText() != NULL) && (naTable->getViewCheck()))		
  {		
    *CmpCommon::diags() << DgSqlCode(-3241) 		
			<< DgString0(" View with check option not allowed.");	    		
    bindWA->setErrStatus();		
    return NULL;		
  }

  bindWA->setMergeStatement(TRUE);  
  RelExpr * boundExpr = Delete::bindNode(bindWA);
  if (bindWA->errStatus()) 
    return NULL;

  if (checkForMergeRestrictions(bindWA))
    return NULL;

  bindWA->removeCurrentScope(); 

  bindWA->setMergeStatement(TRUE);

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

static const char NEWTable [] = "NEW";    // QSTUFF:  corr for embedded d/u
static const char OLDTable [] = "OLD";    // QSTUFF:  corr for embedded d/u

// QSTUFF
// this method binds both, the set clauses applied to the after
// image as well as the set clauses applied to the before image
// the new set on rollback clause allows an application to modify
// the before image.
// delete from tab set on rollback x = 1;
// update tab set x = 1 set on rollback x = 2;
#pragma nowarn(770)   // warning elimination
void GenericUpdate::bindUpdateExpr(BindWA        *bindWA,
                                   ItemExpr      *recExpr,
                                   ItemExprList  &assignList,
                                   RelExpr       *boundView,
                                   Scan          *scanNode,
                                   SET(short)    &stoiColumnSet,
                                   NABoolean     onRollback)
{

  RETDesc *origScope = NULL;

  ValueIdSet &newRecExpr =
    (onRollback == TRUE) ? newRecBeforeExpr() : this->newRecExpr();
  ValueIdArray &newRecExprArray =
    (onRollback == TRUE) ? newRecBeforeExprArray() : this->newRecExprArray();

  if (onRollback &&
      ((!getTableDesc()->getClusteringIndex()->getNAFileSet()->isAudited()) ||
       (getTableDesc()->getNATable()->hasLobColumn()))) {
    // SET ON ROLLBACK clause is not allowed on a non-audited table
    *CmpCommon::diags() << DgSqlCode(-4214)
      << DgTableName(getTableDesc()->getNATable()->getTableName().
        getQualifiedNameAsAnsiString());
    bindWA->setErrStatus();
    return;
  }

  CollIndex     i, j;
  CollIndexList colnoList(STMTHEAP);   // map of col nums (row positions)
  CollIndex a = assignList.entries();

  const ColumnDescList *viewColumns = NULL;

  // if this is a view then get the columns of the view
  if (boundView) {
    viewColumns = boundView->getRETDesc()->getColumnList();
  }

  // if the GU has a SET ON ROLLBACK clause this method is called
  // twice: once to bind the columns in the SET clause and a second
  // time to bind the columns in the SET ON ROLLBACK clause.
  // Initially the update column list of the stoi_ is empty.
  // If this is the second call, store the update column list
  // from the first call.
  short *stoiColumnList = NULL;
  CollIndex currColumnCount = 0;
  if (currColumnCount = stoi_->getStoi()->getColumnListCount())
  {
       stoiColumnList = new (bindWA->wHeap()) short[currColumnCount];

       for (i = 0;  i < currColumnCount; i++)
              stoiColumnList[i] = stoi_->getStoi()->getUpdateColumn(i);
  }

  stoi_->getStoi()->setColumnList(new (bindWA->wHeap()) short[a + currColumnCount]);

  for (i = 0; i < a; i++) {
    CMPASSERT(assignList[i]->getOperatorType() == ITM_ASSIGN);
    assignList[i]->child(0)->bindNode(bindWA);                  // LHS
    if (bindWA->errStatus()) return;
    const NAColumn *nacol = assignList[i]->child(0).getNAColumn();
    if(getOperatorType() == REL_UNARY_UPDATE)
    {
        stoi_->getStoi()->setUpdateColumn(i, (short) nacol->getPosition());
        stoi_->getStoi()->incColumnListCount();
        stoi_->addUpdateColumn(nacol->getPosition());
    }
    const NAType *colType = nacol->getType();
    if (!colType->isSupportedType()) {
      *CmpCommon::diags() << DgSqlCode(-4028)     // 4028 table not updatatble
      << DgTableName(nacol->getNATable()->getTableName().getQualifiedNameAsAnsiString());
      bindWA->setErrStatus();
      return;
    }

    // If this is a sequence generator IDENTITY column
    // with a default type of GENERATED ALWAYS,
    // then post error -3428.  GENERATED ALWAYS
    // IDENTITY columns may not be updated.
    if(getOperatorType() == REL_UNARY_UPDATE         &&
       CmpCommon::getDefault(COMP_BOOL_210) == DF_ON &&
       nacol->isIdentityColumnAlways())
      {
        *CmpCommon::diags() << DgSqlCode(-3428)
                              << DgString0(nacol->getColName());
        bindWA->setErrStatus();
        return;
      }

    colnoList.insert(nacol->getPosition());         // save colno for next loop

    // in case its not a view we record the column position of the
    // base table, otherwise that of the view

    if (NOT boundView)
      stoiColumnSet.insert((short) nacol->getPosition());

    // if this is a view get the positions of the columns
    // within the view that are being updated.
    if (boundView) {
      ValueId vid = assignList[i]->child(0).getValueId();
      NABoolean found = FALSE;
      for (CollIndex k=0; k < viewColumns->entries(); k++) {
        if ((*viewColumns)[k]->getValueId() == vid) {
          stoiColumnSet.insert((short) k);
          found = TRUE;
          // Updatable views cannot have any underlying basetable column
          // appear more than once, so it's safe to break out of the loop.
          break;
        }
      }  // loop k
      CMPASSERT(found);
    }  // boundView
  }  // loop i<a

  // If this is the second call to this method, restore the update
  // columns bound in the first call
  if (currColumnCount)
  {
      for (i = a;  i < (currColumnCount + a); i++)
      {
          stoi_->getStoi()->setUpdateColumn(i,  stoiColumnList[i-a]);
          stoi_->addUpdateColumn(stoiColumnList[i-a]);
      }
  }

  // RHS:  Bind the right side of the Assigns such that the source expressions
  // reference the columns of the source table.
  //
  //### With a cascade of views, should this be "getRETDesc" as is,
  //### or "scanNode->getRETDesc" ?                     --?
  //### Should I set this->setRD to be the target(new)tbl at the beginning,
  //### explicitly say "scanNode..." here?              --i think not
  //

  if (GU_DEBUG) GU_DEBUG_Display(bindWA, this, "u");

  origScope = bindWA->getCurrentScope()->getRETDesc();

  // this sets the scope to the scan table for the before values
  // the previous scope was to the "UPDATE" table
  // we will reset the scope before returning in order not to introduce
  // hidden side effects but have the generic update explicitely point
  // to the scan scope

  bindWA->getCurrentScope()->setRETDesc(getRETDesc());

  //this has to be done after binding the LHS because of triggers
  //Soln :10-050110-3403 : Don't side-effect the SET on ROLLBACK list
  //when we come down to process it the next time over.So process only
  //the assignList
  ItemExpr* tempExpr = assignList.convertToItemExpr();
  tempExpr->convertToValueIdSet(newRecExpr, bindWA, ITM_ITEM_LIST);
  if (bindWA->errStatus()) return;

  if (NOT onRollback)
  {
    for (ValueId v = newRecExpr.init(); newRecExpr.next(v);
	 newRecExpr.advance(v))
      {
	CMPASSERT(v.getItemExpr()->getOperatorType() == ITM_ASSIGN);
	
        // remove all the onrollack expressions
	if (((Assign *)v.getItemExpr())->onRollback())
	  {
	    newRecExpr.remove(v);
	  }
      }
  }
  else
  {
     for (ValueId v = newRecExpr.init(); newRecExpr.next(v);
              newRecExpr.advance(v))
     {
        CMPASSERT(v.getItemExpr()->getOperatorType() == ITM_ASSIGN);

        // remove all the NON-onrollack expressions
        if ((getOperatorType() == REL_UNARY_UPDATE) &&
               !(((Assign *)v.getItemExpr())->onRollback()))
        {
            newRecExpr.remove(v);
        }
     }

     if (getOperatorType() == REL_UNARY_DELETE)
     {
        recExpr->convertToValueIdSet(this->newRecExpr(), bindWA, ITM_ITEM_LIST);
     }
  }

  // now we built the RHS
  // Now we have our colnoList map with which to build a temporary array
  // (with holes) and get the update columns ordered (eliminating dups).
  // Actually we store the ids of the bound Assign nodes corresponding
  // to the columns, of course.
  //
  CollIndex totalColCount = getTableDesc()->getColumnList().entries();
#pragma nowarn(1506)   // warning elimination
  ValueIdArray holeyArray(totalColCount);
#pragma warn(1506)  // warning elimination
  ValueId assignId;                                 // i'th newRecExpr valueid
  for (i = 0, assignId = newRecExpr.init();         // bizarre ValueIdSet iter
         newRecExpr.next(assignId);
         i++, newRecExpr.advance(assignId)) {
     j = colnoList[i];
     if (holeyArray.used(j)) {
       const NAColumn *nacol = holeyArray[j].getItemExpr()->child(0).getNAColumn();
       //4022 target column multiply specified
       *CmpCommon::diags() << DgSqlCode(-4022) << DgColumnName(nacol->getColName());
       bindWA->setErrStatus();
       return;
     }
     holeyArray.insertAt(j, assignId);
   }

   //
   // Now we have the holey array.  The next loop ignores unused entries
   // and copies the used entries into newRecExprArray(), with no holes.
   // It also builds a list of the columns being updated that contain
   // a column on the right side of the SET assignment expression.
   //
   // Entering this loop, i is the number of specified update columns;
   // exiting, j is.
   //
   CMPASSERT(i == a);

   // we built a map between identifical old and new columns, i.e. columns
   // which are not updated and thus identical. We insert the resulting
   // equivalence relationships e.g. old.a = new.a during transformation
   // into the respective VEGGIES this allows the optimizer to select index
   // scan for satisfying order requirements specified by an order by clause
   // on new columns, e.g.
   // select * from (update t set y = y + 1 return new.a) t order by a;
   // we cannot get the benefit of this VEG for a merge statement when IM is required
   // allowing a VEG in this case causes corruption on base table key values because
   // we use the "old" value of key column from fetchReturnedExpr, which can be junk
   // in case there is no row to update/delete, and a brand bew row is being inserted
   NABoolean mergeWithIndex = isMerge() && getTableDesc()->hasSecondaryIndexes() ;
   if ((NOT onRollback) && (NOT mergeWithIndex)){
     for (i = 0;i < totalColCount; i++){
       if (!(holeyArray.used(i))){
         oldToNewMap().addMapEntry(
           scanNode->getTableDesc()->
           getColumnList()[i].getItemExpr()->getValueId(),
           getTableDesc()->
           getColumnList()[i].getItemExpr()->getValueId());
       }
     }
   }

   // when binding a view which contains an embedded update
   // we must map update valueids to scan value ids
   // to allow for checking of access rights.
   for (i = 0; i < getTableDesc()->getColumnList().entries();i++)
     bindWA->getUpdateToScanValueIds().addMapEntry(
     getTableDesc()->getColumnList()[i].getItemExpr()->getValueId(),
     scanNode->getTableDesc()->getColumnList()[i].getItemExpr()->getValueId());

   newRecExprArray.resize(i);
   TableDesc *scanDesc = scanNode->getTableDesc();
   NABoolean rightContainsColumn = FALSE;

   for (i = j = 0; i < totalColCount; i++) {
     if (holeyArray.used(i)) {
       ValueId assignExpr = holeyArray[i];
       newRecExprArray.insertAt(j++, assignExpr);
       ItemExpr *right = assignExpr.getItemExpr()->child(1);

       // even if a column is set to a constant we mark it
       // as updated to prevent indices covering this column from
       // being used for access
       ItemExpr *left = assignExpr.getItemExpr()->child(0);

       scanDesc->addColUpdated(left->getValueId());

       if (right->containsColumn())
         rightContainsColumn = TRUE;
     }
   }

   // WITH NO ROLLBACK not supported if rightside of update 
   // contains a column expression. Also this feature is not
   // supported with the SET ON ROLLBACK feature
   if (isNoRollback() ||
       (CmpCommon::transMode()->getRollbackMode() == TransMode::NO_ROLLBACK_))
  {
    if ((rightContainsColumn && CmpCommon::getDefault(ALLOW_RISKY_UPDATE_WITH_NO_ROLLBACK) == DF_OFF) || onRollback)        
    {
      NAString warnMsg = "";
      if(rightContainsColumn)
      {
	warnMsg = "Suggestion: Set ALLOW_RISKY_UPDATE_WITH_NO_ROLLBACK CQD to ON to allow";
	if (getOperatorType() == REL_UNARY_DELETE)
	  warnMsg += " DELETE ";
	else
	  warnMsg += " UPDATE ";
	warnMsg += "command with right-hand side SET clause consisting of columns.";
      }

      if (getOperatorType() == REL_UNARY_DELETE)
	*CmpCommon::diags() << DgSqlCode(-3234) << DgString0(warnMsg);
      else
	*CmpCommon::diags() << DgSqlCode(-3233) << DgString0(warnMsg);
      bindWA->setErrStatus();
      return ;
    }
  }

   CMPASSERT(j == a);
   bindWA->getCurrentScope()->setRETDesc(origScope);
}
#pragma warn(770)  // warning elimination

void getScanPreds(RelExpr *start, ValueIdSet &preds)
{
  RelExpr *result = start;

  while (result) {
    preds += result->selectionPred();

    if (result->getOperatorType() == REL_SCAN) break;
    if (result->getArity() > 1) {
      return ;
    }
    result = result->child(0);
  }

  return;
}


// Note that this is the R2 compatible way to handle Halloween problem.
// This update (only insert for now) contains a reference to the
// target in the source.  This could potentially run into the so
// called Halloween problem.  Determine if this is a case we may be
// able to handle.  The cases that we handle are:
//
//   -- The reference to the target is in a subquery
//   -- There any number of references to the target in the source
//   -- The subquery cannot be a row subquery.
//   -- The subquery must contain only one source (the reference to the target)
//   -- 
//
//  Return TRUE if this does represent a Halloween problem and the caller will
//  then issue the error message
//
//  Return FALSE is this is a case we can handle.  Set the
//  'avoidHalloweenR2' flag in the subquery and this generic Update so
//  that the optimizer will pick a plan that is Halloween safe.
//
NABoolean GenericUpdate::checkForHalloweenR2(Int32 numScansToFind)
{
  
  // If there are no scans, no problem, return okay (FALSE)
  //
  if(numScansToFind == 0) {
    return FALSE;
  }

  // Allow any number of scans

  // Do not support for general NEO users.
  if (CmpCommon::getDefault(MODE_SPECIAL_1) == DF_OFF)
    return TRUE;

  // Number of scans of the target table found so far.
  //
  Int32 numHalloweenScans = 0;

  // Get the primary source of the generic update.  We are looking for
  // the halloween scans in the predicates of this scan node
  //
  ValueIdSet preds;
  getScanPreds(this, preds);

  Subquery *subq;

  // Search the preds of this scan for subqueries.
  //
  //    ValueIdSet &preds = scanNode->selectionPred();

  for(ValueId p = preds.init(); preds.next(p); preds.advance(p)) {
    ItemExpr *pred = p.getItemExpr();

    // If this pred contains a subquery, find the scans
    //
    if(pred->containsSubquery()) {
      ValueIdSet subqPreds;
      subqPreds += pred->getValueId();

      // Search all the preds and their children
      //
      while(subqPreds.entries()) {
        ValueIdSet children;
        for(ValueId s = subqPreds.init();
            subqPreds.next(s);
            subqPreds.advance(s)) {
          ItemExpr *term = s.getItemExpr();

          // Found a subquery, now look for the scan...
          //
          if(term->isASubquery()) {
            subq = (Subquery *)term;
              
            // We don't support row subqueries, keep looking for the scan
            // in the next subquery.
            if(!subq->isARowSubquery()) {

              // Is this the subquery that has the scan of the table
              // we are updating?
              //
              Scan *halloweenScan = subq->getSubquery()->getScanNode(FALSE);
              if(halloweenScan) { 
                  
                // Is this the scan we are looking for?
                //
                if(halloweenScan->getTableDesc()->getNATable() == 
                   getTableDesc()->getNATable()) {
                  subq->setAvoidHalloweenR2(this);
                  numHalloweenScans++;
                }
              }
            }
          }
            
          // Follow all the children as well.
          //
          for(Int32 i = 0; i < term->getArity(); i++) {
            children += term->child(i)->getValueId();
          }
        }
        subqPreds = children;
      }
    }
  }

  setAvoidHalloweenR2(numScansToFind);

  // If we found and marked all the halloween scans, then return FALSE (allow).
  // We have marked the subqueries to avoid the halloween problem.  This will
  // force the optimizer to pick a plan that will be safe.
  //
  if(numHalloweenScans == numScansToFind)
    return FALSE;

  return TRUE;
}

// See ANSI 7.9 SR 12 + 6.3 SR 8 for definition of "updatable" table
// references;  in particular, note that one of the requirements for a view's
// being updatable is that ultimately underlying it (passing through a
// whole stack of views) is *exactly one* wbase table -- i.e., no joins
// allowed.
//
RelExpr * GenericUpdate::bindNode(BindWA *bindWA)
{
  if (nodeIsBound())
  {
    bindWA->getCurrentScope()->setRETDesc(getRETDesc());
    return this;
  }

  // QSTUFF
  // we indicate that we are in a generic update. If we are
  // already in a generic update we know that this time we are
  // binding a generic update within a view.
  // however be aware of the following scenario. We currently
  // reject embedded updates and streams in the source but
  // obviously allow view with embedded updates as a target.
  // Since its already within a generic update we will only
  // return the scan node to the  insert
  //
  // insert into select ... from (update/delete ....) t;
  //
  // but not cause the update to be bound in when doing
  //
  // insert into viewWithDeleteOrUpdate values(...);
  //
  // in both cases we got an insert->update/delete->scan
  NABoolean inGenericUpdate = FALSE;

  if (getOperatorType() != REL_UNARY_INSERT)
    inGenericUpdate = bindWA->setInGenericUpdate(TRUE);

  NABoolean returnScanNode =
    (inGenericUpdate && bindWA->inViewExpansion() &&
    ( getOperatorType() == REL_UNARY_DELETE ||
      getOperatorType() == REL_UNARY_UPDATE ));

  // those group attributes should be set only by the topmost
  // generic update once we are invoked when already binding
  // another generic we reset those group attributes since we
  // already know that we will only return a scan node

  if ((returnScanNode) && (child(0))) {
    child(0)->getGroupAttr()->setStream(FALSE);
    child(0)->getGroupAttr()->setSkipInitialScan(FALSE);
    child(0)->getGroupAttr()->setEmbeddedIUD(NO_OPERATOR_TYPE);
  }

  // if we have no user-specified access options then
  // get it from nearest enclosing scope that has one (if any)
  if (!accessOptions().userSpecified()) {
    StmtLevelAccessOptions *axOpts = bindWA->findUserSpecifiedAccessOption();
    if (axOpts) {
      accessOptions() = *axOpts;
    }
  }
  // The above code is in Scan::bindNode also.
  // It would be nice to refactor this common code; someday.

  // Make sure we have the appropriate transaction mode & isolation level
  // in order to do the update.  Genesis 10-970922-3488.
  // Keep this logic in sync with Generator::verifyUpdatableTransMode()!
  Lng32 sqlcodeA = 0, sqlcodeB = 0;

  // fix case 10-040429-7402 by checking our statement level access options
  // first before declaring any error 3140/3141.
  TransMode::IsolationLevel il;
  ActiveSchemaDB()->getDefaults().getIsolationLevel
    (il,
     CmpCommon::getDefault(ISOLATION_LEVEL_FOR_UPDATES));
  verifyUpdatableTrans(&accessOptions(), CmpCommon::transMode(),
                       il,
                       sqlcodeA, sqlcodeB);

  if (sqlcodeA || sqlcodeB) {
    // 3140 The isolation level cannot be READ UNCOMMITTED.
    // 3141 The transaction access mode must be READ WRITE.
    if (sqlcodeA) *CmpCommon::diags() << DgSqlCode(sqlcodeA);
    if (sqlcodeB) *CmpCommon::diags() << DgSqlCode(sqlcodeB);
    bindWA->setErrStatus();
    return this;
  }

  Int64 transId=-1;
  if ((isNoRollback() && 
       (NOT (Get_SqlParser_Flags(INTERNAL_QUERY_FROM_EXEUTIL)))) &&
      ((CmpCommon::transMode()->getAutoCommit() != TransMode::ON_ ) ||
       (NAExecTrans(0, transId)))) {

    // do not return an error if this is a showplan query being compiled
    // in the second arkcmp.
    const NAString * val =
      ActiveControlDB()->getControlSessionValue("SHOWPLAN");
    if (NOT ((val) && (*val == "ON")))
      {
	*CmpCommon::diags() << DgSqlCode(-3231);   // Autocommit must be ON,
	bindWA->setErrStatus(); // if No ROLLBACK is specified in IUD statement syntax
	return this;
      }
  }

  if (isNoRollback() ||
      (CmpCommon::transMode()->getRollbackMode() == TransMode::NO_ROLLBACK_))
  {
    if ((child(0)->getGroupAttr()->isStream()) || 
        (child(0)->getGroupAttr()->isEmbeddedUpdateOrDelete()) ||
        (updateCurrentOf()))
    {
      if (getOperatorType() == REL_UNARY_DELETE)
        *CmpCommon::diags() << DgSqlCode(-3234);
      else
        *CmpCommon::diags() << DgSqlCode(-3233);
      bindWA->setErrStatus();
      return this;
    }
  }

  // The SQL standard as defined in ISO/IEC JTC 1/SC 32 date: 2009-01-12
  // CD 9075-2:200x(E) published by ISO/IEC JTC 1/SC 32/WG 3
  // "Information technology -- Database languages -- SQL --
  //  Part2: Foundation (SQL/Foundation)", page 920, section 14.14,
  // page 918, section 14.13, page 900, section 14.9, page 898, section 14.8
  // does allow correlation names in update & delete statements.
  // Therefore, we delete this unnecessary restriction as part of the fix
  // for genesis solution 10-090921-4747:
  // Many places in this method assume the specified target table
  // has no correlation name -- indeed, Ansi syntax does not allow one --
  // this assert is to catch any future syntax-extensions we may do.
  //
  // E.g., see code marked
  //	##SQLMP-SYNTAX-KLUDGE##
  // in SqlParser.y + SqlParserAux.cpp,
  // which add a non-Ansi corr name to all table refs
  // when they really only should add to SELECTed tables.
  // So here, in an INSERT/UPDATE/DELETEd table,
  // we UNDO that kludge.
  //
  //if (!getTableName().getCorrNameAsString().isNull()) {
    //CMPASSERT(SqlParser_NAMETYPE == DF_NSK ||
    // HasMPLocPrefix(getTableName().getQualifiedNameObj().getCatalogName()));
    //getTableName().setCorrName("");			// UNDO that kludge!
  //}

  // Genesis 10-980831-4973
  if (((getTableName().isLocationNameSpecified() || 
        getTableName().isPartitionNameSpecified()) &&
     (!Get_SqlParser_Flags(ALLOW_SPECIALTABLETYPE))) &&
     (getOperatorType() != REL_UNARY_DELETE)) {
    *CmpCommon::diags() << DgSqlCode(-4061);   // 4061 a partn not ins/upd'able
    bindWA->setErrStatus();
    return this;
  }
  
   // -- Triggers
  // If this node is part of the action of a trigger,
  // then don't count the rows that are affected.
  if (bindWA->findNextScopeWithTriggerInfo() != NULL)
  {
    rowsAffected_ = DO_NOT_COMPUTE_ROWSAFFECTED;

    // Does the table name match the name of one of the transition tables?
    if (updatedTableName_.isATriggerTransitionName(bindWA))
    {
      // 11020 Ambiguous or illegal use of transition name $0~string0.
      *CmpCommon::diags() << DgSqlCode(-11020)
                          << DgString0(getTableName().getQualifiedNameAsString());

      bindWA->setErrStatus();
      return this;
    }
  }

  // Get the NATable for this object, and an initial ref count.
  // Set up stoi.
  //
  // We do not suppress mixed name checking in getNATable for R1
  // from here, because prototype name executes through here.  We
  // want to check prototype name.

  const NATable *naTable = bindWA->getNATable(getTableName());
  if (bindWA->errStatus()) return this;

  if (naTable && naTable->isHbaseTable())
    hbaseOper() = TRUE;

  if (naTable && naTable->isHbaseMapTable() &&
      (CmpCommon::getDefault(TRAF_HBASE_MAPPED_TABLES_IUD) == DF_OFF))
    {
      *CmpCommon::diags() << DgSqlCode(-4223)
			  << DgString0("Insert/Update/Delete on HBase mapped tables is");
      
      bindWA->setErrStatus();
      return this;
    }

  if ((CmpCommon::getDefault(ALLOW_DML_ON_NONAUDITED_TABLE) == DF_OFF) &&
      naTable && naTable->getClusteringIndex() && 
      (!naTable->getClusteringIndex()->isAudited())
      // && !bindWA->isBindingMvRefresh()  // uncomment if non-audit MVs are ever supported
     )
  {
     *CmpCommon::diags() << DgSqlCode(-4211)
       << DgTableName(
           naTable->getTableName().getQualifiedNameAsAnsiString());
     bindWA->setErrStatus();
     return NULL;
  }
  
  Int32 beforeRefcount = naTable->getReferenceCount();

  OptSqlTableOpenInfo *listedStoi
    = setupStoi(stoi_, bindWA, this, naTable, getTableName());

  if (getOperatorType() == REL_UNARY_INSERT &&
      NOT naTable->isInsertable()) {
    *CmpCommon::diags() << DgSqlCode(-4027)  // 4027 table not insertable
      << DgTableName(naTable->getTableName().getQualifiedNameAsAnsiString());
    bindWA->setErrStatus();
    return this;
  }
  if (NOT naTable->isUpdatable()) {
    *CmpCommon::diags() << DgSqlCode(-4028)  // 4028 table not updatable
      << DgTableName(naTable->getTableName().getQualifiedNameAsAnsiString());
    bindWA->setErrStatus();
    return this;
  }

  if (naTable->isVerticalPartition()) {
// LCOV_EXCL_START - cnu
    // On attempt to update an individual VP, say: 4082 table not accessible
    *CmpCommon::diags() << DgSqlCode(-4082) <<
       DgTableName(naTable->getTableName().getQualifiedNameAsAnsiString());
    bindWA->setErrStatus();
    return this;
// LCOV_EXCL_STOP
  }


  if (naTable->isAnMV())
  {
    // we currently don't allow updating (deleting) MVs in a trigger action
    if (bindWA->inDDL() && bindWA->isInTrigger ())
    {
        *CmpCommon::diags() << DgSqlCode(-11051);
        bindWA->setErrStatus();
        return this;
    }

    // This table is a materialized view. Are we allowed to change it?
    if ((getTableName().getSpecialType() != ExtendedQualName::MV_TABLE) &&
        (getTableName().getSpecialType() != ExtendedQualName::GHOST_MV_TABLE))
    {
      // The special syntax flag was not used -
      // Only on request MV allows direct DELETE operations by the user.
      MVInfoForDML *mvInfo = ((NATable *)naTable)->getMVInfo(bindWA);
      if (mvInfo->getRefreshType() == COM_ON_REQUEST &&
          getOperatorType() == REL_UNARY_DELETE)
      {
        // Set NOLOG flag.
        setNoLogOperation();
      }
      else
      {
        // Direct update is only allowed for User Maintainable MVs.
        if (mvInfo->getRefreshType() != COM_BY_USER)
        {
          // A Materialized View cannot be directly updated.
          *CmpCommon::diags() << DgSqlCode(-12074);
          bindWA->setErrStatus();
          return this;
        }
      }
    }

    // If this is not an INTERNAL REFRESH command, make sure the MV is
    // initialized and available.
    // If this is FastDelete using parallel purgedata, do not enforce
    // that MV is initialized.
    if (!bindWA->isBindingMvRefresh())
    {
      if (NOT ((getOperatorType() == REL_UNARY_DELETE) &&
               (((Delete*)this)->isFastDelete())))
        {
          if (naTable->verifyMvIsInitializedAndAvailable(bindWA))
            return NULL;
        }
    }
  }

  if (naTable->isAnMVMetaData() &&
      getTableName().getSpecialType() != ExtendedQualName::MVS_UMD)
  {
    if (getTableName().getPrototype() == NULL ||
        getTableName().getPrototype()->getSpecialType() != ExtendedQualName::MVS_UMD)
    {  // ERROR 12075: A Materialized View Metadata Table cannot be directly updated.
      *CmpCommon::diags() << DgSqlCode(-12075);
      bindWA->setErrStatus();
      return this;
    }
  }

  if ((naTable->isSeabaseTable()) &&
      (naTable->isSeabaseMDTable() || 
       naTable->isSeabasePrivSchemaTable()) &&
      (NOT naTable->isUserUpdatableSeabaseMDTable()) &&
      (NOT Get_SqlParser_Flags(INTERNAL_QUERY_FROM_EXEUTIL)))
    {
      // IUD on hbase metadata is only allowed for internal queries.
     *CmpCommon::diags() << DgSqlCode(-1391)
			 <<  DgString0(naTable->getTableName().getQualifiedNameAsAnsiString())
                         << DgString1("metadata");
      bindWA->setErrStatus();
      return this;
    }
  else if ((naTable->isSeabaseTable()) &&
           (naTable->getTableName().getSchemaName() == SEABASE_REPOS_SCHEMA) &&
           (NOT Get_SqlParser_Flags(INTERNAL_QUERY_FROM_EXEUTIL)))
    {
      // IUD on hbase metadata is only allowed for internal queries.
      *CmpCommon::diags() << DgSqlCode(-1391)
			 <<  DgString0(naTable->getTableName().getQualifiedNameAsAnsiString())
                         << DgString1("repository");
      bindWA->setErrStatus();
      return this;
    }
  
  if ((naTable->isHbaseTable()) &&
      (naTable->isHbaseCellTable() || naTable->isHbaseRowTable()) &&
      (CmpCommon::getDefault(HBASE_NATIVE_IUD) == DF_OFF))
    {
      *CmpCommon::diags() << DgSqlCode(-4223)
			  << DgString0("Insert/Update/Delete on native HBase tables or in CELL/ROW format is");
      
      bindWA->setErrStatus();
      return this;
     }

  NABoolean insertFromValuesList =
   (getOperatorType() == REL_UNARY_INSERT &&
    (child(0)->getOperatorType() == REL_TUPLE ||  // VALUES(1,'b')
     child(0)->getOperatorType() == REL_TUPLE_LIST ||  // VALUES(1,'b'),(2,'Y')
     child(0)->getOperatorType() == REL_UNION)) ||  // VALUES..(with subquery inside the list)
    getOperatorType() == REL_LEAF_INSERT;          // index type of inserts

   if((!insertFromValuesList) && (getOperatorType() == REL_UNARY_INSERT))
    bindWA->setInsertSelectStatement(TRUE);

  // an update/delete node is created as an update/delete with child
  // of a scan node by parser. If this is the case, then no security
  // checks are needed on child Scan node.
  if ((getOperatorType() == REL_UNARY_UPDATE ||
       getOperatorType() == REL_UNARY_DELETE) &&
      (child(0) && (child(0)->getOperatorType() == REL_SCAN))) {
    Scan * scanNode = (Scan *)(child(0)->castToRelExpr());
    scanNode->setNoSecurityCheck(TRUE);
  }

  // Setting the begin index for TableViewUsageList to zero, instead
  // of the bindWA->tableViewUsageList().entries(); Becasue
  // bindWA->tableViewUsageList().entries() sets the index to the current
  //entry in the list, which excludes previous statements executed in a CS.
  CollIndex begSrcUsgIx = 0;
  if (!insertFromValuesList) {
    //
    // Create a new table name scope for the source table (child node).
    // Bind the source.
    // Reset scope context/naming.
    //
    bindWA->getCurrentScope()->xtnmStack()->createXTNM();
    bindChildren(bindWA);
    if (bindWA->errStatus()) return this;
    bindWA->getCurrentScope()->xtnmStack()->removeXTNM();

    // QSTUFF

    // we currently don't support streams and embedded updates
    // for "insert into select from" statements.
    if (getOperatorType() == REL_UNARY_INSERT){

      if (child(0)->getGroupAttr()->isStream()){
        *CmpCommon::diags() << DgSqlCode(-4170);
        bindWA->setErrStatus();
        return this;
      }

      if (child(0)->getGroupAttr()->isEmbeddedUpdateOrDelete() ||
          child(0)->getGroupAttr()->isEmbeddedInsert()){
        *CmpCommon::diags() << DgSqlCode(-4171)
			    << DgString0(getGroupAttr()->getOperationWithinGroup());
        bindWA->setErrStatus();
        return this;
      }
    }

    // binding a generic update within a generic update
    // can only occur when binding an updatable view containing
    // an embedded delete or embedded update. We don't continue
    // binding the generic update and but return the bound scan node.
    // the scan node may be either a base table scan or a RenameTable
    // node in case we are updating a view
    // Since an embedded generic update may have referred to the OLD
    // and NEW table we set a binder flag causing the table name to
    // be changed to the name of the underlying scan table in the
    // RelRoot on top of the generic update. Since we
    // know that the normalizer has checked before allowing an update
    // on the view that not both, i.e.new and old column values have been
    // referred this is a safe operation.

    if (returnScanNode){
      // this line is a hack to get through Update::bindNode on the return
      setTableDesc(getScanNode()->getTableDesc());

      bindWA->setInGenericUpdate(inGenericUpdate);
      bindWA->setRenameToScanTable (TRUE);
      NATable *nTable = bindWA->getNATable(getTableName());

      // decr once for just getting it here
      // and again to compensate for the reference taken out
      // previously which becomes obsolete since we just return a scan node
      nTable->decrReferenceCount();
      nTable->decrReferenceCount();

      return getViewScanNode();
    }
    // QSTUFF
  }
  else {
    // else, Insert::bindNode does VALUES(...) in its Assign::bindNode loop
    // in particular, it does      VALUES(..,DEFAULT,..)
  }

  #ifndef NDEBUG
    GU_DEBUG_Display(bindWA, this, "incoming", NULL, TRUE);
  #endif

  // QSTUFF
  // in case of an insert operation we don't set it initially in order
  // to prevent that an embedded update or delete may be accidentially
  // removed from a source view. However we need it for binding the
  // target because it may be a view and its embedded updates have to
  // be removed.

  if (getOperatorType() == REL_UNARY_INSERT)
    inGenericUpdate = bindWA->setInGenericUpdate(TRUE);

  CMPASSERT(NOT(updateCurrentOf() &&
                getGroupAttr()->isEmbeddedUpdateOrDelete()));

  // this is a patch to allow for embedded updates in view definitions
  ParNameLocList * pLoc = NULL;
  if (getGroupAttr()->isEmbeddedUpdate()) {
    pLoc =  bindWA->getNameLocListPtr();
    bindWA->setNameLocListPtr(NULL);
  }
  // QSTUFF

  // Allocate a TableDesc and attach it to the node.
  //
  // Note that for Update/Delete, which always have a Scan node attached
  // (see below), we cannot reuse the Scan's TableDesc:
  // GenMapTable.C doesn't find the proper ValueIds when processing an
  // update/delete on a table with an index.
  // So we must always create a new (target) TableDesc, always a base table.
  //
  // Note that bindWA->getCurrentScope()->setRETDesc() is implicitly called:
  // 1) by createTableDesc, setting it to this new (target) base table;
  // 2) by bindView (if called), resetting it to the view's RenameTable RETDesc
  //    atop the new (target) table.
  //
  const NATable *naTableTop = naTable;
  NABoolean isView = naTable->getViewText() != NULL;
  RelExpr *boundView = NULL;      // ## delete when done with it?
  Scan *scanNode = NULL;

  if (getOperatorType() == REL_UNARY_INSERT ||
      getOperatorType() == REL_LEAF_INSERT) {
    if (isView) {        // INSERT into a VIEW:
    //
    // Expand the view definition as if it were a Scan child of the Insert
    // (like all children, must have its own table name scope).
    //
    bindWA->getCurrentScope()->xtnmStack()->createXTNM();
    boundView = bindWA->bindView(getTableName(),
                                 naTable,
                                 accessOptions(),
                                 removeSelPredTree(),
                                 getGroupAttr());
    #ifndef NDEBUG
      GU_DEBUG_Display(bindWA, this, "bv1", boundView);
    #endif
    if (bindWA->errStatus()) return this;
    scanNode = boundView->getScanNode();
    bindWA->getCurrentScope()->xtnmStack()->removeXTNM();
    }
  }
  else if (getOperatorType() == REL_UNARY_UPDATE ||
           getOperatorType() == REL_UNARY_DELETE) {
    scanNode = getScanNode();
  }

  if (updateCurrentOf()) {
    CMPASSERT(scanNode);
    scanNode->bindUpdateCurrentOf(bindWA,
                                  (getOperatorType() == REL_UNARY_UPDATE));
    if (bindWA->errStatus()) return this;
  }

  // As previous comments indicated, we're creating a TableDesc for the target,
  // the underlying base table.  Here we go and do it:

  NABoolean isScanOnDifferentTable = FALSE;
  if (isView) {
    // This binding of the view sets up the target RETDesc.
    // This is the first bindView for UPDATE and DELETE on a view,
    // and the second for INSERT into a view (yes, we *do* need to do it again).
    boundView = bindWA->bindView(getTableName(),
                                 naTable,
                                 accessOptions(),
                                 removeSelPredTree(),
                                 getGroupAttr(),
                                 TRUE);   // QSTUFF
    setTableDesc(boundView->getScanNode()->getTableDesc());
    if ((getOperatorType() == REL_INSERT)||
        (getOperatorType() == REL_UNARY_INSERT) ||
        (getOperatorType() == REL_LEAF_INSERT))
    {
      ((Insert *)this)->setBoundView(boundView);
    }
    // for triggers
    if (scanNode)
      {
        const NATable *naTableLocal = scanNode->getTableDesc()->getNATable();
        if ((naTableLocal != naTable) && (naTableLocal->getSpecialType() == ExtendedQualName::TRIGTEMP_TABLE))
          isScanOnDifferentTable = TRUE;
      }
  } else if (NOT (getUpdateCKorUniqueIndexKey() && (getOperatorType() == REL_UNARY_INSERT))) {
    // an insert that is introduced to implement a phase of update primary key already 
    // has the right tabledesc (obtained from the update that it is replacing), so 
    // do not create another tablesdesc for such an insert.
    if (scanNode)
      naTable = scanNode->getTableDesc()->getNATable();
    CorrName tempName(naTableTop->getTableName(),
                      bindWA->wHeap(),
                      "",
                      getTableName().getLocationName(),
                      getTableName().getPrototype());
    
    tempName.setUgivenName(getTableName().getUgivenName());
    
    tempName.setSpecialType(getTableName().getSpecialType());
    //    tempName.setIsVolatile(getTableName().isVolatile());
    TableDesc * naTableToptableDesc = bindWA->createTableDesc(
                                                             naTableTop,
                                                             tempName);

    if(naTableToptableDesc)
    {
      naTableToptableDesc->setSelectivityHint(NULL);
      naTableToptableDesc->setCardinalityHint(NULL);
    }

    setTableDesc(naTableToptableDesc);

    // Now naTable has the Scan's table, and naTableTop has the GU's table.
    isScanOnDifferentTable = (naTable != naTableTop);
  }

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


  // QSTUFF
  // in case of a delete or update we may have to bind set clauses.
  // first we bind the left target column, second we bind the right hand side
  // we also have to separate the set on rollback clauses in a separate
  // list. The set clauses generate a newRecExpr list, the set on rollback
  // clause generate a newRecBeforeExpr list.

  // we add the old to new valueid map as it allows us to generate
  // a subset operator in the presence of order by. the compiler
  // needs to understand that the old and new valueids are identical

  // inlined trigger may update and scan different tables
  if ((getOperatorType() == REL_UNARY_DELETE) && 
    (!isScanOnDifferentTable && !getUpdateCKorUniqueIndexKey())) {
    const ValueIdList &dkeys =
      getTableDesc()->getClusteringIndex()->getClusteringKeyCols();
    const ValueIdList &skeys =
      scanNode->getTableDesc()->getClusteringIndex()->getClusteringKeyCols();
    CollIndex j = skeys.entries();
    for (CollIndex i = 0; i < j; i++) {
      oldToNewMap().addMapEntry(skeys[i].getItemExpr()->getValueId(),
                                dkeys[i].getItemExpr()->getValueId());
    }
  }

  ItemExpr *recExpr = removeNewRecExprTree();

  if (recExpr &&
      (getOperatorType() == REL_UNARY_DELETE ||
       getOperatorType() == REL_UNARY_UPDATE)) {

    ItemExprList  recList(recExpr, bindWA->wHeap());
    ItemExprList  recBeforeList(bindWA->wHeap());
    SET(short)    stoiColumnSet(bindWA->wHeap());

    // in case a delete statement has a recEpxr, set on rollback
    // clauses have been defined and need to be bound

    // as part of binding any set on rollback clause we have check
    // that no contraints are defined for the specific clauses; otherwise
    // the statement is rejected.
    // the target columns are bound to the update table, the source
    // columns are bound to the scan table

    if (getOperatorType() == REL_UNARY_DELETE){
      recBeforeList.insert(recList);
      bindUpdateExpr(bindWA,recExpr,recBeforeList,boundView,scanNode,stoiColumnSet,TRUE);
      if (bindWA->errStatus()) return this;
    }

    // in case of an update operator we have to separate the set and
    // set on rollback clauses

    if (getOperatorType() == REL_UNARY_UPDATE) {
      CMPASSERT(recList.entries());

      NABoolean leftIsList      = FALSE;
      NABoolean rightIsList     = FALSE;
      NABoolean legalSubqUdfExpr = FALSE;

      for (CollIndex i = 0;i < recList.entries(); i++){

        CMPASSERT(recList[i]->getOperatorType() == ITM_ASSIGN);

        if (recList[i]->child(0)->getOperatorType() == ITM_ITEM_LIST)
          leftIsList = TRUE;
        if (recList[i]->child(1)->getOperatorType() == ITM_ITEM_LIST)
          rightIsList = TRUE;

        if (((Assign *)recList[i])->onRollback()){

          // On rollback clause currently not allowed with update lists.
          if ((leftIsList) || (rightIsList))
            {
              *CmpCommon::diags() << DgSqlCode(-3242) 
                                  << DgString0(" ON ROLLBACK not supported with SET lists.");
              bindWA->setErrStatus();
              return this;
            }
          //          CMPASSERT((NOT leftIsList) && (NOT rightIsList))
          
          recBeforeList.insert(recList[i]);
          recList.removeAt(i);
          i--;
        }
      }
      

      if ((leftIsList) &&
          (NOT rightIsList) && 
          (recList.entries() == 1) &&
          ((recList[0]->child(1)->getOperatorType() == ITM_ROW_SUBQUERY) ||
          (recList[0]->child(1)->getOperatorType() == ITM_USER_DEF_FUNCTION)))
        {
          ItemExpr   * expr = NULL;

          // Both Subqueries and UDFs are now using the ValueIdProxy
          // to carry the each of the valueIds representing the select list
          // or UDF outputs. The transformation of the ValueIdProxy will do the
          // right thing, and we don't need setSubqInUpdateAssing() anymore.

          // Bind the subquery
          if (recList[0]->child(1)->getOperatorType() == ITM_ROW_SUBQUERY) 
          {
             RowSubquery * rs = 
               (RowSubquery*)(recList[0]->child(1)->castToItemExpr());

             // Not sure that we ever have a subquery without a REL_ROOT
             // left this additional check from the old code.
             if (rs->getSubquery()->getOperatorType() == REL_ROOT)
             {
                rs = (RowSubquery *) rs->bindNode(bindWA);
                if (bindWA->errStatus())
                  return this;

                legalSubqUdfExpr = TRUE;
                expr = (ItemExpr *) rs;
             }
          
          }
          else
          {
             UDFunction * rudf = 
               (UDFunction*)(recList[0]->child(1)->castToItemExpr());

             //  Need to bind the UDFunction to get its outputs.
             rudf = (UDFunction *) rudf->bindNode(bindWA);
             if (bindWA->errStatus())
               return this;

             legalSubqUdfExpr = TRUE;
             expr = (ItemExpr *) rudf;

          }

          // Update the recList with the bound itemExpr
          recList[0]->child(1) = expr;


          // Use the ItemExprList to flatten the Subquery or UDF
          ItemExprList *exprList = (ItemExprList *) new(bindWA->wHeap())
                                  ItemExprList(expr,bindWA->wHeap());

          // Convert the ItemExprList to a Tree
          ItemExpr * ie = exprList->convertToItemExpr();
          ie = ie->bindNode(bindWA);
          if (bindWA->errStatus())
            return this;
  
          Assign * assignNode = (Assign *)recList[0];
          assignNode->child(1) = ie;

          rightIsList = TRUE;
        }

      if ((leftIsList) || (rightIsList)) // some elements as lists
        {
          ItemExprList  newRecList(bindWA->wHeap());
          for (CollIndex i = 0; i < recList.entries(); i++)
            {
              Assign * assignNode = (Assign *)recList[i];

                // Need to bind any UDFs or Subqieries in the expression 
                // so that we know the degree before we expand the list.
              assignNode->child(0) = 
                          assignNode->child(0)->bindUDFsOrSubqueries(bindWA); 
              if (bindWA->errStatus())
                return this;

                // Need to bind any UDFs or Subqieries in the expression 
                // so that we know the degree before we expand the list.
              assignNode->child(1) = 
                          assignNode->child(1)->bindUDFsOrSubqueries(bindWA); 
              if (bindWA->errStatus())
                return this;

              ItemExprList leftList(assignNode->child(0), bindWA->wHeap());
              ItemExprList rightList(assignNode->child(1), bindWA->wHeap());
              Lng32 numLeftElements = (Lng32) leftList.entries();
              Lng32 numRightElements = (Lng32) rightList.entries();

              // See if ALLOW_SUBQ_IN_SET is enabled. It is enabled if
              // the default is ON, or if the default is SYSTEM and
              // ALLOW_UDF is ON.
              NABoolean allowSubqInSet_Enabled = FALSE;
              DefaultToken allowSubqTok =
                CmpCommon::getDefault(ALLOW_SUBQ_IN_SET);
              if ((allowSubqTok == DF_ON) ||
                  (allowSubqTok == DF_SYSTEM))
                allowSubqInSet_Enabled = TRUE;

              if (!allowSubqInSet_Enabled)
                 {
                   for (CollIndex j = 0; j < rightList.entries(); j++)
                     {
                       if (((numLeftElements > 1) ||
                           (numRightElements > 1)) &&
                           (((rightList[j]->getOperatorType() == ITM_ROW_SUBQUERY) ||
                             (rightList[j]->getOperatorType() == ITM_VALUEID_PROXY)) &&
                             (legalSubqUdfExpr == FALSE)))
                         {
                           *CmpCommon::diags() << DgSqlCode(-3242) 
                             << DgString0(" Multiple elements or multiple subqueries are not allowed in this SET clause.");    
                           bindWA->setErrStatus();
                           return this;
                         }
                     }
                 }

              if (numLeftElements != numRightElements)
                {
                  *CmpCommon::diags() << DgSqlCode(-4023)
                    << DgInt0(numRightElements) 
                    << DgInt1(numLeftElements);
                  bindWA->setErrStatus();
                  return this;
                }
              
              // create newRecList with one Assign node for each element.
              for (CollIndex k = 0; k < leftList.entries(); k++)
                {
                  ItemExpr * leftIE = leftList[k];
                  ItemExpr * rightIE = rightList[k];
                  Assign *assign = new (bindWA->wHeap())
                    Assign(leftIE, rightIE);
                  // We do not bind the above Assign as it will be done
                  // in bindUpdateExpr below. (bug #1893)
                  newRecList.insert(assign);
                }

            } // for

	  bindUpdateExpr(bindWA,recExpr,newRecList,boundView,scanNode,stoiColumnSet);
	  if (bindWA->errStatus()) 
	    return this;
	} // some elements as lists
      else
	{ // no elements as lists
	  if (recList.entries()){
	    bindUpdateExpr(bindWA,recExpr,recList,boundView,scanNode,stoiColumnSet);
	    if (bindWA->errStatus()) return this;
	  }
	}

      if (recBeforeList.entries()){
      bindUpdateExpr(bindWA,recExpr,recBeforeList,boundView,scanNode,stoiColumnSet,TRUE);
      if (bindWA->errStatus()) return this;
      }

    } // UNARY_UPDATE

  // now we record the columns updated for the SqlTableOpenInfo
  if (listedStoi) {
    listedStoi->getStoi()->setColumnListCount((short)stoiColumnSet.entries());

    short *stoiColumnList = new (bindWA->wHeap())
      short[stoiColumnSet.entries()];

    for (CollIndex i = 0; i < stoiColumnSet.entries(); i++)
    {
      stoiColumnList[i] = stoiColumnSet[i];
      listedStoi->addUpdateColumn(stoiColumnSet[i]);
    }

    listedStoi->getStoi()->setColumnList(stoiColumnList);
  }

    // the previous implementation assumed that the scope points
    // to the scan table; we don't want to disturb the code and
    // make that happen --

    #ifndef NDEBUG
      GU_DEBUG_Display(bindWA, this, "u");
    #endif

    bindWA->getCurrentScope()->setRETDesc(getRETDesc());
  }
  // QSTUFFF

  CollIndex endSrcUsgIx = bindWA->tableViewUsageList().entries();

  if ((!isScanOnDifferentTable) &&
      (((getOperatorType() == REL_UNARY_INSERT) &&
       !insertFromValuesList && !getGroupAttr()->isEmbeddedInsert()) ||
      (getOperatorType() == REL_UNARY_UPDATE) ||
      (getOperatorType() == REL_UNARY_DELETE))){

    // Special handling of statements that could suffer the 
    // Halloween problem, e.g., "insert into t select from t"
    // or "insert into v select from t", if v references t

    DBG( if (getenv("TVUSG_DEBUG")) bindWA->tableViewUsageList().display(); )

    const NATable *naTableBase = naTable;
    const QualifiedName *viewName = NULL;
    if (isView) {
      // Currently, per Ansi rules, we can only insert through a view if
      // there is a single underlying base table without joins or unions.
      // Since we are binding the view twice for INSERTS,
      // the variable beforeRefcount for the *single* base table has to be 2.
      //
      beforeRefcount = beforeRefcount + 1;
      naTableBase = getTableDesc()->getNATable();
      viewName = &naTable->getTableName();
    }
    if ((getOperatorType() == REL_UNARY_UPDATE ||
         getOperatorType() == REL_UNARY_DELETE) &&
        (child(0)->getOperatorType() == REL_SCAN)) {
      // The table is referenced twice; once for the update/delete and
      // the second time for the scan below it.
      beforeRefcount = beforeRefcount + 1;
    }

    const QualifiedName &tableBaseName = naTableBase->getTableName();
    Int32 afterRefcount =  naTableBase->getReferenceCount();
    NABoolean isSGTableType = getTableName().getSpecialType() == ExtendedQualName::SG_TABLE;

    NAString viewFmtdList(bindWA->wHeap());
    Int32 baseSeenInSrc = 0;
    
    // The views on the table do not need to be obtained
    // if the table type is a SEQUENCE GENERATOR

    if (!isSGTableType)
      baseSeenInSrc = bindWA->tableViewUsageList().getViewsOnTable(
                               begSrcUsgIx, endSrcUsgIx,
                               bindWA->viewCount(),
                               tableBaseName,
                               getTableName().getSpecialType(),
                               viewName,
                               viewFmtdList);

    NABoolean halloween = FALSE;
    if (CmpCommon::getDefault(R2_HALLOWEEN_SUPPORT) == DF_ON) {

      if (beforeRefcount != afterRefcount) {

          // Check to see if we can support this update.
          //
          if(checkForHalloweenR2(afterRefcount - beforeRefcount)) {
            halloween = TRUE;
          }
      }
      else {
        Scan *scanSrc = getScanNode(FALSE/*no assert*/);
        if ((baseSeenInSrc > beforeRefcount) &&
            ((scanSrc && scanSrc->getTableName().isLocationNameSpecified())||
             (getTableName().isLocationNameSpecified()))) {
          halloween = TRUE;
        }
        if (Get_SqlParser_Flags(ALLOW_SPECIALTABLETYPE)) {
          if ((scanSrc && scanSrc->getTableName().isLocationNameSpecified())||
              (getTableName().isLocationNameSpecified())){
            // Do not enforce Halloween check if it is a
            // partition only operation.
            // We assume the programmer knows what he's doing
            // -- hopefully, by doing insert/update/delete
            // operations as part of Partition Management
            // (Move Partition Boundary or Split Partition or
            // Merge Partition. See TEST057 and TEST058)
            halloween = FALSE;
          }
        }
      }
      if (halloween) {
        CMPASSERT(!(isView && viewFmtdList.isNull()));
        *CmpCommon::diags() << DgSqlCode(viewFmtdList.isNull() ? -4026 : -4060)
                            << DgTableName(
                                  tableBaseName.getQualifiedNameAsAnsiString())
                            << DgString0(viewFmtdList);
        bindWA->setErrStatus();
        return this;
      }
    } 
    else {
      // Support for self-referencing updates/Halloween problem.
      if (beforeRefcount != afterRefcount) {

        setAvoidHalloween(TRUE);

        bindWA->getTopRoot()->setAvoidHalloween(TRUE);

        // Decide if access mode (default or specified) is compatible
        // with the use of DP2 locks.  If access mode was specified,
        // it is a property of the naTableBase.
        NABoolean cannotUseDP2Locks = 
             naTableBase->getRefsIncompatibleDP2Halloween();

        // Now check the transaction isolation level, which can override
        // the access mode.  Note that il was initialized above for the
        // check for an updatable trans, i.e., errors 3140 and 3141.
        if((CmpCommon::transMode()->ILtoAT(il) == REPEATABLE_ ) ||
           (CmpCommon::transMode()->ILtoAT(il) == STABLE_     ) ||
           (CmpCommon::transMode()->ILtoAT(il) == BROWSE_     )) 
           cannotUseDP2Locks = TRUE;

        // Save the result with this GenericUpdate object.  It will be 
        // used when the nextSubstitute  methods of TSJFlowRule or TSJRule 
        // call GenericUpdate::configTSJforHalloween.
        if (NOT getHalloweenCannotUseDP2Locks())
          setHalloweenCannotUseDP2Locks(cannotUseDP2Locks);

        // Keep track of which table in the query is the self-ref table.
        // This is a part of the fix for solution 10-071204-9253.
        ((NATable *)naTableBase)->setIsHalloweenTable();
      }
      else {
        Scan *scanSrc = getScanNode(FALSE/*no assert*/);
        if ((baseSeenInSrc > beforeRefcount) &&
            ((scanSrc && scanSrc->getTableName().isLocationNameSpecified())||
             (getTableName().isLocationNameSpecified()))) {
          halloween = TRUE;
        }
        if (Get_SqlParser_Flags(ALLOW_SPECIALTABLETYPE)) {
          if ((scanSrc && scanSrc->getTableName().isLocationNameSpecified())||
              (getTableName().isLocationNameSpecified())){
            // Do not enforce Halloween check if it is a
            // partition only operation.
            // We assume the programmer knows what he's doing
            // -- hopefully, by doing insert/update/delete
            // operations as part of Partition Management
            // (Move Partition Boundary or Split Partition or
            // Merge Partition. See TEST057 and TEST058)
            halloween = FALSE;
          }
        }
        if (halloween) {
          CMPASSERT(!(isView && viewFmtdList.isNull()));
          *CmpCommon::diags() << DgSqlCode(viewFmtdList.isNull() ? -4026 : -4060)
                              << DgTableName(
                                  tableBaseName.getQualifiedNameAsAnsiString())
                              << DgString0(viewFmtdList);
          bindWA->setErrStatus();
          return this;
        }
      }
    }
  }

  // Bind the base class.
  // Allocate an empty RETDesc and attach it to this node, *but* leave the
  // currently scoped RETDesc (that of naTableTop) as is, for further binding
  // in caller Insert::bindNode or LeafInsert/LeafDelete::bindNode.
  //
  RelExpr *boundExpr = bindSelf(bindWA);
  CMPASSERT(boundExpr == this);  // assumed by RETDesc/RI/IM code below
  if (bindWA->errStatus()) return boundExpr;
  setRETDesc(new (bindWA->wHeap()) RETDesc(bindWA));

  // Copy the check constraints to the private memory of the GenericUpdate.
  //
  checkConstraints() = getTableDesc()->getCheckConstraints();

  // Create a key expression for the table to be updated.
  // The code specific to the Insert node is handled in Insert::bindNode.
  //
  if (getOperatorType() == REL_UNARY_UPDATE ||
      getOperatorType() == REL_UNARY_DELETE) {

    if (getTableDesc()->getNATable()->isHiveTable())
      {
        *CmpCommon::diags() << DgSqlCode(-4223)
                            << DgString0("Update/Delete on Hive table is");
        bindWA->setErrStatus();
        return this;
      }

    // SQL syntax requires (and the parser ensures) that a direct descendant
    // (passing thru views) of an update/delete node is a scan node on the
    // same table that is being updated (note that normalizer transformations
    // may change this at a later time).
    // An exception to this rule happens when before triggers are inlined.
    // In this case, the update/delete on the subject table is driven by
    // a Scan on a temp table. The primary key columns of the subject table are
    // a subset of the primary key columns of the temp table, and using the
    // same column names, but not neccessarily in the same order.
    //
    // Update/Delete nodes require expressions in their newRecExpr that can
    // be used to form the primary key of the table to update/delete.
    //
    const NAColumnArray &keyColArray =
      getTableDesc()->getNATable()->getClusteringIndex()->getIndexKeyColumns();
    CollIndex numKeyCols = keyColArray.entries();
    const NAColumnArray &scanColArray =
    scanNode->getTableDesc()->getNATable()->getNAColumnArray();

    for (CollIndex i = 0; i < numKeyCols; i++) {
      // The scan node and the update/delete node both use the SAME table,
      // so their column names are also the same.
      //
      Lng32 colPos = keyColArray[i]->getPosition();
      ItemExpr *guCol = getTableDesc()->getColumnList()[colPos].getItemExpr();
      ItemExpr *scanCol;  // - Triggers
      if (!isScanOnDifferentTable)
        scanCol = scanNode->getTableDesc()->getColumnList()[colPos].getItemExpr();
      else
      {
        // Make sure this is a BaseColumn.
        CMPASSERT(guCol->getOperatorType() == ITM_BASECOLUMN);
        // Find the column name.
        const NAString& colName = ((BaseColumn *)guCol)->getColName();
        // Find a column with the same name, in the table from the Scan node.
        // SYSKEY is an exception since its name in the temp table is "@SYSKEY"
        ExtendedQualName::SpecialTableType tableType =
          scanNode->getTableDesc()->getCorrNameObj().getSpecialType();
        NAColumn *scanNaCol = NULL;
        if (ExtendedQualName::TRIGTEMP_TABLE == tableType && colName == "SYSKEY")
        {
          scanNaCol = scanColArray.getColumn("@SYSKEY");
        }
        else
        {
          scanNaCol = scanColArray.getColumn(colName);
        }
        CMPASSERT(scanNaCol != NULL)
        // Get the position of this column in the Scan table.
        Lng32 scanColPos = scanNaCol->getPosition();
        // Get the Scan BaseColumn.
        scanCol = scanNode->getTableDesc()->getColumnList()[scanColPos].getItemExpr();
      }
      ItemExpr *newKeyPred = new (bindWA->wHeap())
        BiRelat(ITM_EQUAL, guCol, scanCol);
      newKeyPred->bindNode(bindWA);
      beginKeyPred().insert(newKeyPred->getValueId());

      updateToSelectMap().addMapEntry(
           newKeyPred->child(0)->getValueId(),
           newKeyPred->child(1)->getValueId());

    } // loop over key columns

    // All of the indexes also require expressions that can be used to
    // form the primary key of the index to update/delete. Create these
    // item expressions here.
    // (From here to the end of the loop over indexes structurally resembles
    // GenericUpdate::imBindAllIndexes(), but has significant differences.)
    //
    // Remember the value ID's of the scan node index columns for
    // code generation time.
    //

    if ((this->getOperatorType() == REL_UNARY_UPDATE) && isScanOnDifferentTable)
    {
      setScanIndexDesc(NULL);  // for triggers
    }
    else
    {
      setScanIndexDesc(scanNode->getTableDesc()->getClusteringIndex());
    }
  } // REL_UNARY_UPDATE or REL_UNARY_DELETE


  // QSTUFF
  // we need to check whether this code is executed as part of a create view
  // ddl operation using bindWA->inDDL() and prevent indices, contraints and
  // triggers to be added as the catalog manager binding functions cannot
  // handle it right now
  // QSTUFF

  // QSTUFF hack !
  if (getGroupAttr()->isEmbeddedUpdate())
    bindWA->setNameLocListPtr(pLoc);
  bindWA->setInGenericUpdate(inGenericUpdate);
  // QSTUFF

  // set flag that we are binding an Insert/Update/Delete operation
  // Used to disable Join optimization when necessary
  bindWA->setBindingIUD();

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

NABoolean GenericUpdate::checkForMergeRestrictions(BindWA *bindWA)
{
  if (!isMerge())
    return FALSE;


  ValueIdList tempVIDlist;
  getTableDesc()->getIdentityColumn(tempVIDlist);
  NAColumn *identityCol = NULL;
  if (tempVIDlist.entries() > 0)
  {
    ValueId valId = tempVIDlist[0];
    identityCol = valId.getNAColumn();
  }

  // MERGE on a table with BLOB columns is not supported
  if (getTableDesc()->getNATable()->hasLobColumn())
  {
    *CmpCommon::diags() << DgSqlCode(-3241) 
                        << DgString0(" LOB column not allowed.");
    bindWA->setErrStatus();
    return TRUE;

  }
  
  if (getTableDesc()->hasUniqueIndexes() && 
      (CmpCommon::getDefault(MERGE_WITH_UNIQUE_INDEX) == DF_OFF))
  {
    *CmpCommon::diags() << DgSqlCode(-3241) 
			<< DgString0(" unique indexes not allowed.");
    bindWA->setErrStatus();
    return TRUE;
  }
  
  if ((accessOptions().accessType() == SKIP_CONFLICT_) ||
      (getGroupAttr()->isStream()) ||
      (newRecBeforeExprArray().entries() > 0)) // set on rollback
  {
    *CmpCommon::diags() << DgSqlCode(-3241)
                        << DgString0(" Stream, skip conflict or SET ON ROLLBACK not allowed.");
    bindWA->setErrStatus();
    return TRUE;
  }

  if (getGroupAttr()->isEmbeddedUpdateOrDelete())
  {
    *CmpCommon::diags() << DgSqlCode(-3241)
                        << DgString0(" Embedded update/deletes not allowed.");
    bindWA->setErrStatus();
    return TRUE;
  }

  if ((getInliningInfo().hasInlinedActions()) ||
      (getInliningInfo().isEffectiveGU()))
  {
    if (getInliningInfo().hasTriggers()) 
    {
      *CmpCommon::diags() << DgSqlCode(-3241)
                          << DgString0(" Triggers not allowed.");
      bindWA->setErrStatus();
      return TRUE;
    }
  }

  return FALSE;
}

// This class LeafInsert and its companion LeafDelete
// are currently used only by Index Maintenance,
// but we ought not make any assumptions.
// ##IM: It might be useful to add a flag such as GenericUpdate::isIndexTable_
// ##IM: and set it to TRUE in createIMNode().
//
RelExpr *LeafInsert::bindNode(BindWA *bindWA)
{
  if (nodeIsBound())
  {
    bindWA->getCurrentScope()->setRETDesc(getRETDesc());
    return this;
  }

  #ifndef NDEBUG
    if (GU_DEBUG) cerr << "\nLeafInsert " << getUpdTableNameText() << endl;
  #endif

  setInUpdateOrInsert(bindWA, this, REL_INSERT);

  if (getPreconditionTree()) {
    ValueIdSet pc;
    
    getPreconditionTree()->convertToValueIdSet(pc, bindWA, ITM_AND);
    if (bindWA->errStatus())
      return this;
    
    setPreconditionTree(NULL);
    setPrecondition(pc);
  }

  RelExpr *boundExpr = GenericUpdate::bindNode(bindWA);
  if (bindWA->errStatus()) return boundExpr;

  // Make newRecExprArray_ be an ordered set of assign nodes of the form
  //   "ixcol1 = basetblcol1, ixcol2 = basecol2, ..." (for Index Maintenance)

  // Note: For SQL/MP tables, ixcol0 is the keytag, and will need to be
  // handled differently from other columns.


  const ValueIdList &tgtcols = getTableDesc()->getColumnList();

  CMPASSERT(tgtcols.entries() == baseColRefs().entries());
  for (CollIndex i = 0; i < tgtcols.entries(); i++) {
    Assign *assign;
    assign = new (bindWA->wHeap())
      Assign(tgtcols[i].getItemExpr(), baseColRefs()[i], FALSE);
    assign->bindNode(bindWA);
    if (bindWA->errStatus()) return NULL;
    newRecExprArray().insertAt(i, assign->getValueId());
    newRecExpr().insert(assign->getValueId());
    updateToSelectMap().addMapEntry(assign->getTarget(), assign->getSource());
  }

  if (getReferencedMergeIUDIndicator() != NULL_VALUE_ID)
    bindWA->getCurrentScope()->addOuterRef(getReferencedMergeIUDIndicator());
  // RelExpr::bindSelf (in GenericUpdate::bindNode) has done this line, but now
  // any outer refs discovered in bindNode's in the above loop must be added.
  // For Index Maintenance, these must be exactly the set of baseColRefs vids
  // (all the target index cols are from the locally-scoped RETDesc left by
  // the GenericUpdate::bindNode), plus the merge IUD indicator, if used.
  getGroupAttr()->addCharacteristicInputs(bindWA->getCurrentScope()->getOuterRefs());

  // The NATable of getTableName() had been set to INDEX_TABLE so that
  // getNATable would search the right namespace.
  // Now we make the Optimizer treat this as a regular table, not an index
  // (in particular, don't have it choose VSBB sidetree-insert).
  //
  // The TableDesc setting may be redundant/unnecessary, but we do it
  // for completeness and safety.
  //
  // -- Triggers
  // If it is NOT an index table (like maybe a TRIGTEMP_TABLE), leave it alone
  if (getTableName().getSpecialType() == ExtendedQualName::INDEX_TABLE)
  {
    getTableName().setSpecialType(ExtendedQualName::NORMAL_TABLE);
    getTableDesc()->getCorrNameObj().setSpecialType(ExtendedQualName::NORMAL_TABLE);
  }

  setInUpdateOrInsert(bindWA);
  return boundExpr;

} // LeafInsert::bindNode()

RelExpr *LeafDelete::bindNode(BindWA *bindWA)
{
  if (nodeIsBound())
  {
    bindWA->getCurrentScope()->setRETDesc(getRETDesc());
    return this;
  }

  #ifndef NDEBUG
    if (GU_DEBUG) cerr << "\nLeafDelete " << getUpdTableNameText() << endl;
  #endif

  if (getPreconditionTree()) {
    ValueIdSet pc;

    getPreconditionTree()->convertToValueIdSet(pc, bindWA, ITM_AND);
    if (bindWA->errStatus())
      return this;

    setPreconditionTree(NULL);
    setPrecondition(pc);
  }

  RelExpr *boundExpr = GenericUpdate::bindNode(bindWA);
  if (bindWA->errStatus()) return boundExpr;

  //Set the beginKeyPred
  if (TriggersTempTable *tempTableObj = getTrigTemp())
    {      
     
      const ValueIdList &keycols = getTableDesc()->getClusteringIndex()->getIndexKey();
      ItemExpr *keyExpr;
  
      // Normal case - use the UniqueExecuteId builtin function.
      keyExpr = new(bindWA->wHeap()) UniqueExecuteId();
      
      ItemExpr  *tempKeyPred = new(bindWA->wHeap()) BiRelat(ITM_EQUAL, keycols[0].getItemExpr(), keyExpr);     
      tempKeyPred->bindNode(bindWA);
      if (bindWA->errStatus()) return NULL;
      beginKeyPred().insert(tempKeyPred->getValueId());
      // Create the ItemExpr for the constant UniqueIudNum 
      ItemExpr *col2 = new(bindWA->wHeap()) 
             ColReference(new(bindWA->wHeap()) ColRefName(UNIQUEIUD_COLUMN));

      // Compare it to the correct offset.
      BindWA::uniqueIudNumOffset offset = BindWA::uniqueIudNumForInsert ; 
       
      ItemExpr *iudConst = new(bindWA->wHeap()) ConstValue(bindWA->getUniqueIudNum(offset));
      ItemExpr *predIudId = new(bindWA->wHeap()) BiRelat(ITM_EQUAL, keycols[1].getItemExpr(), iudConst);
      predIudId->bindNode(bindWA);
      if (bindWA->errStatus()) return NULL;
      beginKeyPred().insert(predIudId->getValueId());
      
      
       for (CollIndex i = 2; i<keycols.entries(); i++)
         {
           ItemExpr *keyPred = NULL;
           ItemExpr *keyItemExpr = keycols[i].getItemExpr();
           ItemExpr *baseItemExpr = NULL;
           Lng32 keyColPos = keycols[i].getNAColumn()->getPosition();
           baseItemExpr = baseColRefs()[keyColPos];
           keyPred = new (bindWA->wHeap())
             BiRelat(ITM_EQUAL, keyItemExpr, baseItemExpr);
         
           keyPred->bindNode(bindWA);
           if (bindWA->errStatus()) return NULL;
           beginKeyPred().insert(keyPred->getValueId());
         }
    }
    
  else
    {
    
  
  const ValueIdList &keycols = getTableDesc()->getClusteringIndex()->getIndexKey();

  for (CollIndex i = 0; i < keycols.entries() ; i++) 
    {
    ItemExpr *keyPred = 0;
    ItemExpr *keyItemExpr = keycols[i].getItemExpr();
    Lng32 keyColPos = keycols[i].getNAColumn()->getPosition();
    
    ItemExpr *baseItemExpr = NULL;
    // For a unique index (for undo) we are passing in all the index
    // columns in baseColRefs. So we need to find the index key col 
    // position in the index col list and compare the key columns with
    // it's corresponding column in the index column list
    if (isUndoUniqueIndex())
      baseItemExpr = baseColRefs()[keyColPos];
    else
      baseItemExpr = baseColRefs()[i];
    
    keyPred = new (bindWA->wHeap())
      BiRelat(ITM_EQUAL, keyItemExpr, baseItemExpr);

    keyPred->bindNode(bindWA);
    if (bindWA->errStatus()) return NULL;
    beginKeyPred().insert(keyPred->getValueId());
  }
    }
 

  if (isUndoUniqueIndex())
    {
      setUpExecPredForUndoUniqueIndex(bindWA) ;
    }
 
  if (getTrigTemp())
    {
      setUpExecPredForUndoTempTable(bindWA);
    }

  // See LeafInsert::bindNode for comments on remainder of this method.

  if (getReferencedMergeIUDIndicator() != NULL_VALUE_ID)
    bindWA->getCurrentScope()->addOuterRef(getReferencedMergeIUDIndicator());
  getGroupAttr()->addCharacteristicInputs(bindWA->getCurrentScope()->getOuterRefs());

  getTableName().setSpecialType(ExtendedQualName::NORMAL_TABLE);
  getTableDesc()->getCorrNameObj().setSpecialType(ExtendedQualName::NORMAL_TABLE);

  return boundExpr;

} // LeafDelete::bindNode()

void LeafDelete::setUpExecPredForUndoUniqueIndex(BindWA *bindWA)
{
  // Set up the executor predicate . Used in the case of Undo to undo the
  // exact row that caused an error.Note that if we used only the key 
  // columns  to undo, we may end up undoing existing rows . 
  // This is done only for unique indexes 
  ItemExpr *execPred  = NULL;


  const ValueIdList &indexCols = getTableDesc()->getClusteringIndex()->getIndexColumns();
  for ( CollIndex i = 0; i < indexCols.entries(); i++)
    {  
      execPred = new (bindWA->wHeap())
        BiRelat(ITM_EQUAL, indexCols[i].getItemExpr(), baseColRefs()[i]);
      execPred->bindNode(bindWA);
      if (bindWA->errStatus()) return ;
        executorPred() += execPred->getValueId();
    }
  return;
}
void LeafDelete::setUpExecPredForUndoTempTable(BindWA *bindWA)
{

ItemExpr *execPred  = NULL;
 
  const ValueIdList &tempCols = getTableDesc()->getClusteringIndex()->getIndexColumns();
  for ( CollIndex i = 0; i < tempCols.entries(); i++)
    {
      NAString colName(tempCols[i].getNAColumn()->getColName());
      if (colName.data()[0] == '@' && colName.compareTo("@SYSKEY"))
        continue;
      execPred = new (bindWA->wHeap())
        BiRelat(ITM_EQUAL, tempCols[i].getItemExpr(), baseColRefs()[i]);
      execPred->bindNode(bindWA);
      if (bindWA->errStatus()) return;
      executorPred() += execPred->getValueId();
    }

  return;
}

// -----------------------------------------------------------------------
// RelRoutine
// -----------------------------------------------------------------------
// LCOV_EXCL_START - rfi
RelExpr *RelRoutine::bindNode(BindWA *bindWA)
{
  CMPASSERT(0); // For the time being, all classes above implement their own.

  //
  // Allocate an RETDesc and attach it to this and the BindScope.
  // Needs to occur in later classes when we know if we are at table
  // type or not..
  // XXX setRETDesc(new (bindWA->wHeap()) RETDesc(bindWA, getTableDesc()));
  // bindWA->getCurrentScope()->setRETDesc(getRETDesc());
  //
  // Bind the base class.
  //
  RelExpr *boundExpr = bindSelf(bindWA);
  if (bindWA->errStatus()) return boundExpr;
  //
  // Assign the set of columns that belong to the virtual table
  // as the output values that can be produced by this node.
  //
  //  XXX done in later clasees 
  //  getGroupAttr()->addCharacteristicOutputs(getTableDesc()->getColumnList());
  return boundExpr;
} // RelRoutine::bindNode()
// LCOV_EXCL_STOP

// -----------------------------------------------------------------------
// BuiltinTableValuedFunction
// will be called by 
// ExplainFunc and StatisticsFunc
//   Rely on function implementation in TableValuedFunction 
// -----------------------------------------------------------------------

// -----------------------------------------------------------------------
// Explain/Statistics/HiveMD Func
// -----------------------------------------------------------------------
RelExpr *BuiltinTableValuedFunction::bindNode(BindWA *bindWA)
{
  if (nodeIsBound())
  {
    bindWA->getCurrentScope()->setRETDesc(getRETDesc());
    return this;
  }

  //
  // Bind the child nodes.
  //
  bindChildren(bindWA);
  if (bindWA->errStatus())
    return this;

  //
  // Check if there is already an NATable for the Explain/Statistics table.
  //
  if (getOperatorType() == REL_EXPLAIN ||
      getOperatorType() == REL_STATISTICS  ||
      getOperatorType() == REL_HIVEMD_ACCESS ||
      getOperatorType() == REL_HBASE_ACCESS)
  {
    NATable *naTable =  NULL;

    if (getOperatorType() == REL_HBASE_ACCESS)
      {
	// should not reach here
	CMPASSERT(0); 
      }
    else
      {
	CorrName corrName(getVirtualTableName());
	corrName.setSpecialType(ExtendedQualName::VIRTUAL_TABLE);
	NATable *naTable = bindWA->getSchemaDB()->getNATableDB()->
	  get(&corrName.getExtendedQualNameObj());
	
	if (NOT naTable) 
	  {
	    TrafDesc *tableDesc = createVirtualTableDesc();
	    if (tableDesc)
	      naTable = bindWA->getNATable(corrName, FALSE/*catmanUsages*/, tableDesc);
	    
	    if ( ! tableDesc || bindWA->errStatus() )
	      return this;
	  }
	
	// Allocate a TableDesc and attach it to this.
	//
	TableDesc * td = bindWA->createTableDesc(naTable, corrName);
	if (! td || bindWA->errStatus())
	  return this;
	
	setTableDesc(td);
	if (bindWA->errStatus())
	  return this;
      }

    if (getProcAllParamsTree()) 
      {
	((ItemExpr *)getProcAllParamsTree())->convertToValueIdList(getProcAllParamsVids(), bindWA, ITM_ITEM_LIST);
	if (bindWA->errStatus())
	  return this;
	
	// Clear the Tree since we now have gotten vids for all the parameters.
	setProcAllParamsTree(NULL);
	
	Lng32 sqlcode = 0;
	if (getProcAllParamsVids().entries() != numParams()) 
	  {
	    sqlcode = -4067;
	    
	    // 4067 Explain/Statistics requires two operands, of type character.
	    *CmpCommon::diags() << DgSqlCode(sqlcode) << DgString0(getTextForError());
	    bindWA->setErrStatus();
	    return NULL;
	  }
	
	// type any param arguments to fixed char since runtime explain
	// expects arguments to be fixed char.
	Lng32 len = (Lng32)CmpCommon::getDefaultNumeric(VARCHAR_PARAM_DEFAULT_SIZE);
	SQLChar c(len);
	
	for (Lng32 i = 0; i < numParams(); i++)
	  {
	    getProcAllParamsVids()[i].coerceType(c, NA_CHARACTER_TYPE);
	    if (getProcAllParamsVids()[i].getType().getTypeQualifier() != NA_CHARACTER_TYPE)
	      {
		sqlcode = -4067;
		
		// 4067 Explain/Statistics requires two operands, of type character.
		*CmpCommon::diags() << DgSqlCode(sqlcode) << DgString0(getTextForError());
		bindWA->setErrStatus();
		return NULL;
	      }
	    
	    const NAType &typ = getProcAllParamsVids()[i].getType();
	    
	    CharInfo::CharSet chld_cs = ((const CharType&)typ).getCharSet();
	    ItemExpr *ie;
	    if ( chld_cs == CharInfo::UNICODE )
	      {
		ie = new (bindWA->wHeap()) Translate(
						     getProcAllParamsVids()[i].getItemExpr(),
						     Translate::UNICODE_TO_ISO88591);
		ie = ie->bindNode(bindWA);
		getProcAllParamsVids()[i] = ie->getValueId();
	      }
	    
	    if (bindWA->errStatus())
	      return NULL;
	    
	    // For Explain and Statistics all parameters are inputs
	    getProcInputParamsVids().insert(getProcAllParamsVids());
	  } // for
      }
  } // if
  
  return TableValuedFunction::bindNode(bindWA);
    
}

// -----------------------------------------------------------------------
// TableValuedFunction
// -----------------------------------------------------------------------
RelExpr *TableValuedFunction::bindNode(BindWA *bindWA)
{
  if (nodeIsBound())
  {
    bindWA->getCurrentScope()->setRETDesc(getRETDesc());
    return this;
  }

  //
  // Bind the child nodes.
  //
  bindChildren(bindWA);
  if (bindWA->errStatus())
    return this;


  //
  // Allocate an RETDesc and attach it to this and the BindScope.
  //
  setRETDesc(new (bindWA->wHeap()) RETDesc(bindWA, getTableDesc()));
  bindWA->getCurrentScope()->setRETDesc(getRETDesc());
  //
  // Bind the base class.
  //
  RelExpr *boundExpr = bindSelf(bindWA);
  if (bindWA->errStatus()) return boundExpr;
  //
  // Assign the set of columns that belong to the virtual table
  // as the output values that can be produced by this node.
  //
  getGroupAttr()->addCharacteristicOutputs(getTableDesc()->getColumnList());
  return boundExpr;
} // TableValuedFunction::bindNode()


// -----------------------------------------------------------------------
// Member functions for classes Control*
// must be written allowing for a NULL BindWA to be passed in!
//
// This happens when called from the SQLC/SQLCO Preprocessor,
// which needs to bind certain "static-only" statements --
// those which evaluate to STATIC_ONLY_WITH_WORK_FOR_PREPROCESSOR --
// see ControlAbstractClass::isAStaticOnlyStatement().
// -----------------------------------------------------------------------

RelExpr * ControlAbstractClass::bindNode(BindWA *bindWA)
{
  if (nodeIsBound()) return this;

  // Early return if called by SQLC/SQLCO Preprocessor
  if (!bindWA) return this;

  // Allocate an empty RETDesc and attach it to this node and the BindScope.
  setRETDesc(new(bindWA->wHeap()) RETDesc(bindWA));
  bindWA->getCurrentScope()->setRETDesc(getRETDesc());

  return bindSelf(bindWA);
} // ControlAbstractClass::bindNode()


RelExpr * ControlQueryShape::bindNode(BindWA *bindWA)
{
  if (nodeIsBound())
  {
    bindWA->getCurrentScope()->setRETDesc(getRETDesc());
    return this;
  }

  // remember the required shape in the control table
  if (alterArkcmpEnvNow())
    {
      if (getShape())
        ActiveControlDB()->setRequiredShape(this);
      else
        {
          // no shape passed in. Hold or Restore.
          if (holdShape())
            ActiveControlDB()->saveCurrentCQS();
          else
            ActiveControlDB()->restoreCurrentCQS();
          if (ActiveControlDB()->getRequiredShape())
            ActiveControlDB()->getRequiredShape()->holdShape() = holdShape();
        }
    }

  return ControlAbstractClass::bindNode(bindWA);
} // ControlQueryShape::bindNode()


RelExpr * ControlQueryDefault::bindNode(BindWA *bindWA)
{
  if (nodeIsBound())
  {
    bindWA->getCurrentScope()->setRETDesc(getRETDesc());
    return this;
  }

  // Alter the current Defaults settings if this is a static CQD.
  //
  // "AffectYourself" is coming to you courtesy of the Staple Singers:
  // 'Affect yourself, na na na, na na na na, affect yourself, re re re re.'
  // It's neat to find such Binder-relevant lyrics, eh?
  //
  NABoolean affectYourself = alterArkcmpEnvNow();

  assert(!bindWA || bindWA->getSchemaDB() == ActiveSchemaDB());
  NADefaults &defs = ActiveSchemaDB()->getDefaults();
  defs.setState(NADefaults::SET_BY_CQD);

  if ( defs.isReadonlyAttribute(token_) == TRUE )
    {
      Int32 attrNum = defs.lookupAttrName(token_);
      
      if (stricmp(value_, defs.getValue(attrNum)) != 0 ) 
      {
         if (CmpCommon::getDefault(DISABLE_READ_ONLY) == DF_OFF)
         {
           if (bindWA) bindWA->setErrStatus();
           *CmpCommon::diags() << DgSqlCode(-4130) << DgString0(token_);
           return NULL;
         }
       }
    }
  
  if (holdOrRestoreCQD_ == 0)
    {
  attrEnum_ = affectYourself ? defs.validateAndInsert(token_, value_, reset_)
                             : defs.validate         (token_, value_, reset_);
  if (attrEnum_ < 0)
    {
      if (bindWA) bindWA->setErrStatus();
      return NULL;
    }

  // remember this control in the control table
  if (affectYourself)
    ActiveControlDB()->setControlDefault(this);
    }
  else if ((holdOrRestoreCQD_ > 0) && (affectYourself))
    {
      attrEnum_ = defs.holdOrRestore(token_, holdOrRestoreCQD_);
      if (attrEnum_ < 0)
        {
          if (bindWA) bindWA->setErrStatus();
          return NULL;
        }
    }

  return ControlAbstractClass::bindNode(bindWA);
} // ControlQueryDefault::bindNode()


RelExpr * ControlTable::bindNode(BindWA *bindWA)
{
  if (nodeIsBound()) return this;

  CMPASSERT(bindWA);  // can't handle it yet if called from SQLC Preprocessor

  // remember this control in the control table
  tableName_->applyDefaults(bindWA, bindWA->getDefaultSchema());

  NABoolean ok = alterArkcmpEnvNow() ?
                      ActiveControlDB()->setControlTableValue(this) :
                      ActiveControlDB()->validate(this);
  if (NOT ok)
    {
      if (bindWA) bindWA->setErrStatus();
      return NULL;
    }

  return ControlAbstractClass::bindNode(bindWA);
} // ControlTable::bindNode()


RelExpr * ControlSession::bindNode(BindWA *bindWA)
{
  if (nodeIsBound()) return this;

  // remember this control in the control session
  NABoolean ok = alterArkcmpEnvNow() ?
                      ActiveControlDB()->setControlSessionValue(this) :
                      ActiveControlDB()->validate(this);
  if (NOT ok)
    {
      if (bindWA) bindWA->setErrStatus();
      return NULL;
    }

  return ControlAbstractClass::bindNode(bindWA);
} // ControlSession::bindNode()


RelExpr * SetSessionDefault::bindNode(BindWA *bindWA)
{
  if (nodeIsBound())
  {
    bindWA->getCurrentScope()->setRETDesc(getRETDesc());
    return this;
  }

  if (getOperatorType() == REL_SET_SESSION_DEFAULT)
    {
      // trim leading and trailing spaces from token_ and value_
      // and upcase token
      token_ = token_.strip(NAString::both);
      value_ = value_.strip(NAString::both);
      token_.toUpper();

      // TBD:  perhaps add a component privilege that allows others
      //       to set parserflags
      if ((token_ == "SET_PARSERFLAGS") ||
          (token_ == "RESET_PARSERFLAGS"))
        {
          if (!ComUser::isRootUserID())
            {
              *CmpCommon::diags() << DgSqlCode(-1017);
              bindWA->setErrStatus();
              return this;
            }
        }

    }

  return ControlAbstractClass::bindNode(bindWA);
} // SetSessionDefault::bindNode()



// -----------------------------------------------------------------------
// member function for class RelSetTimeout
// -----------------------------------------------------------------------

RelExpr * RelSetTimeout::bindNode(BindWA *bindWA)
{
  if (nodeIsBound()) return this;

  // Allocate an empty RETDesc and attach it to this node and the BindScope.
  setRETDesc(new(bindWA->wHeap()) RETDesc(bindWA));
  bindWA->getCurrentScope()->setRETDesc(getRETDesc());

  if (timeoutValueExpr_) {  // bind the timeout-value expression
    timeoutValueExpr_->bindNode(bindWA);
    if (bindWA->errStatus()) return this;
  }

  if ( ! strcmp("*", userTableName_.getCorrNameAsString()) )
    isForAllTables_ = TRUE ;

  HostVar *proto = userTableName_.getPrototype() ;

  // Check for the not-supported  "SET STREAM TIMEOUT" on a specific stream
  if ( isStream_ && ! isForAllTables_ ) {
    *CmpCommon::diags() << DgSqlCode(-3187);
    bindWA->setErrStatus();
    return this;
  }

  if ( isForAllTables_ ) { /* do nothing */ }
  else if ( proto ) { // it is a HOSTVAR or DEFINE
    userTableName_.applyDefaults(bindWA, bindWA->getDefaultSchema());
    CMPASSERT ( proto->isPrototypeValid() ) ;
    userTableName_.getPrototype()->bindNode(bindWA);
  } else { // i.e., an explicit table name was specified
    // Get the NATable for this table.
    NATable *naTable = bindWA->getNATable(userTableName_, FALSE);
    if (bindWA->errStatus()) return this;  // e.g. error: table does not exist

    if ( naTable->getViewText() ) {  // can not set lock timeout on a view
      *CmpCommon::diags() << DgSqlCode(-3189);
      bindWA->setErrStatus();
      return this;
    }

    // Extract and keep the physical file name
    const NAFileSet * clstInd = naTable->getClusteringIndex() ;
    setPhysicalFileName( clstInd->getFileSetName().getQualifiedNameAsString().data() );
  }

  // Bind the base class.
  return bindSelf(bindWA);
}
// -----------------------------------------------------------------------
// member functions for class Describe
// (see sqlcomp/CmpDescribe.cpp for execution of the request)
// -----------------------------------------------------------------------

RelExpr *Describe::bindNode(BindWA *bindWA)
{
  if (nodeIsBound())
  {
    bindWA->getCurrentScope()->setRETDesc(getRETDesc());
    return this;
  }

  // SHOWCONTROL DEFAULT "magic string"; -- see ShowSchema.h and ExSqlComp.cpp
  if (getFormat() == CONTROL_DEFAULTS_) {
    if (getDescribedTableName().getQualifiedNameObj().getObjectName() ==
        ShowSchema::ShowControlDefaultSchemaMagic())
    {
      // Return info in an error message (a warning msg doesn't cut it).
      const SchemaName &catsch = bindWA->getDefaultSchema();
      NAString cat(catsch.getCatalogNameAsAnsiString(),bindWA->wHeap());
      NAString sch(catsch.getUnqualifiedSchemaNameAsAnsiString(),bindWA->wHeap());
      //
      if (SqlParser_NAMETYPE == DF_NSK) {
// LCOV_EXCL_START - nsk
        // The cat & sch from the BindWA are really from MPLOC.
        // Get the real ANSI cat & sch, prepending them to the strings
        // and put the MPLOC info in parens.
        const SchemaName &csAnsi = ActiveSchemaDB()->getDefaultSchema();
        NAString cAnsi(csAnsi.getCatalogNameAsAnsiString(),bindWA->wHeap());
        NAString sAnsi(csAnsi.getUnqualifiedSchemaNameAsAnsiString(),bindWA->wHeap());
        cat.prepend(cAnsi + " (");
        cat += ")";
        sch.prepend(sAnsi + " (");
        sch += ")";
// LCOV_EXCL_STOP
      }
      *CmpCommon::diags() << DgSqlCode(-ABS(ShowSchema::DiagSqlCode()))
        << DgCatalogName(cat) << DgSchemaName (sch);
      bindWA->setErrStatus();
      return this;
    }
    if (getDescribedTableName().getQualifiedNameObj().getObjectName() ==
        GetControlDefaults::GetExternalizedDefaultsMagic())
    {
      // Return info in an error message (a warning msg doesn't cut it).
      NAString cqdPairs(bindWA->wHeap());
      size_t lenN, lenV;
      char lenbufN[10], lenbufV[10];
      const char *nam, *val;
      NADefaults &defs = bindWA->getSchemaDB()->getDefaults();
      for (CollIndex i = 0; i < defs.numDefaultAttributes(); i++ ) {
        if (defs.getCurrentDefaultsAttrNameAndValue(i, nam, val, TRUE)) {
          lenN = strlen(nam);
          lenV = strlen(val);
          CMPASSERT(lenN <= 999 && lenV <= 999);  // %3d coming up next
          sprintf(lenbufN, "%3d", (UInt32)lenN);
          sprintf(lenbufV, "%3d", (UInt32)lenV);
          cqdPairs += NAString(lenbufN) + nam + lenbufV + val;
        }
      }
      *CmpCommon::diags()
        << DgSqlCode(-ABS(GetControlDefaults::DiagSqlCode()))
        << DgString0(cqdPairs);
      bindWA->setErrStatus();
      return this;
    }
  }

  // Create a descriptor for a virtual table to look like this:
  // 
  //	CREATE TABLE DESCRIBE__ (DESCRIBE__COL VARCHAR(3000) NOT NULL);
  // For SeaQuest Unicode:
  //	CREATE TABLE DESCRIBE__ (DESCRIBE__COL VARCHAR(3000 BYTES) CHARACTER SET UTF8 NOT NULL);
  //
  #define MAX_DESCRIBE_LEN 3000 // e.g., SQL/MP Views.ViewText column

  // TrafAllocateDDLdesc requires that HEAP (STMTHEAP) be used for new's!

  TrafDesc * table_desc = TrafAllocateDDLdesc(DESC_TABLE_TYPE, NULL);
  table_desc->tableDesc()->tablename = new HEAP char[strlen("DESCRIBE__")+1];
  strcpy(table_desc->tableDesc()->tablename, "DESCRIBE__");

  // see nearly identical code below for indexes file desc
  TrafDesc * files_desc = TrafAllocateDDLdesc(DESC_FILES_TYPE, NULL);
  table_desc->tableDesc()->files_desc = files_desc;

  Lng32 colnumber = 0, offset = 0;
  TrafDesc * column_desc = TrafMakeColumnDesc(
       table_desc->tableDesc()->tablename,
       "DESCRIBE__COL",
       colnumber,      // INOUT
       REC_BYTE_V_ASCII,
       MAX_DESCRIBE_LEN,
       offset,      // INOUT
       FALSE/*not null*/,
       SQLCHARSETCODE_UNKNOWN,
       NULL);
  column_desc->columnsDesc()->character_set    = CharInfo::UTF8;
  column_desc->columnsDesc()->encoding_charset = CharInfo::UTF8;

  table_desc->tableDesc()->colcount = colnumber;
  table_desc->tableDesc()->record_length = offset;

  TrafDesc * index_desc = TrafAllocateDDLdesc(DESC_INDEXES_TYPE, NULL);
  index_desc->indexesDesc()->tablename = table_desc->tableDesc()->tablename;
  index_desc->indexesDesc()->indexname = table_desc->tableDesc()->tablename;
  index_desc->indexesDesc()->keytag = 0; // primary index
  index_desc->indexesDesc()->record_length = table_desc->tableDesc()->record_length;
  index_desc->indexesDesc()->colcount = table_desc->tableDesc()->colcount;
  index_desc->indexesDesc()->blocksize = 4096; // anything > 0

  // Cannot simply point to same files desc as the table one,
  // because then ReadTableDef::deleteTree frees same memory twice (error)
  TrafDesc * i_files_desc = TrafAllocateDDLdesc(DESC_FILES_TYPE, NULL);
  index_desc->indexesDesc()->files_desc = i_files_desc;

  TrafDesc * key_desc = TrafAllocateDDLdesc(DESC_KEYS_TYPE, NULL);
  key_desc->keysDesc()->keyseqnumber = 1;
  key_desc->keysDesc()->tablecolnumber = 0;
  key_desc->keysDesc()->setDescending(FALSE);

  index_desc->indexesDesc()->keys_desc = key_desc;
  table_desc->tableDesc()->columns_desc = column_desc;
  table_desc->tableDesc()->indexes_desc = index_desc;

  //
  // Get the NATable for this object.
  //
  CorrName corrName("DESCRIBE__");
  corrName.setSpecialType(ExtendedQualName::VIRTUAL_TABLE);
  NATable *naTable = bindWA->getNATable(corrName, FALSE/*CatBind*/, table_desc);
  if (bindWA->errStatus())
    return this;
  //
  // Allocate a TableDesc (which is not the table_desc we just constructed)
  // and attach it to the Scan node.
  //
  setTableDesc(bindWA->createTableDesc(naTable, corrName));
  if (bindWA->errStatus())
    return this;
  //
  // Allocate an RETDesc and attach it to the Scan node and the BindScope.
  //
  setRETDesc(new (bindWA->wHeap()) RETDesc(bindWA, getTableDesc()));
  bindWA->getCurrentScope()->setRETDesc(getRETDesc());
  //
  // Bind the described table CorrName member, the children, and the base class.
  //

  if (! describedTableName_.getQualifiedNameObj().getObjectName().isNull())
    {
      if ((getFormat() >= CONTROL_FIRST_) &&
          (getFormat() <= CONTROL_LAST_))
        {
          describedTableName_.applyDefaults(bindWA, bindWA->getDefaultSchema());
        }
      else
        {
          // do not override schema for showddl
          bindWA->setToOverrideSchema(FALSE);  
          
          // if this is a showlabel command on a resource fork, 
          // but the describedTableName
          // is not a fully qualified rfork name, then get the rfork name
          // for the specified table.
          if ((getFormat() == Describe::LABEL_) &&
              (describedTableName_.getSpecialType() == ExtendedQualName::RESOURCE_FORK) &&
              (describedTableName_.getLocationName().isNull()))
            {
              describedTableName_.setSpecialType(ExtendedQualName::NORMAL_TABLE);
              NATable *naTable = bindWA->getNATable(describedTableName_);
              if (NOT bindWA->errStatus())
                {
                  // replace the describedTableName with its rfork name.
                  describedTableName_.setSpecialType(ExtendedQualName::RESOURCE_FORK);
                
                  NAString rforkName = naTable->getClusteringIndex()->getFileSetName().getQualifiedNameAsString();
                  char * rforkNameData = (char*)(rforkName.data());
                  rforkNameData[rforkName.length()-1] += 1;
                  describedTableName_.setLocationName(rforkName);
                }
            }

          // check if we need to consider public schema before 
          // describedTableName_ is qualified by getNATable
          if (describedTableName_.getQualifiedNameObj().getSchemaName().isNull())
            setToTryPublicSchema(TRUE);
      
          bindWA->getNATable(describedTableName_);
          if (bindWA->errStatus()) 
            {
              // if volatile related error, return it.
              // Otherwise, clear diags and let this error be caught
              // when describe is executed.
              if ((CmpCommon::diags()->mainSQLCODE() == -4190) ||
                  (CmpCommon::diags()->mainSQLCODE() == -4191) ||
                  (CmpCommon::diags()->mainSQLCODE() == -4192) ||
                  (CmpCommon::diags()->mainSQLCODE() == -4193) ||
                  (CmpCommon::diags()->mainSQLCODE() == -4155) || // define not supported
                  (CmpCommon::diags()->mainSQLCODE() == -4086) || // catch Define Not Found error
                  (CmpCommon::diags()->mainSQLCODE() == -30044)|| // default schema access error
                  (CmpCommon::diags()->mainSQLCODE() == -4261) || // reserved schema
                  (CmpCommon::diags()->mainSQLCODE() == -1398))   // uninit hbase
                    return this;
      
              CmpCommon::diags()->clear();
              bindWA->resetErrStatus();
            }
        }
      if (pUUDFName_ NEQ NULL AND NOT pUUDFName_->getObjectName().isNull())
      {
          pUUDFName_->applyDefaults(bindWA->getDefaultSchema());
      }
    }
  
  bindChildren(bindWA);
  RelExpr *boundExpr = bindSelf(bindWA);
  if (bindWA->errStatus()) return boundExpr;
  //
  // Assign the set of columns that belong to the table to be scanned
  // as the output values that can be produced by this scan.
  //
  getGroupAttr()->addCharacteristicOutputs(getTableDesc()->getColumnList());
  return boundExpr;
} // Describe::bindNode()

// -----------------------------------------------------------------------
// member functions for class RelLock
// -----------------------------------------------------------------------

RelExpr * RelLock::bindNode(BindWA *bindWA)
{
  if (nodeIsBound())
  {
    bindWA->getCurrentScope()->setRETDesc(getRETDesc());
    return this;
  }

  // do not do override schema for this
  bindWA->setToOverrideSchema(FALSE);

  // Get the NATable for this object.
  NATable *naTable = bindWA->getNATable(getTableName());
  if (bindWA->errStatus())
    return this;

  NABoolean isView = !!naTable->getViewText();
  if (isView && !naTable->isAnMV())
    {
      *CmpCommon::diags() << DgSqlCode(-4222)
                          << DgString0("Views");
      bindWA->setErrStatus();
      return this;
    }
  else
    {
      baseTableNameList_.insert((CorrName *)getPtrToTableName());
    }

  Int32 locSpec = 0;
  NAString tabNames(bindWA->wHeap());

  for (CollIndex i = 0; i < baseTableNameList_.entries(); i++) {
    naTable = bindWA->getNATable(*baseTableNameList_[i]);
    if (bindWA->errStatus())
      return this;

    // Genesis 10-990212-6908:
    // Ignore the user-specified correlation name --
    // use just the 3-part tblname (and any LOCATION clause, etc).
    // Then, insert only unique names into tabIds_ --
    // to prevent XTNM duplicates (errmsg 4056)
    // when multiple layered views reference the same table or corr-name.

    CorrName bt(*baseTableNameList_[i]);
    bt.setCorrName("");

    NABoolean haveTDforThisBT = FALSE;
    for (CollIndex j = 0; j < tabIds_.entries(); j++) {
      if (bt == tabIds_[j]->getCorrNameObj()) {
        haveTDforThisBT = TRUE;
        break;
      }
    }

    if (!haveTDforThisBT) {
      if (bt.isLocationNameSpecified()) locSpec++;
      tabNames += NAString(", ") +
                    bt.getQualifiedNameObj().getQualifiedNameAsAnsiString();
      tabIds_.insert(bindWA->createTableDesc(naTable, bt));
      if (bindWA->errStatus()) return this;
    }
  }

  if (tabIds_.entries() > 1) {
    CMPASSERT(locSpec == 0);
    tabNames.remove(0, 2);   // remove leading ", "
    // Warning 4124: More than one table will be locked: $0~String0.
    // (warning, so user realizes the effects of this command
    // when run on a view which joins tables...).
    *CmpCommon::diags() << DgSqlCode(+4124) << DgString0(tabNames);
  }

  if ((isView) ||
      (tabIds_.entries() > 1) ||
      (baseTableNameList_.entries() > 1) ||
      (CmpCommon::getDefault(ATTEMPT_ESP_PARALLELISM) == DF_OFF))
    {
      parallelExecution_ = FALSE;
    }

  // Allocate an empty RETDesc and attach it to this node and the BindScope.
  setRETDesc(new(bindWA->wHeap()) RETDesc(bindWA));
  bindWA->getCurrentScope()->setRETDesc(getRETDesc());

  // Bind the base class.
  return bindSelf(bindWA);
} // RelLock::bindNode()

// -----------------------------------------------------------------------
// member functions for class RelTransaction
// -----------------------------------------------------------------------

RelExpr * RelTransaction::bindNode(BindWA *bindWA)
{
  if (nodeIsBound())
  {
    bindWA->getCurrentScope()->setRETDesc(getRETDesc());
    return this;
  }

  // Allocate an empty RETDesc and attach it to this node and the BindScope.
  setRETDesc(new(bindWA->wHeap()) RETDesc(bindWA));
  bindWA->getCurrentScope()->setRETDesc(getRETDesc());

  if (diagAreaSizeExpr_) {
    diagAreaSizeExpr_->bindNode(bindWA);
    if (bindWA->errStatus()) return this;
  }

  // "mode_" is NULL if BEGIN/COMMIT/ROLLBACK WORK, nonNULL if SET TRANSACTION.
  if (mode_) {
    if ((mode_->autoCommit() != TransMode::AC_NOT_SPECIFIED_) || 
        (mode_->getAutoBeginOn() != 0) ||
        (mode_->getAutoBeginOff() != 0))
    {
      CMPASSERT(mode_->isolationLevel() == TransMode::IL_NOT_SPECIFIED_ &&
                mode_->accessMode()     == TransMode::AM_NOT_SPECIFIED_);
    }
    else 
    {
      // See Ansi 14.1, especially SR 4.
      // Similar code must be maintained in
      // comexe/ExControlArea::addControl() and NADefaults::validateAndInsert().

      // SET TRANSACTION w/o specifying ISOLATION LEVEL reverts TransMode to
      // the NADefaults setting of ISOLATION_LEVEL
      // (which the user should set to SERIALIZABLE if they want
      // SET TRANSACTION to be Ansi conformant).

      if (mode_->isolationLevel() == TransMode::IL_NOT_SPECIFIED_)
      {
        if (CmpCommon::getDefault(ISOLATION_LEVEL_FOR_UPDATES) == DF_NONE)
          bindWA->getSchemaDB()->getDefaults().getIsolationLevel(
            mode_->isolationLevel()); // short int
        else
          bindWA->getSchemaDB()->getDefaults().getIsolationLevel(
            mode_->isolationLevel(), // short int
            CmpCommon::getDefault(ISOLATION_LEVEL_FOR_UPDATES));
      }

      if (mode_->accessMode() == TransMode::AM_NOT_SPECIFIED_)
        mode_->updateAccessModeFromIsolationLevel(
          mode_->getIsolationLevel());   // enum

      // 3114 Transaction access mode RW is incompatible with isolation level RU
      if (mode_->accessMode() == TransMode::READ_WRITE_ &&
          mode_->isolationLevel() == TransMode::READ_UNCOMMITTED_) {
        *CmpCommon::diags() << DgSqlCode(-3114);
        bindWA->setErrStatus();
        return this;
      }

      if (mode_->rollbackMode() == TransMode::ROLLBACK_MODE_NOT_SPECIFIED_)
          mode_->rollbackMode() = TransMode::ROLLBACK_MODE_WAITED_ ;
      // 4352 - 
      if (mode_->multiCommit() == TransMode::MC_ON_)
        {
          if (mode_->invalidMultiCommitCompatibility())
            {
              *CmpCommon::diags() << DgSqlCode(-4352);
              bindWA->setErrStatus();
              return this;
            }

        }
    }
  } // SET TRANSACTION stmt

  // Bind the base class.
  return bindSelf(bindWA);
}


// Transpose::bindNode - Bind the transpose node.
// Coming into the node (from the parser) there are two ItemExpr Trees:
//
//   keyCol_: The ItemExpr contains a ColReference to the key column which
//   is added by the transpose node. This pointer ia set to NULL by bindNode.
//   If keyCol_ is NULL coming into the bindNode, then no key Column is
//   generated for this transpose.
//
//   transValsTree_: This ItemExpr tree contains a list of pairs which is
//   NULL terminated (for ease of processing).  Each pair contains in child(0),
//   a list of transpose items for a given transpose set and in child(1), a
//   list of ColReferences to the new value columns associated with this
//   transpose set. A transpose item is a list of value expressions.
//   This pointer is set to NULL by bindNode.
//
// For Example:
//
//           SELECT *
//             FROM Table
//        TRANSPOSE A,B AS C1
//                  X,Y,Z as C2
//                  (1,'hello'),(2,'world') AS (C3, C4)
//           KEY BY K1
//
//   For the above query, after parsing, the TRANSPOSE node will look like:
//
//                  TRANSPOSE
//               keyCol_  transValsTree_
//                  |      |
//                  K1     O------O---------O---NULL
//                         |      |         |
//                         O      O         O--O
//                         |\     |\        |  |\
//                         O C1   O C2      | C3 C4
//                         |\     |\        O---------O---NULL
//                         A O    X O       |         |
//                           |\     |\      O         O
//                           B NULL Y O     |\        |\
//                                    |\    1 'hello' 2 'world'
//                                    Z NULL
//
// O - represent ITM_LIST nodes.
//
// bindNode binds this structure to form a new structure contained in
// the vector of ValueIdLists, transUnionVector_.
//
//   transUnionVector_: This is a vector of ValueIdLists. There is one entry
//   for each transpose set, plus one entry for the key values. Each entry
//   contains a list of ValueIdUnion Nodes. The first entry contains a list
//   with one ValueIdUnion node. This node is for the Const. Values (1 - N)
//   representing the Key Values. The other entries contain lists of
//   ValueIdUnion nodes for the Transposed Values. Each of these entries of
//   the vector represent a transpose set.  If the transpose set contains a
//   list of values, then there will be only one ValueIdUnion node in the
//   list.  If the transpose set contains a list of lists of values, then
//   there will be as many ValueIdUnion nodes as there are items in the
//   sublists. (see example below.)
//   transUnionVector_ is generated in bindNode().
//
//   transUnionVectorSize_: This is the number of entries in transUnionVector_.
//
// For the above query, after binding, the TRANSPOSE node will look like:
//
//               TRANSPOSE
//                 transUnionVectorSize_: 4
//                 transUnionVector_:
//                     ValueIdUnion(1,2,3,4,5,6,7)
//                     ValueIdUnion(A,B)
//                     ValueIdUnion(X,Y,Z)
//                     ValueIdUnion(1,2) , ValueIdUnion('hello','world')
//
//
RelExpr *Transpose::bindNode(BindWA *bindWA)
{

  // If this node has already been bound, we are done.
  //
  if (nodeIsBound())
  {
    bindWA->getCurrentScope()->setRETDesc(getRETDesc());
    return this;
  }

  BindContext *curContext = bindWA->getCurrentScope()->context();
  curContext->inTransposeClause() = TRUE;

  // Bind the child nodes.
  //
  bindChildren(bindWA);
  if (bindWA->errStatus()) return this;

  // At this point the Transpose relational operator has two or three
  // expressions:
  // keyCol_        --- A ColReference to the new keyCol. (possibly NULL)
  // transValsTree_ --- expressions for the transposed values and their
  //                    ColReferences.
  //
  // transpose::bindNode() performs the following steps:
  //
  // 1 - Construct a list of transpose set expressions
  //     and a list of ColReferences associated with each transpose set
  //     expression.
  //
  // 2 - Allocate a return descriptor and add the columns from the
  //     childs descriptor to it.
  //
  // 3 - Allocate the transUnionVector_
  //
  // 4 - Construct a ValueIdUnion node for the Key Values. Bind this node.
  //     Add the keyColName to the return descriptor with the valueId of this
  //     node.  Add the valueId of this node as the first entry of
  //     a ValueIdList in the first entry of transUnionVector_.
  //
  // 5 - For each transpose set, Construct as many ValueIdUnion nodes as
  //     there are values in each item of the transpose set. Within a
  //     given transpose set, the number of values per item must be the
  //     same.  In the example above, the third transpose set contains the
  //     items (1, 'hello') and (2, 'world'). These both have two values per
  //     item.  The others all have 1 value per item. The ValueIdUnions
  //     generated will contain the i'th value from each item. Bind each
  //     of these ValueUnionId nodes. Add the value column name to the
  //     return descriptor with the valueId of this node. Add the valueId
  //     of this node the ValueIdList in the proper entry of
  //     transUnionVector_.
  //
  // 6 - Set the return descriptor, and bindSelf.
  //

  CollIndex i, j, k;
  CollIndex numTransSets = 0;

  // Get a pointer to the head of this list of pairs.
  // This is the last time we will have to reference this tree.
  //
  ItemExpr *transTree = (ItemExpr *)removeTransValsTree();

  // Allocate two ItemExpr Lists. One for the list of lists of (lists of)
  // expressions. And the other for the list of (lists of)  ColReferences.
  //
  ItemExprList transSetsList(bindWA->wHeap());
  ItemExprList newColsList(bindWA->wHeap());

  // Populate these lists and
  // determine how many transpose sets there are in this tree.
  // In the example above, there should be three.
  //
  while (transTree) {
    transSetsList.insert(transTree->child(0)->child(0));
    newColsList.insert(transTree->child(0)->child(1));
    numTransSets++;
    transTree = transTree->child(1);
  }

  // Must have at least one value expression in the transpose values list.
  //
  CMPASSERT(numTransSets > 0);

  // Using the example above, at this point:
  //
  //   transSetsList                          newColsList
  //  |      |      |                          |   |   |
  //  O      O      O---------O---NULL         C1  C2  O
  //  |\     |\     |         |                        |\
  //  A O    X O    O         O                       C3 C4
  //    |\     |\   |\        |\
  //    B NULL Y O  1 'hello' 2 'world'
  //             |\
  //             Z NULL
  //
  // Allocate the return descriptor.  This will contain the
  // columns of the child node as well as the new columns added
  // by the transpose operator.  The column order is:
  //
  //       [childs columns][keyCol][valCol1][valCol2] ...
  //
  // Using the example, this would be:
  //
  //       [childs columns], K1, C1, C2, C3, C4
  //
  RETDesc *resultTable = new(bindWA->wHeap()) RETDesc(bindWA);

  // Add the columns from the child to the RETDesc.
  //
  const RETDesc &childTable = *child(0)->getRETDesc();
  resultTable->addColumns(bindWA, childTable);

  transUnionVectorSize_ = numTransSets + 1;
  transUnionVector() = new(bindWA->wHeap())
    ValueIdList[transUnionVectorSize_];
  //If there is a lob column return error. Transpose not allowed on lob columns.
 
  for (i = 0; i < resultTable->getDegree(); i++)
    {
      if ((resultTable->getType(i)).getFSDatatype() == REC_BLOB || 
	  (resultTable->getType(i)).getFSDatatype() == REC_CLOB)
	{
	  *CmpCommon::diags() << DgSqlCode(-4322);
	  bindWA->setErrStatus();
	  return this;
	}
    }
 
    

  // Get the key column reference
  // This is the last time we need this ItemExpr.
  //
  ColReference *keyColumn = (ColReference *)removeKeyCol();

  // If no key column has been specified, then no key col will be
  // generated.
  //
  if (keyColumn) {

    //Get the key column name.
    //
    NAString keyColName(keyColumn->getColRefNameObj().getColName(), bindWA->wHeap());

    // Construct and Bind the ValueIdUnion node as the union of constants
    // from 1 to the total number of transpose expressions. In the above
    // example this will be from 1 to 9, since there are 3 transpose sets
    // and each set has 3 expressions.
    //
    ValueIdList constVals;
    ItemExpr *constExpr;

    CollIndex keyVal;

    // For each expression in each transpose set.
    //
    for (i = 0, keyVal = 1; i < numTransSets; i++) {

      // Determine how many expressions are in each transpose set.
      //
      CollIndex numTransItems = 0;

      ItemExpr *transSet = transSetsList[i];

      while (transSet) {
        numTransItems++;
        transSet = transSet->child(1);
      }

      for (j = 0; j < numTransItems; j++, keyVal++) {

        // Construct the constant value
        //
#pragma nowarn(1506)   // warning elimination
        constExpr = new(bindWA->wHeap()) SystemLiteral(keyVal);
#pragma warn(1506)  // warning elimination

        // Bind the constant value.
        //
        constExpr->bindNode(bindWA);
        if (bindWA->errStatus()) return this;

        // Insert the valueId into the list
        //
        constVals.insert(constExpr->getValueId());
      }
    }

    // Construct the ValueIdUnion node which will represent the key Col.
    //
    ValueIdUnion *keyVidu = new(bindWA->wHeap())
      ValueIdUnion(constVals, NULL_VALUE_ID);

    // Bind the ValueIdUnion node.
    //
    keyVidu->bindNode(bindWA);
    if (bindWA->errStatus()) return this;

    // Add the key column to the RETDesc (as the union of all the constants)
    //
    resultTable->addColumn(bindWA, keyColName, keyVidu->getValueId());

    // The ValueIdUnion for the Key Values is the first entry in
    // the ValueIdList of the first entry of transUnionVector_.
    //
    transUnionVector()[0].insert(keyVidu->getValueId());
  }

  // For each transpose set,
  //   - bind the list of expressions.
  //   - Construct a ValueIdUnion node containing the resulting valueIds.
  //   - Bind this ValueIdUnion node
  //   - Add the associate column name to the return descriptor with the
  //     valueId of the ValueIdUnion node.
  //
  ValueIdList transVals;

  for (i = 0; i < numTransSets; i++) {

    // The column(s) associated with this transpose set.
    // (will be used below, within the inner loop)
    //
    ItemExprList newCols(newColsList[i], bindWA->wHeap());

    // Determine how many expressions are in each transpose set.
    //
    CollIndex numTransItems = 0;

    ItemExpr *transSet = transSetsList[i];

    ItemExprList transItemList(bindWA->wHeap());

    // Populate this list.
    //
    while (transSet) {
      transItemList.insert(transSet->child(0));
      numTransItems++;
      transSet = transSet->child(1);
    }

    ItemExprList transItem(transItemList[0], bindWA->wHeap());

    CollIndex numTransVals = transItem.entries();

    // For a given transpose set, the number of new columns declared
    // must be the same as the number of items per value.  In the example
    // above, the third transpose  set contains the items (1, 'hello') and
    // the columns (C3,C4) both have two entries.
    //
    if (numTransVals != newCols.entries()) {
      *CmpCommon::diags() << DgSqlCode(-4088);
      bindWA->setErrStatus();
      return this;
    }

    for (k = 0; k < numTransVals; k++) {

      ItemExpr *transValueUnionExpr = NULL;

      for (j = 0; j < numTransItems; j++) {

        transItem.clear();
        transItem.insertTree(transItemList[j], ITM_ITEM_LIST);

        // Within a given transpose set, the number of values per item
        // must be the same.  In the example above, the third transpose
        // set contains the items (1, 'hello') and (2, 'world'). These
        // both have two values per item.  The others all have 1 value
        // per item.
        //

        if (numTransVals != transItem.entries()) {
          *CmpCommon::diags() << DgSqlCode(-4088);
          bindWA->setErrStatus();
          return this;
        }

        if (transValueUnionExpr == NULL) {
          transValueUnionExpr = transItem[k];
        }
        else
        {
          transValueUnionExpr = new (bindWA->wHeap())
          ItemList(transValueUnionExpr, transItem[k]);
        }
      }


      // Bind the Transpose Values expressions. Get the expression value Id's
      //
      transVals.clear();
      if(transValueUnionExpr != NULL )
       transValueUnionExpr->convertToValueIdList(transVals,
                                                 bindWA,
                                                 ITM_ITEM_LIST);
      if (bindWA->errStatus()) return this;

      // If there are more than one transpose set, the value columns
      // generated by transpose can be NULL. So, make sure the typing is
      // done properly. This is done by setting the first in the list to
      // be nullable, then the ValueIdUnion will be nullable and the new
      // column will be nullable.  This is not done on the ValueIdUnion
      // node itself, since it will add an Null Instantiate node, and
      // we later assume that this node will always be a ValueIdUnion
      // node.
      //
      if (numTransSets > 1) {
        ValueId valId = transVals[0];

        transVals[0] = valId.nullInstantiate(bindWA, FALSE);
      }

      // Construct and Bind the ValueIdUnion node for the transpose vals.
      //
      ValueIdUnion *valVidu = new(bindWA->wHeap())
      ValueIdUnion(transVals, NULL_VALUE_ID);

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

      // Insert this valueIdUnion node into the list of valueIdUnions
      // in the proper entry in transUnionVector_
      //
      transUnionVector()[i + 1].insert(valVidu->getValueId());

      // Get the val column reference
      //
      ColReference *valCol = (ColReference *)newCols[k];

      // Must have Column Refs to val column.
      //
      CMPASSERT(valCol);

      //Get the val column name.
      //
      NAString valColName( valCol->getColRefNameObj().getColName(), bindWA->wHeap());

      // Add the transpose column
      // (as the union of all of the transposed value columns)
      //
      resultTable->addColumn(bindWA, valColName, valVidu->getValueId());
    }
  }

  // Set the return descriptor
  //
  setRETDesc(resultTable);
  bindWA->getCurrentScope()->setRETDesc(resultTable);

  //
  // Bind the base class.
  //
  return bindSelf(bindWA);
} // Transpose::bindNode()

// -----------------------------------------------------------------------
// The Pack node binds itself by componsing its packing expression from
// all the columns available in its child's RETDesc. The packed columns
// produced by the packing expression are then made available in the Pack
// node's own RETDesc.
// -----------------------------------------------------------------------
RelExpr* Pack::bindNode(BindWA* bindWA)
{
  if (nodeIsBound())
  {
    bindWA->getCurrentScope()->setRETDesc(getRETDesc());
    return this;
  }

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

  // ---------------------------------------------------------------------
  // The Pack node has a packing expression stored as packingExprTree_
  // before binding. If packingExprTree_ is NULL, we are just going to
  // pick up all the columns from the output of its child. During binding,
  // this tree is converted into a value id list.
  // ---------------------------------------------------------------------

  // Create and bind the packing factor item expression.
#pragma nowarn(1506)   // warning elimination
  ItemExpr* pfie = new (bindWA->wHeap()) SystemLiteral(packingFactorLong());
#pragma warn(1506)  // warning elimination
  pfie->bindNode(bindWA);
  if (bindWA->errStatus()) return this;

  // Insert vid of bound constant into packingFactor valueIdSet.
  packingFactor().clear();
  packingFactor().insert(pfie->getValueId());

  // Create my RETDesc to hold the packed columns.
  RETDesc* resultTable = new (bindWA->wHeap()) RETDesc (bindWA);

  // Bind the tree if its present.
  if (packingExprTree_)
  {
    ItemExpr* packExprTree = removePackingExprTree();
    packExprTree->convertToValueIdList(packingExpr(), bindWA, ITM_ITEM_LIST);
    if (bindWA->errStatus()) return this;

    for (CollIndex i = 0; i < packingExpr().entries(); i++)
    {
      // Add all columns to result table.
      NAString packedColName( "PACKEDCOL_", bindWA->wHeap());
      packedColName += bindWA->fabricateUniqueName();
#pragma nowarn(1506)   // warning elimination
      Int32 length = packedColName.length();
#pragma warn(1506)  // warning elimination
      char * colName = new (bindWA->wHeap()) char[length + 1];
      colName[length] = 0;
#pragma nowarn(1506)   // warning elimination
      str_cpy_all(colName, packedColName, packedColName.length());
#pragma warn(1506)  // warning elimination

      ColRefName colRefName(colName);
      resultTable->addColumn(bindWA,
                             colRefName,
                             packingExpr().at(i),
                             USER_COLUMN,
                             colName);
    }
  }
  else // no packing expr tree, get all the columns from child.
  {
    // Get RETDesc from child which is assumed to be a RelRoot. too strict?
    const RETDesc& childTable = *child(0)->getRETDesc();
    ValueIdList childTableVidList;

    // These are only the user columns. Are SYS columns important?
    childTable.getValueIdList(childTableVidList);

    // Initialize packing expression.
    packingExpr().clear();

    // For each column in child's RETDesc, put a PackFunc() on top of it.
    for (CollIndex i = 0; i < childTableVidList.entries(); i++)
    {
      ItemExpr* childItemExpr = childTableVidList[i].getItemExpr();
      PackFunc* packedItemExpr = new (bindWA->wHeap())
                                             PackFunc(childItemExpr,pfie);
      // Bind the packed column.
      packedItemExpr->bindNode(bindWA);
      if (bindWA->errStatus()) return this;

      // Insert into both the result table and my packingExpr_.
      packingExpr().insert(packedItemExpr->getValueId());

      // $$$ Any implications of this? Needed to be seen.
      // Use the original column name as the packed column name. The index
      // is on USER columns only. SYS columns matter?
      ColRefName colRefName = childTable.getColRefNameObj(i);
      const char* heading = childTable.getHeading(i);

      // Insert into RETDesc for RelRoot above it to pick up as select-list.
      resultTable->addColumn(bindWA,
                             colRefName,
                             packedItemExpr->getValueId(),
                             USER_COLUMN,
                             heading);
      // $$$
      // OR: start with making a copy of child's RETDesc and change each col
      // to point to the vid for the packed column instead of the original.
    }
  }

  // Set the result table, bind self and return.
  setRETDesc(resultTable);
  bindWA->getCurrentScope()->setRETDesc(resultTable);
  bindSelf(bindWA);

  // To test packing. Add a unpack node on top of this pack node to check.
  char* env = getenv("PACKING_FACTOR");
  if (env && atol(env) > 0)
  {
    Lng32 pf = atol(env);

    ItemExpr* unPackExpr = NULL;
    ItemExpr* rowFilter = NULL;
    ItemExpr* unPackItem;
    ItemExpr* numRows;
    const NAType* typeInt = new(bindWA->wHeap()) SQLInt(TRUE,FALSE);

    ValueIdList packedCols;
    resultTable->getValueIdList(packedCols);

    NAString hostVarName("_sys_UnPackIndex", bindWA->wHeap());
    hostVarName += bindWA->fabricateUniqueName();
    ItemExpr* indexHostVar = new(bindWA->wHeap())
        HostVar(hostVarName,new(bindWA->wHeap()) SQLInt(TRUE,FALSE),TRUE);
    indexHostVar->synthTypeAndValueId();

    for (CollIndex i=0; i < packedCols.entries(); i++)
    {
      const NAType* colType =
            &(packedCols[i].getItemExpr()->child(0)->getValueId().getType());

      Lng32 width = colType->getNominalSize();
#pragma nowarn(1506)   // warning elimination
      Lng32 base = (colType->supportsSQLnullPhysical() ? (pf-1)/CHAR_BIT +1 : 0)
                   + sizeof(Int32);
#pragma warn(1506)  // warning elimination

      // $$$ Some duplicate code to be moved to PackColDesc later.
      ColRefName colRefName;
      colRefName = resultTable->getColRefNameObj(i);
      unPackItem = new(bindWA->wHeap())
        UnPackCol(packedCols[i].getItemExpr(),
                  indexHostVar,
                  width,
                  base,
                  colType->supportsSQLnull(),
                  colType);

      numRows = new(bindWA->wHeap())
       UnPackCol(packedCols[i].getItemExpr(),
                 new(bindWA->wHeap()) SystemLiteral(0),
                 typeInt->getNominalSize(),
                 0,
                 FALSE,
                 typeInt);

      unPackExpr = (unPackExpr ?
                    new(bindWA->wHeap()) ItemList(unPackExpr,unPackItem) :
                    unPackItem);

      rowFilter = (rowFilter ?
                   new(bindWA->wHeap()) ItemList(rowFilter,numRows) :
                   numRows);
    }

    RelExpr* unpack =
           new(bindWA->wHeap()) UnPackRows(pf,unPackExpr,rowFilter,NULL,
                                           this, indexHostVar->getValueId());
    return unpack->bindNode(bindWA);
  }

  return this;

} // Pack::bindNode()

RelExpr * Rowset::bindNode(BindWA* bindWA)
{
  // If this node has already been bound, we are done.
  if (nodeIsBound())
    return this->transformRelexpr_;

  if (bindWA->getHostArraysArea()) {
    bindWA->getHostArraysArea()->done() = TRUE;
  }

  //
  // Bind the child nodes.
  //
  bindChildren(bindWA);
  if (bindWA->errStatus()) return this;

  // Transform current node into a new subtree which performs access to
  // RowSet based on the unpacking and tuple node expression operators.
  // The formed tuple is composed of all input RowSet host variables:
  // Rowset-tuple: array_hv1, array_hv2, ... array_hvN.
  // The Unpack expression is used to retrieve the elements of the Rowset
  // with an indexed operator. For example, retrieve values for index two
  // for each Rowset host variable.
  // The transformed subtree has the following structure
  //
  //         UNPACK
  //            |
  //         TUPLE
  //
  // Note that the original Rowset relational expression has a rename node
  // on top.
  //

  // First find the maxRowSetSize and its rowsetSizeExpr. The rowset size is
  // the smallest declared dimension of the arrays composing the rowset.
  // If a constant rowset size was given in the SQL statement, it must be
  // samaller than the computed value.

  NABoolean hasDifferentSizes = FALSE;
  Lng32  maxRowsetSize  = 0; /* Maximum number of Rows in Rowset */
  ItemExpr *rowsetSizeExpr;
  ItemExpr *hostVarTree;

  // We get the list of input host vars, which is stored in the root of the
  // parse tree
  HostArraysWA *arrayArea = bindWA->getHostArraysArea();
  RelRoot *root =  bindWA->getTopRoot();

  // Do any extra checking at this moment.
  for (hostVarTree = inputHostvars_;
       hostVarTree;
       hostVarTree = hostVarTree->child(1)) {
    CMPASSERT(hostVarTree->getOperatorType() == ITM_ITEM_LIST);
    HostVar *hostVar = (HostVar *)hostVarTree->getChild(0);

    if (hostVar->getOperatorType() != ITM_HOSTVAR ||
        hostVar->getType()->getTypeQualifier() != NA_ROWSET_TYPE) {
      // 30001 A rowset must be composed of host variable arrays
      *CmpCommon::diags() << DgSqlCode(-30001);
      bindWA->setErrStatus();
      return NULL;
    }

    // Get the smallest dimension for rowset size

    SQLRowset* hostVarType  = (SQLRowset *)hostVar->getType();

    if (hostVarType->getNumElements() <= 0) {
      // 30004 The dimesion of the arrays composing the RowSet must be greater
      //       than zero. A value of $0~Int0 was given
      *CmpCommon::diags() << DgSqlCode(-30004)
                          << DgInt0((Int32)hostVarType->getNumElements());
      bindWA->setErrStatus();
      return NULL;
    }

    if (maxRowsetSize == 0)
      maxRowsetSize = hostVarType->getNumElements();
    else if (hostVarType->getNumElements() != maxRowsetSize) {
      // 30005 The dimensions of the arrays composing the RowSet are
      //       different. The smallest dimesnion is assumed.
      // This is just a warning

      // Give the warning only once
      if (hasDifferentSizes == FALSE) {
        if (arrayArea->hasDynamicRowsets()) {
           // 30015 The dimesion of the arrays composing the RowSet must be same
           // in dynamic SQL
            *CmpCommon::diags() << DgSqlCode(-30015) ;
            bindWA->setErrStatus();
            return NULL;
        } // for static SQL this is only a warning.
        hasDifferentSizes = TRUE;
        *CmpCommon::diags() << DgSqlCode(30005);
      }
      // Pick the smallest one
      if (hostVarType->getNumElements() < maxRowsetSize)
        maxRowsetSize = hostVarType->getNumElements();
    }

    // Make sure that the element type null indicator and the corresponding
    // rowset array are both nullable or not nullable. That is, force it

    NAType* hostVarElemType       = hostVarType->getElementType();
    NABoolean hostVarElemNullInd  = !(hostVar->getIndName().isNull());
    // If hostVarType is Unknown then this a dynamic param that has been
    // converted into a hostvar. For dynamic params there is no null 
    // indicator variable/param specified in the query text, so the previous
    // check will always return FALSE. We will set all dynamic params to be 
    // nullable and let type synthesis infer nullability later on.
    if (hostVarElemType->getTypeQualifier() == NA_UNKNOWN_TYPE)
      hostVarElemNullInd = TRUE;

    hostVarElemType->setNullable(hostVarElemNullInd);
  }

  // If a rowset size expression was produced during parsing, it is used
  // to restrict the rowset size during execution. The expression must be
  // an numeric literal (known at compile time) or an integer host variable
  // (known at execution time). We do not allow other type of expression
  // since the rowset size must be know before the statement is executed to
  // avoid copying a lot when the host variable arrays are sent down the
  // execution queue

  // If there is no size specification of the form ROWSET <size> ( <list> ) then
  // we take the size from ROWSET FOR INPUT SIZE <size>
  if (!sizeExpr_ && bindWA->getHostArraysArea()) {
    sizeExpr_ = bindWA->getHostArraysArea()->inputSize();
    if ((bindWA->getHostArraysArea()->getInputArrayMaxSize() > 0) &&
        (!sizeExpr_ )) {
       // ODBC process is performing a bulk insert and we need to create
       // an input parameter to simulate the functionality of ROWSET FOR INPUT
       // SIZE ... syntax.

       NAString name = "__arrayinputsize" ;
       HostVar *node = new (bindWA->wHeap())
                                    HostVar(name,
                                            new(bindWA->wHeap()) SQLInt(TRUE,FALSE),
                                            TRUE);
       node->setHVRowsetForInputSize();
       root->addAtTopOfInputVarTree(node);
       sizeExpr_ = (ItemExpr *) node ;
    }
  }

  if (sizeExpr_) {
    if (sizeExpr_->getOperatorType() == ITM_CONSTANT) {
      if (((ConstValue *)sizeExpr_)->getType()->getTypeQualifier()
          != NA_NUMERIC_TYPE) {
        // 30003 Rowset size must be an integer host variable or an
        //       integer constant
        *CmpCommon::diags() << DgSqlCode(-30003);
        bindWA->setErrStatus();
        return NULL;
      }

      if (((ConstValue *)sizeExpr_)->getExactNumericValue() <= 0) {
        // 30004 The dimesion of the arrays composing the RowSet must be
        //       greater than zero. A value of $0~Int0 was given
        *CmpCommon::diags() << DgSqlCode(-30004)
                            << DgInt0((Int32) (((ConstValue *)sizeExpr_)
                                             ->getExactNumericValue()));
        bindWA->setErrStatus();
        return NULL;
      }

      if (((ConstValue *)sizeExpr_)->getExactNumericValue() > maxRowsetSize) {
        // 30002 The given RowSet size ($0~Int0) must be smaller or
        //       equal to the smallest dimension ($1Int1) of the
        //       arrays composing the rowset
        *CmpCommon::diags() << DgSqlCode(-30002)
                            << DgInt0((Int32)
                                      ((ConstValue *)sizeExpr_)
                                      ->getExactNumericValue())
                            << DgInt1(maxRowsetSize);
        bindWA->setErrStatus();
        return NULL;
      }
      else {
        maxRowsetSize = (Lng32)((ConstValue *)sizeExpr_)->getExactNumericValue() ;
      }
    }
    else
      if (!((sizeExpr_->getOperatorType() == ITM_HOSTVAR &&
          ((HostVar *)sizeExpr_)->getType()->getTypeQualifier()
           == NA_NUMERIC_TYPE) ||
          (sizeExpr_->getOperatorType() == ITM_DYN_PARAM ) ||
          ((sizeExpr_->getOperatorType() == ITM_CAST) &&
          (sizeExpr_->child(0)->getOperatorType() == ITM_DYN_PARAM))))
    {
      // 30003 Rowset size must be an integer host variable or an
      //       integer constant
      *CmpCommon::diags() << DgSqlCode(-30014);
      bindWA->setErrStatus();
      return NULL;
    }
    
      // We return a -1 if the execution time rowset size exceeds the maximum
      // declared size
      ItemExpr *maxSize = new (bindWA->wHeap()) SystemLiteral(maxRowsetSize);
      ItemExpr *neg = new (bindWA->wHeap()) SystemLiteral(-1);
      ItemExpr *constrPred = new (bindWA->wHeap())
                               BiRelat(ITM_GREATER, sizeExpr_, maxSize);
      rowsetSizeExpr = new (bindWA->wHeap())
                         IfThenElse(constrPred, neg, sizeExpr_);

      // IfThenElse only works if Case is its parent.
      rowsetSizeExpr = new (bindWA->wHeap()) Case (NULL, rowsetSizeExpr);

      // At code generation time, it is assumed that the size expression
      // is of size integer, so we do this cast. We do not allow null
      // values.
      rowsetSizeExpr = new (bindWA->wHeap())
        Cast(rowsetSizeExpr, new (bindWA->wHeap()) SQLInt(TRUE,FALSE));

      // For dynamic rowsets, the parameter specifying rowset for input size
      // must be typed as an non-nullable integer.
      if (sizeExpr_->getOperatorType() == ITM_DYN_PARAM ) {
        sizeExpr_->synthTypeAndValueId();
        SQLInt intType(TRUE,FALSE); // TRUE -> allow neagtive values, FALSE -> not nullable
        (sizeExpr_->getValueId()).coerceType(intType, NA_NUMERIC_TYPE);
      }


  }
  else
  {
    rowsetSizeExpr = new (bindWA->wHeap()) SystemLiteral(maxRowsetSize);
  }

  // Construct an index host variable to iterate over the elements of the
  // rowset. The name of the host variable must be unique (fabricated
  // by calling fabricateUniqueName). This host variable is bound since it
  // is not an input of the parse tree. Call synthTypeAndValueId()
  // which does the minimum binding.

  NAString indexName(bindWA->wHeap());
  if (indexExpr_) {
    // Get the name.
    indexName = ((ColReference *)indexExpr_)->getColRefNameObj().getColName();
  } else {
    indexName = "_sys_rowset_index" + bindWA->fabricateUniqueName();
  }

  const NAType *indexType = new (bindWA->wHeap()) SQLInt(TRUE, FALSE);
  ItemExpr *indexHostVar = new (bindWA->wHeap())
    HostVar(indexName, indexType,
            TRUE // is system-generated
            );

  indexHostVar->synthTypeAndValueId();

  // Generate the RowsetArrayScan expressions which are used to extract
  // an element value of the rowset array given an index.

  ItemExpr *unPackExpr = NULL;

  for (hostVarTree = inputHostvars_;
       hostVarTree;
       hostVarTree = hostVarTree->child(1)) {
    HostVar *hostVar = (HostVar *)hostVarTree->getChild(0);
    SQLRowset* hostVarType        = (SQLRowset *)hostVar->getType();
    NAType* hostVarElemType       = hostVarType->getElementType();
    Lng32  hostVarElemSize         = hostVarElemType->getTotalSize();
    NABoolean hostVarElemNullInd  = !(hostVar->getIndName().isNull());

    // Force all host variable to have the same number of elements which was
    // found previously
    hostVarType->setNumElements(maxRowsetSize);

    // The element size must be align
    hostVarElemSize = ALIGN(hostVarElemSize,
                            hostVarElemType->getDataAlignment());

    // Assign a valueId for this Host variable. UnPackRows node will need
    // this valueId during its binding.
    //hostVar->synthTypeAndValueId();
    hostVar->bindNode(bindWA);

    ItemExpr *unPackCol =
      new (bindWA->wHeap())
      RowsetArrayScan(hostVar,          // Rowset Host Var array
                      indexHostVar,     // Index
                      maxRowsetSize,    // Cannot go over this size
                      hostVarElemSize,  // Element size in bytes
                      hostVarElemNullInd,
                      hostVarElemType
                      );

    // Construct a list of expressions to extract the Data value from
    // the packed row.  During normalization, this list (or a ValueIdList
    // representing this list) will be reduced to the minimum required.

    // This should be a NULL terminated list, unfortunately, there are
    // many parts in the SQL/MX code that loops over the arity instead
    // of checking for NULL terminated list...the effect a segmentation
    // violation.

    unPackExpr = (unPackExpr
                  ? new (bindWA->wHeap()) ItemList(unPackExpr, unPackCol)
                  : unPackCol);

  }

  // enable rowsetrowcount for rowset update and deletes
  // if the user has not turned the feature OFF.
  // if we have rowsets in where clause and are not in a select
  // then we have either rowset ypdate or delete, for direct rowsets.
  if (arrayArea && 
      (!(arrayArea->getHasDerivedRowsets())) &&
      arrayArea->hasHostArraysInWhereClause() && 
      (arrayArea->hasInputRowsetsInSelectPredicate() != HostArraysWA::YES_) &&
      (CmpCommon::getDefault(ROWSET_ROW_COUNT) == DF_ON)) {
    arrayArea->setRowsetRowCountArraySize(maxRowsetSize);
  }

  if (indexExpr_) {
    /*
     * Create and item expression to obtain the index
     */
    ItemExpr *unPackCol =
      new (bindWA->wHeap())
      RowsetArrayScan(indexHostVar,     // Index
                      indexHostVar,     // Index
                      maxRowsetSize,    // Cannot go over this size
                      indexType->getTotalSize(),
                      0,
                      indexType,
                      ITM_ROWSETARRAY_ROWID
                      );

    unPackExpr = (unPackExpr
                  ? new (bindWA->wHeap()) ItemList(unPackExpr, unPackCol)
                  : unPackCol);
  }

  // Now create a Tuple node to hang the children and input values of the
  // actual Rowset Node to it. Make sure to copy the RelExpr part of Rowset
  // to tuple.

  // Kludge up a dummy child for the index
  ItemExpr *inputs = ((indexExpr_)
                      ? new (bindWA->wHeap()) ItemList(inputHostvars_,
                                                       indexHostVar)
                      : inputHostvars_);

  Tuple *tupleExpr = new (bindWA->wHeap()) Tuple(inputs);
  tupleExpr->setBlockStmt(isinBlockStmt());

  copyTopNode(tupleExpr);

  // Construct the replacement tree for the Rowset operator.
  RelExpr *newSubTree = (new (bindWA->wHeap())
                         UnPackRows(maxRowsetSize,
                                    unPackExpr,
                                    rowsetSizeExpr,
                                    NULL,
                                    tupleExpr,
                                    indexHostVar->getValueId()));

  newSubTree->setBlockStmt(isinBlockStmt());

  // do not set this flag for derived rowsets. This flag is used in generator to determine
  // in onlj and TF TDB must set rownumber when encountering a execution time rowset error.
  if (arrayArea && 
      (!(arrayArea->getHasDerivedRowsets())) &&
      (arrayArea->hasInputRowsetsInSelectPredicate() != HostArraysWA::YES_)) 
  {
    newSubTree->setRowsetIterator(TRUE);
  }

  // Move any predicate on the packed table to be on the result
  // of unpacking.
  newSubTree->addSelPredTree(removeSelPredTree());

  // Remember the transform tree, just in case someone is trying to bind this
  // node again.
  transformRelexpr_  = newSubTree;

  // Bind the new generated subtree.
  return newSubTree->bindNode(bindWA);

} // Rowset::bindNode()

RelExpr * RowsetRowwise::bindNode(BindWA* bindWA)
{
  // If this node has already been bound, we are done.
  if (nodeIsBound())
    return this->transformRelexpr_;

  if (bindWA->getHostArraysArea()) {
    bindWA->getHostArraysArea()->done() = TRUE;
  }

  //
  // Bind the child nodes.
  //
  bindChildren(bindWA);
  if (bindWA->errStatus()) 
    return this;

  // Transform current node into a new subtree which performs access to
  // RowSet based on the unpacking.
  //         UNPACK
  //            |
  //         TUPLE
  //

  // We get the list of input host vars, which is stored in the root of the
  // parse tree
  HostArraysWA *arrayArea = bindWA->getHostArraysArea();
  
  if ((arrayArea->rwrsMaxSize()->getOperatorType() != ITM_CONSTANT) ||
      (((ConstValue *)arrayArea->rwrsMaxSize())->getType()->getTypeQualifier()
       != NA_NUMERIC_TYPE))
    {
      // 30003 Rowset size must be an integer host variable or an
      //       integer constant
      *CmpCommon::diags() << DgSqlCode(-30003);
      bindWA->setErrStatus();
      return NULL;
    }

  // if partition number has been specified, then we don't unpack
  // rows. The whole buffer is shipped to the specified partition.
  if (arrayArea->partnNum())
    return child(0)->castToRelExpr();

  Lng32 maxRowsetSize = 
    (Lng32)((ConstValue *)arrayArea->rwrsMaxSize())->getExactNumericValue() ;

  NAType * typ = new(bindWA->wHeap()) SQLInt(FALSE, FALSE); 
  ItemExpr * rwrsInputSizeExpr = 
    new(bindWA->wHeap()) Cast(arrayArea->inputSize(), typ);
  if (bindWA->errStatus()) 
    return this;

  ItemExpr * rwrsMaxInputRowlenExpr =
    new(bindWA->wHeap()) Cast(arrayArea->rwrsMaxInputRowlen(), typ);
  if (bindWA->errStatus()) 
    return this;

  ItemExpr * rwrsBufferAddrExpr = arrayArea->rwrsBuffer(); 
  if (bindWA->errStatus()) 
    return this;
  
  // Construct the replacement tree for the Rowset operator.
  RelExpr *newSubTree = (new (bindWA->wHeap())
                         UnPackRows(maxRowsetSize,
                                    rwrsInputSizeExpr,
                                    rwrsMaxInputRowlenExpr,
                                    rwrsBufferAddrExpr,
                                    child(0)));

  // Remember the transform tree, just in case someone is trying to bind this
  // node again.
  transformRelexpr_  = newSubTree;

  // Bind the new generated subtree.
  return newSubTree->bindNode(bindWA);
} // RowsetRowwise::bindNode()

// LCOV_EXCL_START - rfi
RelExpr * RowsetFor::bindNode(BindWA* bindWA)
{
  // Binding of this node should not happen. It should have been eliminated
  // by now by the pre-binding step. Its content is used to populate the
  // RowSet node with options.

  CMPASSERT(0);
  return NULL;
}
// LCOV_EXCL_STOP

RelExpr * RowsetInto::bindNode(BindWA* bindWA)
{
  // If this node has already been bound, we are done.
  if (nodeIsBound())
    return this->transformRelexpr_;

  //
  // Bind the child nodes.
  //
  bindChildren(bindWA);
  if (bindWA->errStatus()) return this;

  NABoolean hasDifferentSizes = FALSE;
  Lng32  maxRowsetSize  = 0; /* Maximum number of Rows in Rowset */
  ULng32 numOutputHostvars = 0;

  ItemExpr *rowsetSizeExpr;
  ItemExpr *hostVarTree;

  // Do any extra checking at this moment.
  for (hostVarTree = outputHostvars_;
       hostVarTree;
       hostVarTree = hostVarTree->child(1)) {
    numOutputHostvars++;
    CMPASSERT(hostVarTree->getOperatorType() == ITM_ITEM_LIST);
    HostVar *hostVar = (HostVar *)hostVarTree->getChild(0);

    if (hostVar->getOperatorType() != ITM_HOSTVAR ||
        hostVar->getType()->getTypeQualifier() != NA_ROWSET_TYPE) {
      // 30001 A rowset must be composed of host variable arrays
      *CmpCommon::diags() << DgSqlCode(-30001);
      bindWA->setErrStatus();
      return NULL;
    }

    // Get the smallest dimension for rowset size


    SQLRowset* hostVarType  = (SQLRowset *)hostVar->getType();

    if (hostVarType->getNumElements() <= 0) {
      // 30004 The dimesion of the arrays composing the RowSet must be greater
      //       than zero. A value of $0~Int0 was given
      *CmpCommon::diags() << DgSqlCode(-30004)
                          << DgInt0((Int32)hostVarType->getNumElements());
      bindWA->setErrStatus();
      return NULL;
    }

    if (maxRowsetSize == 0)
      maxRowsetSize = hostVarType->getNumElements();
    else if (hostVarType->getNumElements() != maxRowsetSize) {
      // 30005 Warning: the dimensions of the arrays composing the RowSet are
      //       different. The smallest dimesnion is assumed.
      // This is just a warning

      // Give the warning only once
      if (hasDifferentSizes == FALSE) {
        hasDifferentSizes = TRUE;
        *CmpCommon::diags() << DgSqlCode(30005);
      }
      // Pick the smallest one
      if (hostVarType->getNumElements() < maxRowsetSize)
        maxRowsetSize = hostVarType->getNumElements();
    }

    // Make sure that the element type null indicator and the corresponding
    // rowset array are both nullable or not nullable. That is, force it

    NAType* hostVarElemType       = hostVarType->getElementType();
    NABoolean hostVarElemNullInd  = !(hostVar->getIndName().isNull());

    hostVarElemType->setNullable(hostVarElemNullInd);
  }

  // If a rowset size expression was produced during parsing, it is used
  // to restrict the rowset size during execution. The expression must be
  // an numeric literal (known at compile time) or an integer host variable
  // (known at execution time). We do not allow other type of expression
  // since the rowset size must be know before the statement is executed to
  // avoid copying a lot when the host variable arrays are sent down the
  // execution queue

  if (sizeExpr_) {
    if (sizeExpr_->getOperatorType() == ITM_CONSTANT) {
      if (((ConstValue *)sizeExpr_)->getType()->getTypeQualifier()
          != NA_NUMERIC_TYPE) {
        // 30003 Rowset size must be an integer host variable or an
        //       integer constant
        *CmpCommon::diags() << DgSqlCode(-30003);
        bindWA->setErrStatus();
        return NULL;
      }

      if (((ConstValue *)sizeExpr_)->getExactNumericValue() > maxRowsetSize) {
        // 30002 The given RowSet size ($0~Int0) must be smaller or
        //       equal to the smallest dimension ($1Int1) of the
        //       arrays composing the rowset
        *CmpCommon::diags() << DgSqlCode(-30002)
                            << DgInt0((Int32)
                                      ((ConstValue *)sizeExpr_)
                                      ->getExactNumericValue())
                            << DgInt1(maxRowsetSize);
        bindWA->setErrStatus();
        return NULL;
      }
    }
    else
      if (!(sizeExpr_->getOperatorType() == ITM_HOSTVAR &&
            ((HostVar *)sizeExpr_)->getType()->getFSDatatype()
            == REC_BIN32_SIGNED)) {
        // 30003 Rowset size must be an integer host variable or an
        //       integer constant
        *CmpCommon::diags() << DgSqlCode(-30003);
        bindWA->setErrStatus();
        return NULL;
      }
    rowsetSizeExpr = sizeExpr_;
  }
  else
    rowsetSizeExpr = new (bindWA->wHeap()) SystemLiteral(maxRowsetSize);


  if (getGroupAttr()->isEmbeddedUpdateOrDelete()){
    // 30020 Embedded update/delete cannot be used with SELECT...INTO and rowset.
    *CmpCommon::diags() << DgSqlCode(-30020);
    bindWA->setErrStatus();
    return NULL;
  }

  // Generate the RowsetArrayInto expressions which are used to append
  // an element value to the rowset array.

  // Get RETDesc from its only child one which must be RelRoot type.
  const RETDesc& childTable = *child(0)->getRETDesc();
  ValueIdList childTableVidList;

  childTable.getValueIdList(childTableVidList);

  if (numOutputHostvars != childTableVidList.entries()) {
    // 4094 The number of output host vars  ($0) must equal the number of cols
    *CmpCommon::diags() << DgSqlCode(-4094)
#pragma nowarn(1506)   // warning elimination
      << DgInt0(numOutputHostvars) << DgInt1(childTableVidList.entries());
#pragma warn(1506)  // warning elimination
    bindWA->setErrStatus();
    return NULL;
  }

  ItemExpr *packExpr = NULL;
  Lng32 i;

  for (hostVarTree = outputHostvars_, i = 0;
       hostVarTree;
       hostVarTree = hostVarTree->child(1), i++) {
    HostVar *hostVar = (HostVar *)hostVarTree->getChild(0);


    SQLRowset* hostVarType        = (SQLRowset *)hostVar->getType();
    NAType* hostVarElemType       = hostVarType->getElementType();
    // hostVarElemType->setNullable(TRUE);
    Lng32  hostVarElemSize         = hostVarElemType->getTotalSize();
    NABoolean hostVarElemNullInd  = !(hostVar->getIndName().isNull());
    ItemExpr* sourceExpr          = childTableVidList[i].getItemExpr();

    ValueId sourceId = childTableVidList[i];
    const NAType& targetType = *hostVarElemType;
    sourceId.coerceType(targetType);
    const NAType& sourceType = sourceId.getType();

    NABoolean relaxCharTypeMatchingRule = FALSE;

    // We make sure that the types that are coming from below this
    // node match properly with the types it has
    if (NOT targetType.isCompatible(sourceType)) {
      // JQ
      // Relaxing Characet Data Type mismatching rule.
      if ( targetType.getTypeQualifier() == NA_CHARACTER_TYPE &&
           sourceType.getTypeQualifier() == NA_CHARACTER_TYPE &&
           ((const CharType&)targetType).getCharSet() == CharInfo::UNICODE &&
           ((const CharType&)sourceType).getCharSet() == CharInfo::ISO88591
         )
      {
        relaxCharTypeMatchingRule = TRUE;
      }

      if ( !relaxCharTypeMatchingRule ) {
        // Incompatible assignment from type $0~String0 to type $1~String1
        *CmpCommon::diags() << DgSqlCode(-30007)
                            << DgString0(sourceType.getTypeSQLname(TRUE /*terse*/))
                            << DgString1(targetType.getTypeSQLname(TRUE /*terse*/));
        bindWA->setErrStatus();
        return FALSE;
      }
    }

    // Force all host variable to have the same number of elements which was
    // found previously
    hostVarType->setNumElements(maxRowsetSize);

    // The element size must be align
    hostVarElemSize = ALIGN(hostVarElemSize,
                            hostVarElemType->getDataAlignment());

    // Preserve the length that is coming from the node below this one
    if (hostVarElemType->getTypeQualifier() == NA_CHARACTER_TYPE &&
        sourceType.getTypeQualifier() == NA_CHARACTER_TYPE) {
      Int32 sourceSize = ((CharType *) &sourceType)->getDataStorageSize();
      Int32 targetSize = ((CharType *) hostVarElemType)->getDataStorageSize();
      if (sourceSize > targetSize ) {
     // Adjust the layout size instead of changing the element size?
        ((CharType *) hostVarElemType)->setDataStorageSize(sourceSize);
      }
    }

    if ( relaxCharTypeMatchingRule == TRUE )
      sourceExpr = new (bindWA->wHeap())
           Translate(sourceExpr, Translate::ISO88591_TO_UNICODE);

    // If the type is external (for instance, decimal or varchar), we must first
    // convert to our internal equivalent type
    if (hostVarElemType->isExternalType()) {
      NAType *internalType = hostVarElemType->equivalentType();
      sourceExpr = new (bindWA->wHeap()) Cast(sourceExpr, internalType);
    }

    sourceExpr = new (bindWA->wHeap()) Cast(sourceExpr, hostVarElemType);

    ItemExpr *packCol =
      new (bindWA->wHeap())
      RowsetArrayInto(sourceExpr,
                      rowsetSizeExpr,    // Runtime size
                      maxRowsetSize,     // Cannot go over this size
                      hostVarElemSize,   // Element size in bytes
                      hostVarElemNullInd,
                      hostVarType
                      );

    // Construct a list of expressions to append the Data value to the
    // RowSet array. This list should be a NULL terminated list,
    // unfortunately, there are many parts in the SQL/MX code that
    // loops over the arity instead of checking for NULL terminated
    // list...the effect a segmentation violation.

    packExpr = (packExpr
                ? new (bindWA->wHeap()) ItemList(packExpr, packCol)
                : packCol);
  }

  // Construct the replacement tree for the RowsetInto operator.
  RelExpr *newSubTree = (new (bindWA->wHeap())
                         Pack(maxRowsetSize,
                              child(0)->castToRelExpr(),
                              packExpr));

  newSubTree->setFirstNRows(getFirstNRows());

  // If we have an ORDER BY when there is an INTO :array, then we
  // add the requirement that the tuples that this Pack node will
  // receive must be sorted

  ValueIdList *ptrReqOrder;

  ptrReqOrder = new (bindWA->wHeap())
      ValueIdList(((RelRoot *) (RelExpr *) newSubTree->child(0))->reqdOrder());

  ((Pack *) newSubTree)->setRequiredOrder(*ptrReqOrder);


  // Remember the transform tree, just in case someone is trying to bind this
  // node again.
  transformRelexpr_  = newSubTree;

  // Bind the new generated subtree.
  return newSubTree->bindNode(bindWA);

} // RowsetInto::bindNode

RelExpr *
IsolatedScalarUDF::bindNode (BindWA *bindWA)
{

  if (nodeIsBound())
  {
    bindWA->getCurrentScope()->setRETDesc(getRETDesc());
    return this;
  }

     // If we have a RoutineDesc, it means we got transformed from a 
     // a UDFunction ItemExpr, and do NOT need to check all the metadata
     // params etc. 
  if (getRoutineDesc() == NULL ) 
  {
        // If we get here, we created a IsolatedScalarUDF some other way
        // than through the transformation of UDFunction. Either that or
        // we have someone walking over our memory...

     CMPASSERT(0);
     bindWA->setErrStatus();
     return this;
                                                 

  }
  else
  {
     markAsBound();
  }


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

/*
 * This method performs binder functions for the CALLSP node
 * It performs semantic checks on the called stored procedure
 * creates a Tuple child and allocates ValueIds for the parameters
 * It also provides support for the CLI layer processing for OUT
 * parameter processing.
 */
RelExpr *CallSP::bindNode(BindWA *bindWA)
{
  if (nodeIsBound())
  {
    bindWA->getCurrentScope()->setRETDesc(getRETDesc());
    return this;
  }

  if (bindWA->getHoldableType() == SQLCLIDEV_ANSI_HOLDABLE)
  {
    *CmpCommon::diags() << DgSqlCode(-4382);
    bindWA->setErrStatus();
    bindWA->setBindingCall (FALSE);
    return this;
  }

  bindWA->setBindingCall (TRUE);
  bindWA->setCurrOrdinalPosition (1);
  bindWA->setCurrParamMode (COM_UNKNOWN_DIRECTION);
  bindWA->clearHVorDPinSPDups ();
  bindWA->setDupWarning (FALSE);
  bindWA->setMaxResultSets(0);

  // try PUBLIC SCHEMA only when no schema was specified
  // and CQD PUBLIC_DEFAULT_SCHEMA is specified
  NAString pSchema = 
    ActiveSchemaDB()->getDefaults().getValue(PUBLIC_SCHEMA_NAME);
  ComSchemaName pubSchema(pSchema);
  NAString pubSchemaIntName = "";
  if ( (getRoutineName().getSchemaName().isNull()) && 
       (!pubSchema.getSchemaNamePart().isEmpty()) )
  {
    pubSchemaIntName = pubSchema.getSchemaNamePart().getInternalName();
  }

  // Invoke GetNARoutine () to retrieve the corresponding NARoutine from
  // NARoutineDB_
  QualifiedName name = getRoutineName();
  const SchemaName &defaultSchema =
    bindWA->getSchemaDB ()->getDefaultSchema();
  name.applyDefaults(defaultSchema);
  setRoutineName(name);
  bindWA->setCurrSPName(&name);

    // in open source, only the SEABASE catalog is allowed.
    // Return an error if some other catalog is being used.
  if ((NOT name.isSeabase()) && (NOT name.isHive()))
      {
	*CmpCommon::diags()
	  << DgSqlCode(-1002)
	  << DgCatalogName(name.getCatalogName());
	
	bindWA->setErrStatus();
	return NULL;
      }


  CmpSeabaseDDL cmpSBD((NAHeap*)bindWA->wHeap());
  TrafDesc *catRoutine = 
	    cmpSBD.getSeabaseRoutineDesc(
				       name.getCatalogName(),
				       name.getSchemaName(),
				       name.getObjectName());

  // try public schema
  if ( !catRoutine && 
       !pubSchemaIntName.isNull() )
  {
    getRoutineName().setSchemaName(pubSchemaIntName);
    if ( !pubSchema.getCatalogNamePart().isEmpty() )
    {
      getRoutineName().setCatalogName(pubSchema.getCatalogNamePart().getInternalName());
    }

    // in open source, only the SEABASE catalog is allowed.
    // Return an error if some other catalog is being used.
    if ((NOT getRoutineName().isSeabase()) && (NOT getRoutineName().isHive()))
      {
	*CmpCommon::diags()
	  << DgSqlCode(-1002)
	  << DgCatalogName(getRoutineName().getCatalogName());
	
	bindWA->setErrStatus();
	return NULL;
      }

    bindWA->resetErrStatus();
    catRoutine = 
	    cmpSBD.getSeabaseRoutineDesc(
                 getRoutineName().getCatalogName(),
                 getRoutineName().getSchemaName(),
                 getRoutineName().getObjectName());
    if ( !bindWA->errStatus() && catRoutine )
    { // if found in public schema, do not show previous error
      CmpCommon::diags()->clear();
    }
  }

  if (bindWA->violateAccessDefaultSchemaOnly(getRoutineName()))
    return NULL;

  if ( NULL == catRoutine )
  {
    // Diagnostic error is set by the readRoutineDef, we just need to
    // make sure the rest of the compiler knows that an error occurred.
    bindWA->setBindingCall (FALSE);
    bindWA->setErrStatus ();
    return this;
  }

  // Create a new NARoutine object
  Int32 error = FALSE;
  NARoutine *routine = new (bindWA->wHeap()) NARoutine ( getRoutineName(),
                                                         catRoutine,
                                                         bindWA,
                                                         error );

  if ( bindWA->errStatus () )
  {
    // Error
    bindWA->setBindingCall (FALSE);
    bindWA->setErrStatus ();
    return this;
  }

  NABoolean createRETDesc=TRUE;
  RoutineDesc *rDesc = new (bindWA->wHeap()) RoutineDesc(bindWA, routine); 
  if (rDesc == NULL ||  bindWA->errStatus ())
  {
    // Error
    bindWA->setBindingCall (FALSE);
    bindWA->setErrStatus ();
    return this;
  }
 
  if (rDesc->populateRoutineDesc(bindWA, createRETDesc) == FALSE ) 
  {
    bindWA->setBindingCall (FALSE);
    bindWA->setErrStatus ();
    return this;
  }

  setRoutineDesc(rDesc);


  //
  // Semantic checks
  //

  // if in trigger and during DDL make sure to Fix up the name 
  // location list so that the name is fully qualified when stored 
  // in the TEXT metadata table
  if ( bindWA->inDDL() && bindWA->isInTrigger () )
  {
     ParNameLocList *pNameLocList = bindWA->getNameLocListPtr();
     if (pNameLocList)
     {
       ParNameLoc * pNameLoc
         = pNameLocList->getNameLocPtr(getRoutineName().getNamePosition());
       CMPASSERT(pNameLoc);
       pNameLoc->setExpandedName(getRoutineName().getQualifiedNameAsAnsiString());
     }
  }

  // Cannot support result sets or out params when
  // SP is invoked within a trigger
  if ( bindWA->isInTrigger () &&
       getNARoutine()->hasOutParams ())
  {
    *CmpCommon::diags() <<  DgSqlCode(-UDR_BINDER_OUTPARAM_IN_TRIGGER)
                          << DgTableName (getRoutineName().getQualifiedNameAsString());
    bindWA->setErrStatus ();
    bindWA->setBindingCall (FALSE);
    return this;
  }

  if ( bindWA->isInTrigger () &&
       getNARoutine()->hasResultSets ())
  {
    *CmpCommon::diags() <<  DgSqlCode(-UDR_BINDER_RESULTSETS_IN_TRIGGER)
                          << DgTableName (getRoutineName().getQualifiedNameAsString());
    bindWA->setErrStatus ();
    bindWA->setBindingCall (FALSE);
    return this;
  }

  const NAColumnArray &params = getNARoutine()->getParams ();
  CollIndex i = 0;
  CollIndex numParams = getNARoutine()->getParamCount ();

  CollIndex numSuppliedParams = countSuppliedParams (getRWProcAllParamsTree());
  if (numSuppliedParams != numParams)
  {
    *CmpCommon::diags() << DgSqlCode(-UDR_BINDER_INCORRECT_PARAM_COUNT)
                        << DgTableName(getRoutineName().getQualifiedNameAsString())
                        << DgInt0((Lng32) numParams)
                        << DgInt1((Lng32) numSuppliedParams);
    bindWA->setErrStatus ();
    bindWA->setBindingCall (FALSE);
    return this;
  }

  short numResultSets = (short) getNARoutine()->getMaxResults();
  bindWA->setMaxResultSets(numResultSets);

  // On to the binding
  // Invoke populateAndBindItemExpr, set up needed data structures

  // Set up a RETDesc if we don't already have one.
  RETDesc *resultTable = getRETDesc();
  if (resultTable == NULL) 
  {
       resultTable = new (bindWA->wHeap()) RETDesc(bindWA);
       setRETDesc(resultTable);
  }

  populateAndBindItemExpr ( getRWProcAllParamsTree(),
                            bindWA );
  if ( bindWA->errStatus ())
  {
    bindWA->setBindingCall (FALSE);
    return this;
  }

  // Clear the Tree since we now have gotten vids for all the parameters.
  setProcAllParamsTree(NULL);

  // Now fix the param index value of the dynamic params or host vars
  LIST (ItemExpr *) &bWA_HVorDPs = bindWA->getSpHVDPs();
  CollIndex numHVorDPs = bWA_HVorDPs.entries();

  ARRAY(ItemExpr *) local_HVorDPs(HEAP, numHVorDPs);
  CollIndex idx, idx1, idx2;

  // Sort the ItemExpr in the order they appeared in the stmt
  for (idx = 0; idx < numHVorDPs; idx++)
  {
    // Copy ItemExpr ptrs to a sorted Array.
    local_HVorDPs.insertAt(bWA_HVorDPs[idx]->getHVorDPIndex() - 1,
                           bWA_HVorDPs[idx]);
  }

  // The following code goes through the list of Exprs and
  // sets index values. The rules are:
  // 1. When a DP or HV is repeated, all of them get the same
  // index value which is equal to the index of the first occurrence
  // 2. Two DPs or HVs are same if their names and the modes are same.
  Int32 currParamIndex = 1;
  for (idx1 = 0; idx1 < numHVorDPs; idx1++)
  {
    ItemExpr *src = local_HVorDPs[idx1];
    const NAString &name1 = (src->getOperatorType() == ITM_HOSTVAR) ?
      ((HostVar *)src)->getName() : ((DynamicParam *)src)->getName();
    ComColumnDirection mode1 = src->getParamMode();

    NABoolean encounteredElement = FALSE;

    for (idx2 = idx1; idx2 < numHVorDPs; idx2++)
    {
      ItemExpr *dest = local_HVorDPs[idx2];

      if (!encounteredElement && dest->getHVorDPIndex() >= currParamIndex)
      {
        // The parameter is encountered the first time
        encounteredElement = TRUE;
        dest->setPMOrdPosAndIndex(dest->getParamMode(),
                                  dest->getOrdinalPosition(),
                                  currParamIndex);
        continue;
      }

      // The parameter is already corrected
      if (dest->getHVorDPIndex() < currParamIndex)
        continue;

      const NAString &name2 = (dest->getOperatorType() == ITM_HOSTVAR) ?
        ((HostVar *)dest)->getName() : ((DynamicParam *)dest)->getName();
      ComColumnDirection mode2 = dest->getParamMode();

      if (name2.compareTo("") == 0)
        continue;

      if (name1.compareTo(name2) == 0 && mode1 == mode2)
      {
        dest->setPMOrdPosAndIndex(dest->getParamMode(),
                                  dest->getOrdinalPosition(),
                                  currParamIndex);
      }
    }

    if (encounteredElement)
      currParamIndex++;
  }

  // Restore the bindWA's HVorDP list since it might be needed
  // while binding the root node in case of HVs.
  bindWA->clearHVorDPinSPDups();
  for (idx = 0; idx < numHVorDPs; idx++)
    bindWA->addHVorDPToSPDups(local_HVorDPs[idx]);

  // Create a tuple child for any subqueries or UDF inputs
  // The hasSubquery() / hasUDF() flag gets set in setInOrOutParam if any of our
  // passed in parameters is a subquery.

  
  if ((getProcInputParamsVids().entries() != 0)  && 
      (hasSubquery() || hasUDF())) 
  {
     Tuple *inTuple = new (bindWA->wHeap()) 
                Tuple(getProcInputParamsVids().rebuildExprTree(ITM_ITEM_LIST), 
                      bindWA->wHeap());
   
     if ( inTuple )
     {
       // Now set and bind the Tuple child
       setChild (0, inTuple);
   
       // Bind this Tuple child
       inTuple->bindNode (bindWA);
       if ( bindWA->errStatus ())
       {
         bindWA->setBindingCall (FALSE);
         return this;
       }
   
       // Get each IN entry from the Tuple and put it in
       //the super's list

       // Need to clear the list to avoid duplicates
       getProcInputParamsVids().clear();

       // Now reinitialize the inputs based on the Tuple processing.
       inTuple->getRETDesc ()->getValueIdList (getProcInputParamsVids());
   
     } // if inTuple
     else
     {
         // Out of memory ...
         bindWA->setBindingCall (FALSE);
         bindWA->setErrStatus();
         return this;
     }
  } // if getProcInputParamVids().entries()
  else
  {

    // If we dont have a subquery parameter, we dont need to go thru
    // Optimization time rules and transformations, hence mark this
    // as a physical node.

    isPhysical_ = TRUE;
  }


  //
  // Not sure whether we need to set the currently scoped RETDesc
  // before binding the base class. Tuple::bindNode() does not do it
  // so we won't either (for now)
  //
  //bindWA->getCurrentScope()->setRETDesc(getRETDesc());

  // add the routine to the UdrStoiList.  The UdrStoi list is used
  // to check valid privileges
  LIST(OptUdrOpenInfo *) udrList = bindWA->getUdrStoiList ();
  ULng32 numUdrs = udrList.entries();
  NABoolean udrReferenced = FALSE;

  // See if UDR already exists
  for (ULng32 stoiIndex = 0; stoiIndex < numUdrs; stoiIndex++)
  {
    if ( 0 ==
         udrList[stoiIndex]->getUdrName().compareTo(
                           getRoutineName().getQualifiedNameAsAnsiString()
                                                  )
       )
    {
      udrReferenced = TRUE;
      break;
    }
  }

  // UDR has not been defined, go ahead an add one
  if ( FALSE == udrReferenced )
  {
    SqlTableOpenInfo *udrStoi = new (bindWA->wHeap ())SqlTableOpenInfo ();
    udrStoi->setAnsiName ( convertNAString(
                           getRoutineName().getQualifiedNameAsAnsiString(),
                           bindWA->wHeap ())
                         );

    OptUdrOpenInfo *udrOpenInfo = new (bindWA->wHeap ())
      OptUdrOpenInfo( udrStoi
                    , getRoutineName().getQualifiedNameAsAnsiString()
                    , (NARoutine *)getNARoutine()
                    );
    bindWA->getUdrStoiList().insert(udrOpenInfo);
  }


  //
  // Bind the base class
  //
  RelExpr *boundExpr = bindSelf(bindWA);
  if (bindWA->errStatus())
  {
    bindWA->setBindingCall (FALSE);
    return boundExpr;
  }

  // Our characteristic inputs get set for us, we don't need to do it
  // ourselves, however, we need to set our characteristic outputs
  getGroupAttr()->addCharacteristicOutputs(getProcOutputParamsVids());

  if (getNARoutine()->isProcedure())
    bindWA->setHasCallStmts(TRUE);

  bindWA->setBindingCall (FALSE);
  return boundExpr;
} // CallSP::bindNode()



// This is the main entry point to walking the ItemExpr tree built by the
// parser, separating the IN and OUT parameters, setting appropriate
// characteristics of the IN/OUT parameters and binding them
// Currently only CallSP uses this code. If this routine needs to be shared
void IsolatedNonTableUDR::populateAndBindItemExpr ( ItemExpr *param,
                                       BindWA *bindWA )
{
  // This method is called recursively
  CollIndex numParams = getEffectiveNARoutine()->getParamCount ();
  CollIndex ordinalPosition = bindWA->getCurrOrdinalPosition ();

  // No parameters, or we are done with the leaf node
  if ( NULL == param )
  {
    return;
  }

  ComColumnDirection mode =
     getEffectiveNARoutine()->getParams()[ordinalPosition-1]->getColumnMode ();

  // This is the structure of the ItemExpr tree
  // For 1 param
  //    ItemExpr
  //
  //  2 params
  //    ItemList
  //     /    \
  //  Param1  Param2
  //
  // > 2 params
  //              ItemList
  //             /        \
  //        Param1         ItemList
  //                    /       \
  //                 Param2    ItemList
  //                        ...        ...
  //                     ...             ...
  //                      /              /   \
  //                    Param (N-2)    /      \
  //                                 /         \
  //                              Param(N-1)   Param(N)
  if ( ITM_ITEM_LIST == param->getOperatorType ())
  {
    // Use left child
    CMPASSERT ((ItemExpr *) NULL != (*param).child (0));

    populateAndBindItemExpr ( (*param).child(0),
                              bindWA );

    if ( bindWA->errStatus ())
      return;

    // Now for the right child
    CMPASSERT ((ItemExpr *) NULL != (*param).child (1));
    populateAndBindItemExpr ( (*param).child(1),
                              bindWA );

    return;

  } // if ITM_ITEM_LIST == param->getOperatorType ()

  // For all leaf nodes we must come here (see the recursive call to
  // populateAndBindItemExp above)
  // Set the bindWA's current ordinal position and parameter mode
  // Let HV and DynamicParam's bindNode take care of the
  // settings. To ensure this, do a bindNode here
  bindWA->setCurrParamMode (mode);
  param->bindNode (bindWA);
  if (bindWA->errStatus ())
    return;

  // Add the IN or OUT params to their respective lists
  // and also create and bind a new ItemExpr for INOUT and OUT
  // params.
  // Also bump up the ordinalPosition count since we are done with this
  // parameter.
  setInOrOutParam (param,/* ordinalPosition,*/ mode, bindWA);
  if ( bindWA->errStatus ())
    return;

  bindWA->setCurrOrdinalPosition (bindWA->getCurrOrdinalPosition () + 1);

} // PopulateAndBindItemExpr



// LCOV_EXCL_START - rfi
void
IsolatedNonTableUDR::setInOrOutParam (ItemExpr *expr,
                              ComColumnDirection paramMode,
                              BindWA *bindWA)
{
    // Should not get here..
   CMPASSERT(FALSE);
}
// LCOV_EXCL_STOP


// This method separates the IN and OUT parameters Each IN/INOUT param
// is cast to the formal type (from NARoutine). This Cast'ed item expr
// is added to an ItemList tree to be passed to the Tuple ()
// constructor.  For each OUT/INOUT, we create a NATypeToItem
// ItemExpr, bind it and add it to procOutParams_.
//
// This method is called once for each CALL statement argument. If an
// input argument to a CALL is an expression tree such as "? + ?" or
// "abs(:x)" then this method is called once for the entire tree.
//
// Side Effects: OUT: hasSubquery_
//                    neededValueIds_
//                    procAllParamsVids_
//                    procInputParamsVids_
//                    procOutputParamsVids_
void CallSP::setInOrOutParam ( ItemExpr *expr,
                               ComColumnDirection paramMode,
                               BindWA *bindWA)
{

  // Depending on whether this is an IN or OUT parameter, we need to
  // take different actions.

  // For an IN (and INOUT) param, do the following
  // Cast the parameter to its formal type and add it to the list of
  // IN params. This will be used later to create a Tuple child and
  // be bound by the Tuple itself
  CollIndex ordinalPosition = bindWA->getCurrOrdinalPosition ();

  const NAColumnArray &formalParams = getNARoutine()->getParams();
  NAColumn &naColumn = *(formalParams[ordinalPosition-1]);
  const NAType &paramType = *(naColumn.getType());

  // Don't really want to bind this, but how else can we
  // get the ItemExpr's type
  ItemExpr *boundExpr = expr->bindNode (bindWA);
  if ( bindWA->errStatus ())
  {
    return;
  }



  //10-061031-0188-Begin
  //Need to infer charset for string literals part of CALLSP
  //parameters
  ValueId inputTypeId = boundExpr->getValueId();

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

  NABoolean throwInTranslateNode = FALSE;
  CharInfo::CharSet paramCS = CharInfo::UnknownCharSet;
  CharInfo::CharSet inputCS = CharInfo::UnknownCharSet;

 const NABoolean isJdbc =
    (CmpCommon::getDefault(JDBC_PROCESS) == DF_ON ? TRUE : FALSE);
 const NABoolean isOdbc =
    (CmpCommon::getDefault(ODBC_PROCESS) == DF_ON ? TRUE : FALSE);

 const NAType &inputType = inputTypeId.getType();
  //10-061031-0188-End

  if ( COM_INPUT_COLUMN == paramMode ||
       COM_INOUT_COLUMN == paramMode )
  {
    // If this input argument to the CALL is a single dynamic param
    // then we want to record the formal parameter name. It will later
    // be written into the query plan by the code generator and
    // eventually if this CALL statement is DESCRIBEd, the formal
    // param name gets returned in the SQLDESC_NAME descriptor entry.
    if (expr->getOperatorType() == ITM_DYN_PARAM)
    {
      DynamicParam *dp = (DynamicParam *) expr;
      dp->setUdrFormalParamName(naColumn.getColName());
    }

    // Check to see if we have a Subquery as an input
    if ( !hasSubquery() )
      hasSubquery() = expr->containsSubquery ();


    // Check to see if we have a UDF as an input
    if ( !hasUDF() )
      hasUDF() = (expr->containsUDF () != NULL);

    // Do type checking,
    // If it is not a compatible type report an error
    if (!( NA_UNKNOWN_TYPE == inputType.getTypeQualifier () ||
           paramType.isCompatible(inputType) ||
           expr->getOperatorType () == ITM_DYN_PARAM
         )
       )
    {
      if ( inputType.getTypeQualifier() == NA_CHARACTER_TYPE )
      {
         paramCS = ((CharType&)paramType).getCharSet();
         inputCS = ((CharType&)inputType).getCharSet();

         NABoolean CS_unknown = (paramCS == CharInfo::UnknownCharSet) ||
                                (inputCS == CharInfo::UnknownCharSet) ;
         if ( paramType.NAType::isCompatible(inputType) &&
              paramCS != inputCS                        &&
              CS_unknown == FALSE                       &&
              CmpCommon::getDefault(ALLOW_IMPLICIT_CHAR_CASTING) == DF_ON
            )
               throwInTranslateNode = TRUE;
      }
      if ( throwInTranslateNode == FALSE )
      {
        // Error, data types dont match
#pragma nowarn(1506)   // warning elimination
        *CmpCommon::diags() <<  DgSqlCode(-UDR_BINDER_PARAM_TYPE_MISMATCH)
                            << DgInt0 (ordinalPosition)
                            << DgTableName(getRoutineName().getQualifiedNameAsString())
                            << DgString0 (inputType.getTypeSQLname (TRUE))
                            << DgString1 (paramType.getTypeSQLname (TRUE));
#pragma warn(1506)  // warning elimination
        bindWA->setErrStatus ();
        return;
      }
    } // if NOT isCompatible

    // Create a Cast node if the types are not identical
    if (! (inputType == paramType))
    {
       // First create a Translate node if the character sets are not identical

       if ( throwInTranslateNode )
       {
            Int32 tran_type = find_translate_type( inputCS, paramCS );

            ItemExpr * newTranslateChild =
                new (bindWA->wHeap()) Translate(boundExpr, tran_type );
            boundExpr = newTranslateChild->bindNode(bindWA);
            if (bindWA->errStatus())
               return;
            // NOTE: Leave "expr" at it's old value as code below needs to check
            //       that original ItemExpr rather than the new Translate node.
       }
       Cast *retExpr = new (bindWA->wHeap())
                          Cast(boundExpr, &paramType, ITM_CAST, TRUE);

       boundExpr = retExpr->bindNode (bindWA);
       if ( bindWA->errStatus ())
       {
          return;
       }
    }
    // Fill the ValueIdList for all the params
    getProcAllParamsVids().insert( boundExpr->getValueId());

    // Fill the ValueIdList for Input params
    getProcInputParamsVids().insert( boundExpr->getValueId());

  } // if INPUT or INOUT

  // For OUT (and INOUT) parameters, we create a NATypeToItem object,
  // bind it and add it to the list of OUT parameters (procOutParams_)
  if ( COM_OUTPUT_COLUMN == paramMode ||
       COM_INOUT_COLUMN == paramMode )
  {
    if (!( ITM_HOSTVAR == expr->getOperatorType () ||
           ITM_DYN_PARAM == expr->getOperatorType ()))
    {
#pragma nowarn(1506)   // warning elimination
      *CmpCommon::diags() << DgSqlCode(-UDR_BINDER_OUTVAR_NOT_HV_OR_DP)
                          << DgInt0(ordinalPosition)
                          << DgTableName(getRoutineName().getQualifiedNameAsString());
#pragma warn(1506)  // warning elimination
      bindWA->setErrStatus ();
      return;
    } // if NOT HOSTVAR or DYNAMIC PARAM

    NATypeToItem *paramTypeItem = new (bindWA->wHeap())
                                      NATypeToItem (naColumn.mutateType());
    ItemExpr *outputExprToBind = NULL;
    outputExprToBind = paramTypeItem->bindNode (bindWA);
    if ( bindWA->errStatus ())
    {
      return;
    }



    // Fill the ValueIdList for all the params
    getProcAllParamsVids().insert( outputExprToBind->getValueId());

    // Fill the ValueIdList for the output params
    addProcOutputParamsVid(outputExprToBind->getValueId ());

    //
    // Populate our RETDesc
    //
    // It has already been alocated
    RETDesc *resultTable = getRETDesc();

    const NAString &formalParamName = naColumn.getColName();
    const NAString *colParamName = &formalParamName;

    // Set the userParamName
    const NAString &userParamName =
            // cannot use the boundExpr here as it will be a cast()
            // for the HostVar or DynamicParam. Use the original
            // ItemExpr pointer instead.
        (ITM_HOSTVAR == expr->getOperatorType()) ?
        ((HostVar *)expr)->getName() :
        ((DynamicParam *)expr)->getName();


    // Typically the name for this output column will be the formal
    // parameter name. Exceptions:
    // - No formal name was specified in the CREATE PROCEDURE. Use
    //   the (possibly empty) dynamic parameter or host variable name
    //   instead.
    // - This is a JDBC or ODBC compile and the client is using a
    //   named host variable or dynamic parameter. JDBC and ODBC want
    //   us to use the client's name in this case.

    if (formalParamName.isNull() ||
        (!userParamName.isNull() && (isJdbc || isOdbc)))
    {
      colParamName = &userParamName;
    }

    ColRefName *columnName = 
        new (bindWA->wHeap())
            ColRefName(*colParamName, bindWA->wHeap());

    resultTable->addColumn(bindWA, *columnName, outputExprToBind->getValueId());

    //
    // We need the following line for static cursor declaration,
    // according to a comment in bindRowValues()
    //
    cmpCurrentContext->saveRetrievedCols_ = resultTable->getDegree();

  } // if OUTPUT or INOUT

} // setInOrOutParam





CollIndex RelRoutine::countSuppliedParams (ItemExpr *tree) const
{
  CollIndex numParams=0;

  if ( !tree )  return 0;

  if (ITM_ITEM_LIST == tree->getOperatorType ())
  {
    numParams += countSuppliedParams (tree->child (0));
    numParams += countSuppliedParams (tree->child (1));
  }
  else
    numParams++;

  return numParams;

} // RelRoutine::countSuppliedParams

void RelRoutine::gatherParamValueIds (const ItemExpr *tree, ValueIdList &paramsList) const
{
  if ( !tree )  return;

  if (ITM_ITEM_LIST == tree->getOperatorType ())
  {
    gatherParamValueIds (tree->child (0), paramsList);
    gatherParamValueIds (tree->child (1), paramsList);
  }
  else
    paramsList.insert(tree->getValueId());
} // RelRoutine::gatherParamValueIds

void ProxyFunc::createProxyFuncTableDesc(BindWA *bindWA, CorrName &corrName)
{
  // Map column definitions into a TrafDesc
  TrafDesc *tableDesc = createVirtualTableDesc();

  // Map the TrafDesc into an NATable. This will also add an
  // NATable entry into the bindWA's NATableDB.
  NATable *naTable =
    bindWA->getNATable(corrName, FALSE /*catmanUsages*/, tableDesc);
  if (bindWA->errStatus())
    return;

  // Allocate a TableDesc and attach it to this RelExpr instance
  setTableDesc(bindWA->createTableDesc(naTable, corrName));
  if (bindWA->errStatus())
    return;

  // Allocate a RETDesc and attach it to this and the BindScope
  setRETDesc(new (bindWA->wHeap()) RETDesc(bindWA, getTableDesc()));
  bindWA->getCurrentScope()->setRETDesc(getRETDesc());
}


RelExpr *ProxyFunc::bindNode(BindWA *bindWA)
{
  // This method now serves as a common bind node for SPProxy and 
  // ExtractSource classes, where we before had SPProxyFunc::bindNode()
  // and ExtractSource::bindNode().

  if (nodeIsBound())
  {
    bindWA->getCurrentScope()->setRETDesc(getRETDesc());
    return this;
  }

  // Bind the child nodes
  bindChildren(bindWA);
  if (bindWA->errStatus())
    return this;

  // Declare a correlation name that is unique within this query
  switch (getOperatorType())
  {
    case REL_EXTRACT_SOURCE:
      virtualTableName_ = "EXTRACT_SOURCE_";
      break;
    case REL_SP_PROXY:
      virtualTableName_ = "SP_RESULT_SET_";
      break;
    default:
         CMPASSERT(0);
      break;
  }

  virtualTableName_ += bindWA->fabricateUniqueName();
  CorrName corrName(getVirtualTableName());
  corrName.setSpecialType(ExtendedQualName::VIRTUAL_TABLE);
  
  createProxyFuncTableDesc(bindWA, corrName);
  if (bindWA->errStatus())
    return this;

  // Bind the base class
  RelExpr *boundExpr = bindSelf(bindWA);
  if (bindWA->errStatus())
    return boundExpr;

  // Assign the set of columns that belong to the virtual table
  // as the output values that can be produced by this node.
  getGroupAttr()->addCharacteristicOutputs(getTableDesc()->getColumnList());

  return boundExpr;

} // ProxyFunc::bindNode()

RelExpr *TableMappingUDF::bindNode(BindWA *bindWA)
{
  if (nodeIsBound())
    {
      bindWA->getCurrentScope()->setRETDesc(getRETDesc());
      return this;
    }

  // Create NARoutine object (no caching for TMUDF)
  NARoutine *tmudfRoutine =NULL;
  CorrName& tmfuncName = getUserTableName();
  tmfuncName.setSpecialType(ExtendedQualName::VIRTUAL_TABLE);

  
  QualifiedName name = getRoutineName();
  const SchemaName &defaultSchema =
    bindWA->getSchemaDB ()->getDefaultSchema();
  name.applyDefaults(defaultSchema);
  setRoutineName(name);

  // Return an error if an unsupported catalog is being used.
  if ((NOT name.isSeabase()) && (NOT name.isHive()))
      {
	*CmpCommon::diags()
	  << DgSqlCode(-1002)
	  << DgCatalogName(name.getCatalogName());
	
	bindWA->setErrStatus();
	return NULL;
      }

  Lng32 diagsMark = CmpCommon::diags()->mark();
  NABoolean errStatus = bindWA->errStatus();

  tmudfRoutine = getRoutineMetadata(name, tmfuncName, bindWA);
  if (tmudfRoutine == NULL)
    {
      // this could be a predefined TMUDF, which is not
      // recorded in the metadata at this time
      OperatorTypeEnum opType =
        PredefinedTableMappingFunction::nameIsAPredefinedTMF(tmfuncName);

      if (opType != REL_ANY_TABLE_MAPPING_UDF)
        {
          // yes, this is a predefined TMUDF
          PredefinedTableMappingFunction *result;

          // discard the errors from the failed name lookup
          CmpCommon::diags()->rewind(diagsMark);
          if (!errStatus)
            bindWA->resetErrStatus();

          // create a new RelExpr
          result = new(bindWA->wHeap())
            PredefinedTableMappingFunction(
                 getArity(),
                 tmfuncName,
                 const_cast<ItemExpr *>(getProcAllParamsTree()),
                 opType);

          // copy data members of the base classes
          TableMappingUDF::copyTopNode(result);

          // set children
          result->setArity(getArity());
          for (int i=0; i<getArity(); i++)
            result->child(i) = child(i);

          // Abandon the current node and return the bound new node.
          // Next time it will reach this method it will call an
          // overloaded getRoutineMetadata() that will succeed.
          return result->bindNode(bindWA);
        }

      // getRoutineMetadata has already set the diagnostics area
      // and set the error status
      CMPASSERT(bindWA->errStatus());
      return NULL;
    }

  // Bind the child nodes.
  bindChildren(bindWA);
  if (bindWA->errStatus())
    return this;

  // Use information from child to populate childInfo_
  NAHeap *heap = CmpCommon::statementHeap();
  for(Int32 i = 0; i < getArity(); i++)
  {
    NAString childName(heap);
    NAColumnArray childColumns(heap) ;
    RETDesc *childRetDesc = child(i)->getRETDesc();
    
    // Get Name
    LIST(CorrName*) nameList(STMTHEAP);
    childRetDesc->getXTNM().dumpKeys(nameList);
    if (nameList.entries() == 1)
    {
      childName = (nameList[0])->getExposedNameAsString();
    }
    else
    {
      childName = "_inputTable" + bindWA->fabricateUniqueName();
    }
    
    // ask for histograms of all child outputs, since we don't
    // know what the UDF will need and what predicates exist
    // on passthru columns of the UDF
    bindWA->getCurrentScope()->context()->inWhereClause() = TRUE;

    // Get NAColumns
    
    CollIndex numChildCols = childRetDesc->getColumnList()->entries();
    for(CollIndex j=0; j < numChildCols; j++)
    {
      NAColumn * childCol = new (heap) NAColumn(
        childRetDesc->getColRefNameObj(j).getColName().data(),
        j,
        childRetDesc->getType(j).newCopy(heap),
        heap);
      childColumns.insert(childCol);

      bindWA->markAsReferencedColumn(childRetDesc->getValueId(j));
    }
    bindWA->getCurrentScope()->context()->inWhereClause() = FALSE;

    // get child root
    CMPASSERT(child(i)->getOperator().match(REL_ROOT) ||
      child(i)->getOperator().match(REL_RENAME_TABLE));
    RelRoot * myChild;
    if (child(i)->getOperator().match(REL_RENAME_TABLE))
      myChild = (RelRoot *) (child(i)->child(0).getPtr());
    else
      myChild = (RelRoot *) child(i).getPtr();

    // output vidList from child RetDesc, 
    // can also get from child Root compExpr
    ValueIdList vidList;
    childRetDesc->getValueIdList(vidList, USER_COLUMN);
    ValueIdSet childPartition(myChild->partitionArrangement());
    ValueIdList childOrder(myChild->reqdOrder());

    // request multi-column histograms for the PARTITION BY columns
    bindWA->getCurrentScope()->context()->inGroupByClause() = TRUE;

    // replace 1-based ordinals in the child's partition by / order by with
    // actual columns
    for (ValueId cp=childPartition.init();
         childPartition.next(cp);
         childPartition.advance(cp))
      {
        NABoolean negate;
        ConstValue *cv = cp.getItemExpr()->castToConstValue(negate);

        if (cv &&
            cv->canGetExactNumericValue())
        {
          Lng32 scale = 0;
          Int64 ordinal = cv->getExactNumericValue(scale);

          if (!negate && scale == 0 && ordinal >= 1 && ordinal <= vidList.entries())
            {
              // remove this ValueId from the set and add the corresponding
              // column value. Note that this won't cause problems with the
              // iterator through the set, since we don't need to apply
              // this conversion on the new element we are inserting
              childPartition -= cp;
              childPartition += vidList[ordinal-1];
            }
          else
            {
              *CmpCommon::diags()
                << DgSqlCode(-11154)
                << DgInt0(ordinal)
                << DgString0("PARTITION BY")
                << DgInt1(vidList.entries());
              bindWA->setErrStatus();
              return NULL;
            }
        }
        bindWA->markAsReferencedColumn(cp);
      }
    bindWA->getCurrentScope()->context()->inGroupByClause() = FALSE;

    for (CollIndex co=0; co<childOrder.entries(); co++)
      {
        NABoolean negate;
        ItemExpr *ie = childOrder[co].getItemExpr();
        ConstValue *cv = NULL;

        if (ie->getOperatorType() == ITM_INVERSE)
          ie = ie->child(0);
        cv = ie->castToConstValue(negate);

        if (cv &&
            cv->canGetExactNumericValue())
        {
          Lng32 scale = 0;
          Int64 ordinal = cv->getExactNumericValue(scale);

          // replace the const value with the actual column
          if (!negate && scale == 0 && ordinal >= 1 && ordinal <= vidList.entries())
            if (ie == childOrder[co].getItemExpr())
              {
                // ascending order
                childOrder[co] = vidList[ordinal-1];
              }
            else
              {
                // desc order, need to add an InverseOrder on top
                ItemExpr *inv = new(bindWA->wHeap()) InverseOrder(
                     vidList[ordinal-1].getItemExpr());
                inv->synthTypeAndValueId();
                childOrder[co] = inv->getValueId();
              }
          else
            {
              *CmpCommon::diags()
                << DgSqlCode(-11154)
                << DgInt0(ordinal)
                << DgString0("ORDER BY")
                << DgInt1(vidList.entries());
              bindWA->setErrStatus();
              return NULL;
            }
        }
      }

    TableMappingUDFChildInfo * cInfo = new (heap) TableMappingUDFChildInfo(
      childName, 
      childColumns,
      myChild->getPartReqType(), 
      childPartition,
      childOrder,
      vidList);
    childInfo_.insert(cInfo);
  }

  RoutineDesc *tmudfRoutineDesc = new (bindWA->wHeap()) RoutineDesc(bindWA, tmudfRoutine); 
  if (tmudfRoutineDesc == NULL ||  bindWA->errStatus ())
  {
    // Error
    bindWA->setBindingCall (FALSE);
    bindWA->setErrStatus ();
    return this;
  }
  setRoutineDesc(tmudfRoutineDesc);
  // xcnm will be empty because the routineDesc does not contain any 
  // output columns yet
  RETDesc *rDesc = new (bindWA->wHeap()) RETDesc(bindWA, tmudfRoutineDesc);
  bindWA->getCurrentScope()->setRETDesc(rDesc);
  setRETDesc(rDesc);

  dllInteraction_ = new (bindWA->wHeap()) TMUDFDllInteraction();

  // ValueIDList of the actual input parameters 
  // (tmudfRoutine has formal parameters)
  if (getProcAllParamsTree() && (getProcAllParamsVids().isEmpty() == TRUE)) 
  {
      ((ItemExpr *)getProcAllParamsTree())->convertToValueIdList(
		  getProcAllParamsVids(), bindWA, ITM_ITEM_LIST);
      if (bindWA->errStatus()) return NULL;
      
      // Clear the Tree since we now have gotten vids for all the parameters.
      setProcAllParamsTree(NULL);
  }
  getProcInputParamsVids().insert(getProcAllParamsVids());

  // invoke the optional UDF compiler interface or a default
  // implementation to validate scalar inputs and produce a list of
  // output columns

  NABoolean status = dllInteraction_->describeParamsAndMaxOutputs(this, bindWA);
  if (!status)
    {
      bindWA->setErrStatus();
      return NULL;
    }

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

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

  // create a ValueIdMap that allows us to translate
  // output columns that are passed through back to
  // input columns (outputs of the child), this can
  // be used to push down predicates, translate
  // required order and partitioning, etc.
  status = dllInteraction_->createOutputInputColumnMap(
       this,
       udfOutputToChildInputMap_);
  if (!status)
    {
      bindWA->setErrStatus();
      return NULL;
    }

  // if this is a maintenance-type operation that must run on
  // all nodes of the cluster or must run in parallel, regardless
  // of the ATTEMPT_ESP_PARALLELISM CQD, then set a flag in the
  // root node
  if (getOperatorType() == REL_TABLE_MAPPING_BUILTIN_LOG_READER)
    bindWA->getTopRoot()->setMustUseESPs(TRUE);

  // add the routine to the UdrStoiList.  The UdrStoi list is used
  // to check valid privileges
  LIST(OptUdrOpenInfo *) udrList = bindWA->getUdrStoiList ();
  ULng32 numUdrs = udrList.entries();
  NABoolean udrReferenced = FALSE;

  // See if UDR already exists
  for (ULng32 stoiIndex = 0; stoiIndex < numUdrs; stoiIndex++)
  {
    if ( 0 ==
         udrList[stoiIndex]->getUdrName().compareTo(
                           getRoutineName().getQualifiedNameAsAnsiString()
                                                  )
       )
    {
      udrReferenced = TRUE;
      break;
    }
  }

  // UDR has not been defined, go ahead an add one
  if ( FALSE == udrReferenced )
  {
    SqlTableOpenInfo *udrStoi = new (bindWA->wHeap ())SqlTableOpenInfo ();
    udrStoi->setAnsiName ( convertNAString(
                           getRoutineName().getQualifiedNameAsAnsiString(),
                           bindWA->wHeap ())
                         );

    OptUdrOpenInfo *udrOpenInfo = new (bindWA->wHeap ())
      OptUdrOpenInfo( udrStoi
                    , getRoutineName().getQualifiedNameAsAnsiString()
                    , (NARoutine *)getNARoutine()
                    );
    bindWA->getUdrStoiList().insert(udrOpenInfo);
  }

  RelExpr *boundExpr = bindSelf(bindWA);
  if (bindWA->errStatus())
    return NULL;
  return boundExpr;
}

RelExpr * FastExtract::bindNode(BindWA *bindWA)
{
  if (nodeIsBound())
  {
    bindWA->getCurrentScope()->setRETDesc(getRETDesc());
    return this;
  }


  // check validity of target location
  if (getTargetType() == FILE)
  {
    char reasonMsg[256];
    NABoolean raiseError = FALSE;
    if ((unsigned char)(getTargetName().data()[0]) != SLASH_C)
    {
      raiseError = TRUE;
      sprintf(reasonMsg,"Relative path name was used");
    }
    else if (getTargetName().length() > 512)
    {
      raiseError = TRUE;
      sprintf(reasonMsg,"Length exceeds 512 characters");
    }
    else
    {
      char * sqroot = getenv("TRAF_HOME");
      if (sqroot && (! CmpCommon::context()->getSqlmxRegress()) &&
          (strncmp(sqroot, getTargetName().data(),strlen(sqroot)) == 0))
      {
        raiseError = TRUE;
        sprintf(reasonMsg,"Database system directory was used");
      }
    }
    if (raiseError  && strncmp(getTargetName().data(),"hdfs://",7) != 0 )
    {
      *CmpCommon::diags() << DgSqlCode(-4378) << DgString0(reasonMsg) ;
      bindWA->setErrStatus();
      return NULL;
    }
  }


  if (getDelimiter().length() == 0)
  {
    delimiter_ = ActiveSchemaDB()->getDefaults().getValue(TRAF_UNLOAD_DEF_DELIMITER);
  }

  // if inserting into a hive table and an explicit null string was
  // not specified in the unload command, and the target table has a user
  // specified null format string, then use it.
  if ((isHiveInsert()) &&
      (hiveTableDesc_ && hiveTableDesc_->getNATable() && 
       hiveTableDesc_->getNATable()->getClusteringIndex()) &&
      (NOT nullStringSpec_))
    {
      const HHDFSTableStats* hTabStats = 
        hiveTableDesc_->getNATable()->getClusteringIndex()->getHHDFSTableStats();

      if (hTabStats->getNullFormat())
        {
          nullString_ = hTabStats->getNullFormat();
          nullStringSpec_ = TRUE;
        }
    }

  // if an explicit or user specified null format was not used, then
  // use the default null string.
  if (NOT nullStringSpec_) 
    {
      nullString_ = HIVE_DEFAULT_NULL_STRING;
    }
  
  if (getRecordSeparator().length() == 0)
  {
    recordSeparator_ = ActiveSchemaDB()->getDefaults().getValue(TRAF_UNLOAD_DEF_RECORD_SEPARATOR);
  }


  if (!isHiveInsert())
  {
    bindWA->setIsFastExtract();
  }
  // Bind the child nodes.
  bindChildren(bindWA);
  if (bindWA->errStatus())
    return this;

  // Use information from child to populate childInfo_
  NAHeap *heap = CmpCommon::statementHeap();

  RETDesc *childRETDesc = child(0)->getRETDesc();
  // output vidList from child RetDesc,
  // can also get from child Root compExpr
  ValueIdList vidList;
  childRETDesc->getValueIdList(vidList, USER_COLUMN);

  if (isHiveInsert())
    {
      // validate number of columns and column types of the select list
      ValueIdList tgtCols;

      hiveTableDesc_->getUserColumnList(tgtCols);

      if (vidList.entries() != tgtCols.entries())
        {
          // 4023 degree of row value constructor must equal that of target table
          *CmpCommon::diags() << DgSqlCode(-4023)
                              << DgInt0(vidList.entries())
                              << DgInt1(tgtCols.entries());
          bindWA->setErrStatus();
          return NULL;
        }

      // Check that the source and target types are compatible.
      for (CollIndex j=0; j<vidList.entries(); j++)
        {
          Assign *tmpAssign = new(bindWA->wHeap())
            Assign(tgtCols[j].getItemExpr(), vidList[j].getItemExpr());

          if ( CmpCommon::getDefault(ALLOW_IMPLICIT_CHAR_CASTING) == DF_ON )
            tmpAssign->tryToDoImplicitCasting(bindWA);
          const NAType *targetType = tmpAssign->synthesizeType();
          if (!targetType) {
            bindWA->setErrStatus();
            return NULL;
          }
        }
    }

  setSelectList(vidList);

  if (includeHeader())
  {
    const ColumnDescList &columnsRET = *(childRETDesc->getColumnList());
    for (CollIndex i = 0; i < columnsRET.entries(); i++)
    {
      if (columnsRET[i]->getHeading())
        header_ += columnsRET[i]->getHeading();
      else if (!(columnsRET[i]->getColRefNameObj().isEmpty()))
        header_ += columnsRET[i]->getColRefNameObj().getColName();
      else
        header_ += "EXPR";

      if (i < (columnsRET.entries() -1))
      {
        header_ += " ";
        header_ += delimiter_;
        header_ += " ";
      }
    }
  }
  else
  {
          header_ = "NO_HEADER" ;
  }

  // no rows are returned from this operator.
  // Allocate an empty RETDesc and attach it to this and the BindScope.
  setRETDesc(new (bindWA->wHeap()) RETDesc(bindWA));

  RelExpr *boundExpr = bindSelf(bindWA);
  if (bindWA->errStatus()) return NULL;
  return boundExpr;
}


RelExpr * ControlRunningQuery::bindNode(BindWA *bindWA)
{
  if (nodeIsBound()) {
    bindWA->getCurrentScope()->setRETDesc(getRETDesc());
    return this;
  }
  //
  // Check to see if user is authorized to control this query.
  //
  if (!isUserAuthorized(bindWA))
     return NULL;

  //
  // Bind the child nodes.
  //
  bindChildren(bindWA);
  if (bindWA->errStatus())
    return this;

  // no rows are returned from this operator. 
  // Allocate an empty RETDesc and attach it to this and the BindScope.
  //
  setRETDesc(new (bindWA->wHeap()) RETDesc(bindWA));

  //
  // Bind the base class.
  //
  RelExpr *boundExpr = bindSelf(bindWA);
  if (bindWA->errStatus()) 
    return boundExpr;


  ValueIdSet ov;
  getPotentialOutputValues(ov);
  getGroupAttr()->addCharacteristicOutputs(ov);

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


bool ControlRunningQuery::isUserAuthorized(BindWA *bindWA)
{
  bool userHasPriv = false;
  Int32 sessionID = ComUser::getSessionUser();

  // Check to see if the current user owns the query id.
  // This only has to be done for the Cancel query request.
  // This option to check privilege is not available unless
  // the query Id was supplied.
  if ((action_ == Cancel) &&
      (qs_ == ControlQid))
  {
    // The user ID associated with the query is stored in the QID. 
    // To be safe, copy the QID to a character string.
    Int32 qidLen = queryId_.length();
    char *pQid = new (bindWA->wHeap()) char[qidLen+1];
    str_cpy_all(pQid, queryId_.data(), qidLen);
    pQid[qidLen] = '\0';

    // Set up the returned parameters
    // Max username can be (128 * 2) + 2 (delimiters) + 1 (null indicator)
    char username[2 * MAX_USERNAME_LEN + 2 + 1];
    Int64 usernameLen = sizeof(username) - 1;
 
    // Call function to extract the username from the QID
    Int32 retcode = ComSqlId::getSqlQueryIdAttr(ComSqlId::SQLQUERYID_USERNAME,
                                                pQid,
                                                qidLen,
                                                usernameLen,
                                                &username[0]);
    if (retcode == 0)
    {
      // The username stored in the QID is actually the userID preceeded with
      // a "U".  Check for a U and convert the succeeding characters 
      // to integer.  This integer value is compared against the current userID.
      username[usernameLen] = '\0';  
      if (username[0] == 'U')
      {
        Int64 userID = str_atoi(&username[1],usernameLen - 1);  
        if (sessionID == userID || sessionID == ComUser::getRootUserID())
          userHasPriv = true;
      }
      // If userName does not begin with a 'U', ignore and continue
    }
    // If retcode != 0, continue, an invalid QID could be specified which
    // is checked later in the code
  }
  
  // The current user does not own the query, see if the current user has 
  // the correct QUERY privilege.  Code above only supports cancel, but other 
  // checks could be added.  Component checks for all query operations.
  if (!userHasPriv)
  {
    SQLOperation operation;
    switch (ControlRunningQuery::action_)
    {
      case ControlRunningQuery::Suspend:
        operation = SQLOperation::QUERY_SUSPEND;
        break;
      case ControlRunningQuery::Activate:
        operation = SQLOperation::QUERY_ACTIVATE;
        break;
      case ControlRunningQuery::Cancel:
        operation = SQLOperation::QUERY_CANCEL;
        break;
      default:
        operation = SQLOperation::UNKNOWN;
    }
    
    NAString privMDLoc = CmpSeabaseDDL::getSystemCatalogStatic();
    privMDLoc += ".\"";
    privMDLoc += SEABASE_PRIVMGR_SCHEMA;
    privMDLoc += "\"";

    PrivMgrComponentPrivileges componentPriv(
      privMDLoc.data(),CmpCommon::diags());

    userHasPriv = componentPriv.hasSQLPriv(sessionID,operation,true);
    
    if (!userHasPriv)
    {
      // ANSI requests a special SqlState for cancel requests
      if (ControlRunningQuery::action_ == ControlRunningQuery::Cancel)
        *CmpCommon::diags() << DgSqlCode(-8029);
      else
        *CmpCommon::diags() << DgSqlCode(-1017);
      bindWA->setErrStatus();
    }
    
    if (bindWA->errStatus())
      return false;
  }
  return true;
  
}// ControlRunningQuery::isUserAuthorized()

RelExpr * CommonSubExprRef::bindNode(BindWA *bindWA)
{
  if (nodeIsBound()) {
    bindWA->getCurrentScope()->setRETDesc(getRETDesc());
    return this;
  }

  CSEInfo *info = CmpCommon::statement()->getCSEInfo(internalName_);
  CommonSubExprRef *parentCSE = bindWA->inCSE();

  DCMPASSERT(info);

  // eliminate any CommonSubExprRef nodes that are not truly common,
  // i.e. those that are referenced only once
  if (info->getNumConsumers() <= 1)
    {
      info->eliminate();
      return child(0).getPtr()->bindNode(bindWA);
    }

  bindWA->setInCSE(this);

  // establish the parent/child relationship
  addParentRef(parentCSE);

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

  // we know that our child is a RenameTable (same name as this CSE,
  // whose child is a RelRoot, defining the CTE. Copy the bound select
  // list of the CTE.
  CMPASSERT(child(0)->getOperatorType() == REL_RENAME_TABLE &&
            child(0)->child(0)->getOperatorType() == REL_ROOT);
  columnList_ = static_cast<RelRoot *>(child(0)->child(0).getPtr())->compExpr();

  bindWA->setInCSE(parentCSE);

  return bindSelf(bindWA);
}

RelExpr * OSIMControl::bindNode(BindWA *bindWA)
{
  if (nodeIsBound())
  {
    bindWA->getCurrentScope()->setRETDesc(getRETDesc());
    return this;
  }
  //Create OptimizerSimulator if this is called first time.
  if(!CURRCONTEXT_OPTSIMULATOR)
      CURRCONTEXT_OPTSIMULATOR = new(CTXTHEAP) OptimizerSimulator(CTXTHEAP);
      
  //in respond to force option of osim load, 
  //e.g. osim load from '/xxx/xxx/osim-dir', force
  //if true, when loading osim tables/views/indexes
  //existing objects with same qualified name 
  //will be droped first
  CURRCONTEXT_OPTSIMULATOR->setForceLoad(isForceLoad());
  //Set OSIM mode
  if(!CURRCONTEXT_OPTSIMULATOR->setOsimModeAndLogDir(targetMode_, osimLocalDir_.data()))
  {
      bindWA->setErrStatus();
      return this;
  }

  return ControlAbstractClass::bindNode(bindWA);
}

