/**********************************************************************
// @@@ 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:         GenRelMisc.C
* RCS:          $Id: GenRelMisc.cpp,v 1.1 2007/10/09 19:38:54  Exp $
* Description:  MapValueId/Root/Tuple operators
*
* Created:      5/17/94
* Modified:     $ $Date: 2007/10/09 19:38:54 $ (GMT)
* Language:     C++
* Status:       $State: Exp $
*
*
*
******************************************************************************
*/
#define   SQLPARSERGLOBALS_FLAGS
#include "ComOptIncludes.h"
#include "GroupAttr.h"
#include "ItemColRef.h"
#include "RelEnforcer.h"
#include "RelJoin.h"
#include "RelExeUtil.h"
#include "RelMisc.h"
#include "RelSet.h"
#include "RelUpdate.h"
#include "RelScan.h"
#include "RelDCL.h"
#include "PartFunc.h"
#include "Cost.h"
#include "GenExpGenerator.h"
#include "GenResources.h"
#include "ComTdbRoot.h"
#include "ComTdbTuple.h"
#include "ComTdbUnion.h"
#include "ComTdbTupleFlow.h"
#include "ComTdbTranspose.h"
#include "ComTdbSort.h"
#include "ComTdbPackRows.h"
#include "ComTdbDDL.h"
#include "ComTdbExeUtil.h"
#include "ComTdbFirstN.h"
#include "ComTdbStats.h"
#include "ComTdbCancel.h"
#include "ExplainTuple.h"
#include "ComTdbHbaseAccess.h"
#include "ComTdbExplain.h"
#include "SchemaDB.h"
#include "ControlDB.h"
#include "NATable.h"
#include "BindWA.h"
#include "ComTransInfo.h"
#include "DefaultConstants.h"
#include "FragDir.h"
#include "PartInputDataDesc.h"
#include "ExpSqlTupp.h"
#include "sql_buffer.h"
#include "ComQueue.h"
#include "ComSqlId.h"
#include "MVInfo.h"
#include "SequenceGeneratorAttributes.h"
#include "CompilationStats.h"
#include "RelRoutine.h"
#include "hs_cont.h"
#include "ComUnits.h"

#include "StmtDDLCleanupObjects.h"

#ifndef HFS2DM
#define HFS2DM
#endif // HFS2DM

#include "ComDefs.h"            // to get common defines (ROUND8)
#include "CmpStatement.h"
#include "ComSmallDefs.h"
#include "sql_buffer_size.h"
#include "ExSqlComp.h"		// for NAExecTrans

#include "ComLocationNames.h"
#include "ComDistribution.h"
#include "OptimizerSimulator.h"

#include "ComCextdecs.h"

#include "TrafDDLdesc.h"

#include "SqlParserGlobals.h"   // Parser Flags

// this comes from GenExplain.cpp (sorry, should have a header file)
TrafDesc * createVirtExplainTableDesc();
void deleteVirtExplainTableDesc(TrafDesc *);

/////////////////////////////////////////////////////////////////////
//
// 
//
//////////////////////////////////////////////////////////////////////

 
/////////////////////////////////////////////////////////
//
// MapValueIds::codeGen()
//
/////////////////////////////////////////////////////////
short MapValueIds::codeGen(Generator * generator)
{

  // The MapValueIds node does not result in any executor nodes.  It
  // does not generate a TDB.  It simply 'maps' its lower values to
  // its upper values.  It does this by doing the following for each
  // upper and lower pairing.
  //
  //   - creates a new expressions which converts the lower value to
  //     the type of the upper value.
  //
  //   - Associates this new expression with the ValueId of the upper
  //     value, by replacing the ItemExpr of the upper valueId with
  //     this new expression.
  //
  // The end result is that in nodes above this MapValueIds node,
  // references to the ValueIds of the upper list, will get the new
  // expression (the Cast of the lower value).
  //
  // This code was initially placed in the MapValueIds::preCodeGen(),
  // but this caused some problems with Query trees involving
  // triggers.  The issue was that with triggers it is possible for a
  // ValueId to be sourced (produced) in two different subtrees of the
  // query tree.  One being a MapValueId.  So when the expressions of
  // the upper valueIds were replaced, it not only affected references
  // to the ValueIds above the MapValueIds, it affected the references
  // to the ValueIds in other subtrees.


  // generate code for the child
  child(0)->codeGen(generator);

  const ValueIdList & topValues = map_.getTopValues();

  for (CollIndex i = 0; i < topValues.entries(); i++)
    {
      ValueId valId = topValues[i];

      // if this value id is mapped to a different one (mappedId ) by
      // this node, then convert the "mappedId" to the type of this
      // 'valid'
      //
      ValueId mappedId;
      map_.mapValueIdDown(valId,mappedId);

      if (mappedId != valId)
	{

	  // Convert the source (lower) value to the type of the
          // target (upper) value.
          //
	  ItemExpr * convValue
	    = new(generator->wHeap()) Cast (mappedId.getItemExpr(),
			&(valId.getType()));

	  // bind/type propagate the new node
	  convValue->bindNode(generator->getBindWA());

          // Replace upper value with converted value.
          //
          valId.replaceItemExpr(convValue);

	}
    }

  // No TDB was generated.  Parent will retrieve childs TDB
  //
  return 0;
}

/////////////////////////////////////////////////////////
//
// Some helper classes and functions for PartitionAccess::codeGen
//
/////////////////////////////////////////////////////////

class NodeCountHelper {
friend class NodeHashHelper;
public:
  UInt32 getCount(void) { return nodeDiskCount_;}
  void incCount(void) { nodeDiskCount_++; }
  inline NABoolean operator==(const NodeCountHelper& other) const
  {
    return (nodeDiskCount_ == other.nodeDiskCount_);
  }

private:
  UInt32 nodeDiskCount_;
};

class NodeNameHelper {
friend class NodeHashHelper;
friend ULng32 nodeNameHashFunc( const NodeNameHelper& n );

public:
  const char * const getNodeName(void) { return nodeName_; }
  ULng32 hash() const { return nodeNameHashFunc(*this); }
  inline NABoolean operator==(const NodeNameHelper& other) const
  {
    if (stricmp(nodeName_, other.nodeName_) != 0)
	return FALSE;
    else
        return TRUE;
  }
private:
  char nodeName_[ComGUARDIAN_SYSTEM_NAME_PART_CHAR_MAX_LEN + 1];
};

ULng32 nodeNameHashFunc( const NodeNameHelper& n )
{
  ULng32 retval = 0;
  const char * const c = n.nodeName_;
  Int32 i = 0;
  do {
    retval += c[i++];
  } while (c[i]);
  return retval;
}


class NodeDiskNameHelper {
friend class NodeHashHelper;
friend ULng32 nodeDiskNameHashFunc( const NodeDiskNameHelper& n );

public:
  inline NABoolean operator==(const NodeDiskNameHelper& other) const
  {
    if (stricmp(nodeDiskName_, other.nodeDiskName_) != 0)
	return FALSE;
    else
        return TRUE;
  }

  ULng32 hash() const { return nodeDiskNameHashFunc(*this); }

private:
  char nodeDiskName_[
     ComGUARDIAN_SYSTEM_NAME_PART_CHAR_MAX_LEN + 1    // + 1 for the dot.
   + ComGUARDIAN_VOLUME_NAME_PART_CHAR_MAX_LEN + 1    // + 1 for the \0.
                    ];
};

ULng32 nodeDiskNameHashFunc( const NodeDiskNameHelper& n )
{
  ULng32 retval = 0;
  const char * const c = n.nodeDiskName_;
  Int32 i = 0;
  do {
    retval += c[i++];
  } while (c[i]);
  return retval;
}

class NodeHashHelper {

public:
  NodeHashHelper  ( const char * partn )
    {
      memmove(nodeName_.nodeName_, partn, sizeof nodeName_.nodeName_);
          // Convert 1st dot into a null termininator.
      char * dotPos = strchr(nodeName_.nodeName_, '.');
      *dotPos = '\0';
      memmove(nodeDiskName_.nodeDiskName_, partn,
                                 sizeof nodeDiskName_.nodeDiskName_);
          // Convert 2nd dot into a null termininator.
      dotPos = strchr(nodeDiskName_.nodeDiskName_, '.');
      dotPos = strchr(dotPos+1, '.');
      *dotPos = '\0';
      nodeDiskCount_.nodeDiskCount_ = 1;
    }
  NodeNameHelper * getNodeName(void) { return &nodeName_; }
  NodeDiskNameHelper * getNodeDiskName(void) { return &nodeDiskName_; }
  NodeCountHelper * getNodeDiskCount(void) { return &nodeDiskCount_ ; }
private:
  NodeHashHelper();
  NodeCountHelper nodeDiskCount_ ;
  NodeNameHelper nodeName_;
  NodeDiskNameHelper nodeDiskName_;
};

static void replaceBaseValue(ItemExpr *incomingExpr, 
			     ItemExpr *resultExpr, 
			     CollHeap *heap,
			     NABoolean setFound) 
{
  static THREAD_P NABoolean found = FALSE;

  found = setFound;
  Int32 nc = incomingExpr->getArity();

  // ITM_ASSIGN operator will not be a leaf node.
  if ((nc != 0) && (found == FALSE)) //have not found yet.
     {
       ItemExpr *child1 = incomingExpr->child(1);
       ItemExpr *newExpr = NULL;
       if (incomingExpr->getOperatorType() == ITM_ASSIGN &&
	   (child1 != NULL && child1->getOperatorType() == ITM_ASSIGN)
	   )
	 {
	   newExpr = new(heap) BiArith(ITM_PLUS,
				       resultExpr,
				       child1);

	   newExpr->synthTypeAndValueId(TRUE);
	   //set type to original type after if has been changed to BigNum above
	   newExpr->getValueId().changeType(new (heap) SQLLargeInt(heap, 1 /* signed */,
								    0 /* not null */));
	   incomingExpr->setChild(1,newExpr);
	   found = TRUE;
	   return;
	 }

       for (Lng32 i = 0; i < (Lng32)nc; i++)
	{
	  if (found == FALSE)
	    replaceBaseValue(incomingExpr->child(i), resultExpr, heap, found);
	}
    } 
  return; 
}

short GenericUtilExpr::codeGen(Generator * generator)
{
  GenAssert(0, "GenericUtilExpr::codeGen. Should not reach here.");

  return 0;
}

/////////////////////////////////////////////////////////
//
// DDLExpr::codeGen()
//
/////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////
//
// ExeUtilExpr::codeGen()
//
/////////////////////////////////////////////////////////
const char * DDLExpr::getVirtualTableName()
{ return (producesOutput() ? "DDL_EXPR__" : NULL); }

TrafDesc *DDLExpr::createVirtualTableDesc()
{
  TrafDesc * table_desc = NULL;
  if (producesOutput())
    {
      table_desc = 
        Generator::createVirtualTableDesc(getVirtualTableName(),
                                          NULL, // let it decide what heap to use
                                          ComTdbDDL::getVirtTableNumCols(),
                                          ComTdbDDL::getVirtTableColumnInfo(),
                                          ComTdbDDL::getVirtTableNumKeys(),
                                          ComTdbDDL::getVirtTableKeyInfo());
    }
  return table_desc;
}

short DDLExpr::codeGen(Generator * generator)
{
  Space * space = generator->getSpace();

  generator->verifyUpdatableTransMode(NULL, generator->getTransMode(), NULL);

  // remove trailing blanks and append a semicolon, if one is not present.
  char * ddlStmt = NULL;

  Int32 i = strlen(getDDLStmtText());
  while ((i > 0) && (getDDLStmtText()[i-1] == ' '))
    i--;

  if (getDDLStmtText()[i-1] == ';')
    i--;
 
  ddlStmt = space->allocateAlignedSpace(i+2);
  strncpy(ddlStmt, getDDLStmtText(), i);
  
  // add a semicolon to the end of str (required by the parser)
  ddlStmt[i++]   = ';';
 
  ddlStmt[i] = '\0';

  ex_cri_desc * givenDesc
    = generator->getCriDesc(Generator::DOWN);
  ex_cri_desc * returnedDesc = givenDesc;
  ex_cri_desc * workCriDesc = NULL;
  const Int32 work_atp = 1;
  const Int32 ddl_row_atp_index = 2;
  if (producesOutput())
    {
      // allocate a map table for the retrieved columns
      generator->appendAtEnd();

      returnedDesc = new(space) ex_cri_desc(givenDesc->noTuples() + 1, space);
      workCriDesc = new(space) ex_cri_desc(4, space);
      short rc = processOutputRow(generator, work_atp, ddl_row_atp_index,
                                  returnedDesc);
      if (rc)
        {
          return -1;
        }
    }

  NAString catSchName = 
    generator->currentCmpContext()->schemaDB_->getDefaultSchema().getSchemaNameAsAnsiString();
  
  CMPASSERT(!catSchName.isNull());		     // not empty
  CMPASSERT(catSchName.first('.') != NA_NPOS);	     // quick test: 'cat.sch'
  
  char * catSchNameStr = space->allocateAlignedSpace(catSchName.length() + 1);
  strcpy(catSchNameStr, catSchName.data());

  ComTdbDDL * ddl_tdb = NULL;

  if (returnStatus_)
    {
      ComTdbDDLwithStatus *ddl_ws_tdb = new(space)
        ComTdbDDLwithStatus(ddlStmt,
                            strlen(ddlStmt),
                            (Int16)getDDLStmtTextCharSet(),
                            catSchNameStr, strlen(catSchNameStr),
                            0, 0, // no input expr
                            0, 0, // no output expr
                            workCriDesc, (producesOutput() ? ddl_row_atp_index : 0),
                            givenDesc,
                            returnedDesc,
                            (queue_index)getDefault(GEN_DDL_SIZE_DOWN),
                            (queue_index)getDefault(GEN_DDL_SIZE_UP),
                            getDefault(GEN_DDL_NUM_BUFFERS),
                            getDefault(GEN_DDL_BUFFER_SIZE));
      
      ddl_ws_tdb->setReturnStatus(TRUE);

      if (isCleanup_)
        {
          ddl_ws_tdb->setMDcleanup(TRUE);

          StmtDDLCleanupObjects * co = 
            getExprNode()->castToElemDDLNode()->castToStmtDDLCleanupObjects();

          if (co->checkOnly())
            ddl_ws_tdb->setCheckOnly(TRUE);

          if (co->returnDetails())
            ddl_ws_tdb->setReturnDetails(TRUE);

        }
      ddl_tdb = ddl_ws_tdb;
    }
  else
    ddl_tdb = new(space)
      ComTdbDDL(ddlStmt,
                strlen(ddlStmt),
                (Int16)getDDLStmtTextCharSet(),
                catSchNameStr, strlen(catSchNameStr),
                0, 0, // no input expr
                0, 0, // no output expr
                workCriDesc, (producesOutput() ? ddl_row_atp_index : 0),
                givenDesc,
                returnedDesc,
                (queue_index)getDefault(GEN_DDL_SIZE_DOWN),
                (queue_index)getDefault(GEN_DDL_SIZE_UP),
                getDefault(GEN_DDL_NUM_BUFFERS),
                getDefault(GEN_DDL_BUFFER_SIZE));
  
  if (isHbase_)
    {
      ddl_tdb->setHbaseDDL(TRUE);
      
      if (hbaseDDLNoUserXn_)
        ddl_tdb->setHbaseDDLNoUserXn(TRUE);
    }
  
  generator->initTdbFields(ddl_tdb);
      
  if(!generator->explainDisabled()) {
    generator->setExplainTuple(
       addExplainInfo(ddl_tdb, 0, 0, generator));
  }

  // no tupps are returned
  generator->setCriDesc((ex_cri_desc *)(generator->getCriDesc(Generator::DOWN)),
			Generator::UP);
  generator->setGenObj(this, ddl_tdb);

  // Set the transaction flag.
  if (xnNeeded())
    {
      if (NOT isHbase_)
	generator->setTransactionFlag(-1);
      else if (getExprNode() && 
               getExprNode()->castToStmtDDLNode()->ddlXns() &&
               (NOT hbaseDDLNoUserXn_))
        {
          // treat like a transactional IUD operation which need to be
          // aborted in case of an error.
          generator->setFoundAnUpdate(TRUE);
	  generator->setUpdAbortOnError(TRUE);
          
          generator->setTransactionFlag(-1);
        }
      else if (NOT hbaseDDLNoUserXn_) 
	generator->setTransactionFlag(-1);
    }

  return 0;
}

/////////////////////////////////////////////////////////
//
// ExeUtilMetadataUpgrade::codeGen()
//
/////////////////////////////////////////////////////////
short ExeUtilMetadataUpgrade::codeGen(Generator * generator)
{
  ExpGenerator * expGen = generator->getExpGenerator();
  Space * space = generator->getSpace();

  // allocate a map table for the retrieved columns
  generator->appendAtEnd();

  ex_cri_desc * givenDesc
    = generator->getCriDesc(Generator::DOWN);

  ex_cri_desc * returnedDesc
    = new(space) ex_cri_desc(givenDesc->noTuples() + 1, space);

  ex_cri_desc * workCriDesc = new(space) ex_cri_desc(4, space);
  const Int32 work_atp = 1;
  const Int32 exe_util_row_atp_index = 2;

  short rc = processOutputRow(generator, work_atp, exe_util_row_atp_index,
                              returnedDesc);
  if (rc)
    {
      return -1;
    }

  ComTdbDDLwithStatus * upgd_tdb = new(space)
    ComTdbDDLwithStatus(NULL, 0, 0,
                        NULL, 0, 
                        0, 0, // no input expr
                        0, 0, // no output expr
                        NULL, 0,
                        givenDesc,
                        returnedDesc,
                        (queue_index)getDefault(GEN_DDL_SIZE_DOWN),
                        (queue_index)getDefault(GEN_DDL_SIZE_UP),
                        getDefault(GEN_DDL_NUM_BUFFERS),
                        getDefault(GEN_DDL_BUFFER_SIZE));

  if (getMDVersion())
    upgd_tdb->setGetMDVersion(TRUE);
  else if (getSWVersion())
    upgd_tdb->setGetSWVersion(TRUE);
  else
    upgd_tdb->setMDupgrade(TRUE);

  generator->initTdbFields(upgd_tdb);
  
  if(!generator->explainDisabled()) {
    generator->setExplainTuple(
       addExplainInfo(upgd_tdb, 0, 0, generator));
  }

  generator->setCriDesc(givenDesc, Generator::DOWN);
  generator->setCriDesc(returnedDesc, Generator::UP);
  
  generator->setGenObj(this, upgd_tdb);

  // Reset the transaction flag.
  generator->setTransactionFlag(0);

  return 0;
}

/////////////////////////////////////////////////////////
//
// FirstN::codeGen()
//
/////////////////////////////////////////////////////////
short FirstN::codeGen(Generator * generator)
{
  ExpGenerator* expGen = generator->getExpGenerator();
  Space * space = generator->getSpace();

  ex_cri_desc * given_desc = generator->getCriDesc(Generator::DOWN);

  // generate code for my child
  child(0)->codeGen(generator);
  ComTdb * child_tdb = (ComTdb *)(generator->getGenObj());
  ExplainTuple *childExplainTuple = generator->getExplainTuple();

  ex_cri_desc * returned_desc = generator->getCriDesc(Generator::UP);

  ex_cri_desc * work_cri_desc = NULL;
  ex_expr * firstNRowsExpr = NULL;
  if (firstNRowsParam_)
    {
      Int32 work_atp = 1; // temps
      Int32 work_atp_index = 2;  // where the result row will be
      work_cri_desc = new(space) ex_cri_desc(3, space);

      // input param is typed as nullable. Make it non-nullable and unsigned.
      NAType * newNAT = 
        firstNRowsParam_->getValueId().getType().newCopy(generator->wHeap());
      newNAT->setNullable(FALSE, FALSE);
      
      Cast * fnp = new(generator->wHeap()) Cast(firstNRowsParam_, newNAT);
      fnp->bindNode(generator->getBindWA());
      
      ValueIdList vidL;
      vidL.insert(fnp->getValueId());

      UInt32 firstNValLen = 0;
      expGen->generateContiguousMoveExpr(vidL,
                                         0, // no convert nodes,
                                         work_atp, work_atp_index,
                                         ExpTupleDesc::SQLARK_EXPLODED_FORMAT,
                                         firstNValLen, &firstNRowsExpr,
                                         NULL, ExpTupleDesc::SHORT_FORMAT);
    }
  
  ComTdbFirstN * firstN_tdb
    = new(space) ComTdbFirstN(
                              child_tdb,
                              getFirstNRows(),
                              firstNRowsExpr,
                              work_cri_desc,
                              given_desc,
                              returned_desc,
                              child_tdb->getMaxQueueSizeDown(),
                              child_tdb->getMaxQueueSizeUp(),
                              1, 4096);
  
  generator->initTdbFields(firstN_tdb);
  
  if(!generator->explainDisabled()) {
    generator->setExplainTuple(
                               addExplainInfo(firstN_tdb, childExplainTuple, 0, generator));
  }
  
  generator->setGenObj(this, firstN_tdb);
  
  return 0;
}


/////////////////////////////////////////////////////////
//
// RelRoot::genSimilarityInfo()
//
/////////////////////////////////////////////////////////
TrafQuerySimilarityInfo * RelRoot::genSimilarityInfo(Generator *generator)
{
  ExpGenerator * exp_gen = generator->getExpGenerator();

  NABoolean recompOnTSMismatch = FALSE;
  NABoolean errorOnTSMismatch = FALSE;

  // generate the similarity info.
  Space * space = generator->getSpace();

  NABoolean disableAutoRecomp   = (CmpCommon::getDefault(AUTOMATIC_RECOMPILATION) == DF_OFF);

  Queue * siList = new(space) Queue(space);
  TrafQuerySimilarityInfo * qsi = NULL;

  if (generator->getTrafSimTableInfoList().entries() > 0)
    qsi = new(space) TrafQuerySimilarityInfo(siList);

  CollIndex i = 0;

  for (CollIndex i = 0; i < generator->getTrafSimTableInfoList().entries(); i++)
    {
      TrafSimilarityTableInfo * genTsi =
	(TrafSimilarityTableInfo *)(generator->getTrafSimTableInfoList()[i]);
      
      char * genTablename =
        space->allocateAndCopyToAlignedSpace(genTsi->tableName(), str_len(genTsi->tableName()), 0);
      char * genRootDir = 
        space->allocateAndCopyToAlignedSpace(genTsi->hdfsRootDir(), str_len(genTsi->hdfsRootDir()), 0);
 
      char * genHdfsHostName =
        space->allocateAndCopyToAlignedSpace(genTsi->hdfsHostName(), str_len(genTsi->hdfsHostName()), 0);
        
      TrafSimilarityTableInfo * si = 
        new(space) TrafSimilarityTableInfo(genTablename,   
                                           genTsi->isHive(),
                                           genRootDir,
                                           genTsi->modTS(),
                                           genTsi->numPartnLevels(),
                                           NULL,
                                           genHdfsHostName,
                                           genTsi->hdfsPort());
      qsi->siList()->insert(si);
    }

  if (qsi)
    {
      qsi->setDisableAutoRecomp(disableAutoRecomp);
    }

  return qsi;
}

short RelRoot::codeGen(Generator * generator)
{
  ExpGenerator * exp_gen = generator->getExpGenerator();
  Space * space;
  FragmentDir *compFragDir = generator->getFragmentDir();
  NABoolean childTdbIsNull = FALSE;

  // -- MVs
  // Mark in the generator that we are doing an INTERNAL REFRESH command now.
  if (isRootOfInternalRefresh())
    generator->setInternalRefreshStatement();

  MapTable * map_table = generator->appendAtEnd();

  // create the fragment (independent code space) for the master executor
  CollIndex myFragmentId = compFragDir->pushFragment(FragmentDir::MASTER);

  // When the master executor gets the generated space, it assumes that
  // the root node is stored at the very beginning of the space, so
  // make sure that the master fragment is fragment 0 (the code
  // below makes sure that the root node is at the beginning of its
  // fragment).
  GenAssert(myFragmentId == 0,"NOT myFragmentId == 0");

  // now we can get a hold of the space object for this fragment
  space = generator->getSpace();

  // usually space for a node is generated after generating code for
  // its children. In case of root, generate the root tdb first.
  // This is done so that the start of the generated code space
  // could point to the root tdb. The tdb, however, is not initialized
  // yet.
  ComTdbRoot *root_tdb = new(space) ComTdbRoot();
  generator->initTdbFields(root_tdb);

  // tell the root tdb whether we collect statistics or not
  if (generator->computeStats())
    {
      root_tdb->setCollectStats(generator->computeStats());
      root_tdb->setCollectStatsType(generator->collectStatsType());
      root_tdb->setCollectRtsStats(generator->collectRtsStats());
    }

   

  //For consistent display of overflow_mode in stats.
  root_tdb->setOverflowMode(generator->getOverflowMode());

    // set the object for the top level fragment
  compFragDir->setTopObj((char *) root_tdb);

  // Copy the current context-wide TransMode,
  // then overlay with this stmt's "FOR xxx ACCESS" setting, if any.
  TransMode * transMode = new(space) TransMode();
  transMode->updateTransMode(generator->getTransMode());
  //
  if (accessOptions().accessType() != TransMode::ACCESS_TYPE_NOT_SPECIFIED_)
    {
      // "FOR xxx ACCESS" becomes an IsolationLevel, and both IL and AccessMode
      // are set in the transMode
      transMode->updateAccessModeFromIsolationLevel(
        TransMode::ATtoIL(accessOptions().accessType()));

      transMode->setStmtLevelAccessOptions();
    }
  else if ( ( generator->currentCmpContext()->internalCompile() == CmpContext::INTERNAL_MODULENAME) ||
            ( CmpCommon::statement()->isSMDRecompile() )
          )
    {
      // As a nicety to everyone writing a trusted .mdf (RFORK, etc),
      // we set this flag so that cli/Statement::execute() will not
      // recompile those trusted stmts due to any TransMode mismatch.
      // (Otherwise, everyone would need to add "FOR xxx ACCESS" to each stmt!)
      //
      transMode->setStmtLevelAccessOptions();
    }

  ex_expr * input_expr = 0;
  ex_expr * output_expr = 0;
  CollIndex i;

  ex_expr * pkey_expr = NULL;
  ULng32 pkey_len = 0;
  
  ex_expr* pred_expr = NULL;

  ULng32 cacheVarsSize = 0;
  //  unsigned long tablenameCacheVarsSize = 0;

  // max number of rows in user rowwise rowset.
  Lng32 rwrsMaxSize = 0;

  // index into the user params to find the value of the number of
  // actual rows in the rowwise rowset buffer.
  short rwrsInputSizeIndex = 0;

  // index into the user params to find the value of the max length
  // of each row in the user rowwise rowset buffer.
  short rwrsMaxInputRowlenIndex = 0;

  // index into the user params to find the value of the address
  // of rowwise rowset buffer in user space.
  short rwrsBufferAddrIndex = 0;

  // index into user params to find the value of the partition number
  // where this rwrs need to be shipped to.
  short rwrsPartnNumIndex = -1; // not specified

  // length of the each internal tuple where user's row will be moved in
  // at runtime.
  Lng32 rwrsMaxInternalRowlen = 0;

  RWRSInfo *rwrsInfo = NULL;
  char *rwrsInfoBuf = NULL;
  if (getHostArraysArea() && getHostArraysArea()->getRowwiseRowset())
    {
      rwrsInfo = (RWRSInfo *) new (space) char[sizeof(RWRSInfo)];

      rwrsInfoBuf = (char*)rwrsInfo;

      rwrsMaxSize = 
	(Lng32)((ConstValue*)getHostArraysArea()->rwrsMaxSize())->
	getExactNumericValue();

      NABoolean packedFormat      = FALSE;
      NABoolean compressed        = FALSE;
      NABoolean dcompressInMaster = FALSE;
      NABoolean compressInMaster  = FALSE;
      NABoolean partnNumInBuffer  = FALSE;
      getHostArraysArea()->getBufferAttributes(packedFormat,
					       compressed, dcompressInMaster,
					       compressInMaster,
					       partnNumInBuffer);
      rwrsInfo->setRWRSisCompressed(compressed);
      rwrsInfo->setDcompressInMaster(dcompressInMaster);
      rwrsInfo->setPartnNumInBuffer(partnNumInBuffer);
    }

  // inputVars() can contain multiple references to the same
  // param/hostvar value, if it is specified more than once in
  // a statement. (Seems like a bug to me, but no one is around
  // to fix it, so i will just work around it). The CharacteristicInputs
  // do not contain duplicate references. Use them to create a non-duplicate
  // newInputVars list.
  ValueIdList newInputVars, cacheVars, rwrsVars;
  NABoolean userInputVars = FALSE;
  short entry = 1;
  for (i = 0; i < inputVars().entries(); i++)
  {
    // CharacteristicInputs contains constants. Don't add
    // them as input. Add hostvar/params to map table, if not
    // already added. This will remove duplicates.
    // Add the non-duplicate input val-ids to the newInputVars list.
    ValueId val_id = inputVars()[i];
    ItemExpr * item_expr = val_id.getItemExpr();
    
    // We create a dummy host var in case it gets a value id from an
    // assignment in compound statements. Such variable will not need
    // to be processed by Cli since it gets its value inside the statement
    NABoolean blankHV = FALSE ;
    if (item_expr->previousHostVar()) {
      Int32 j = 0;
      for (j = 0; j < i; j++) {
	ItemExpr *ie = inputVars()[j].getItemExpr();
	if (ie->getOperatorType() == ITM_HOSTVAR) {
	  if (item_expr->previousName() == ((HostVar *) ie)->getName()) {
	    break;
	  }
	}
      }
      
      if (i == j) {
	NAString str1 = "previousHV__";
	char str2[30];
	str_itoa(i, str2);
	str1 += str2;
	item_expr = new(generator->wHeap()) HostVar(str1,
						    new(generator->wHeap()) SQLUnknown(generator->wHeap()));
	item_expr->bindNode(generator->getBindWA());
	blankHV = TRUE;
	val_id = item_expr->getValueId();
      }
    }
    
    OperatorTypeEnum op = item_expr->getOperatorType();
    
    if ((op == ITM_HOSTVAR) ||
	(op == ITM_DYN_PARAM)){
      userInputVars = TRUE;
      
      // Vicz: filter out the OUT HostVar/DynamicParam
      
      ComColumnDirection paramMode = item_expr->getParamMode();
      
      if(paramMode == COM_OUTPUT_COLUMN)
	continue;
      
    }
    
    // the list of operator types that was present here in R1.8 code in
    // almost equivalent to isAUserSuppliedInput()
    // except for Constant which cannot be handled here as its atpindex
    // should be 0 and not 2.
    // The num_tupps local variable just outside this IF will create
    // attributes with atpindex 2.
    // Constants are added later to the MapTable.
    if (((item_expr->isAUserSuppliedInput()) && // for evaluate once functions
	 (op != ITM_CONSTANT)) &&
	(! generator->getMapInfoAsIs(val_id))) // not added yet
      {
	MapInfo *map = generator->addMapInfoToThis(generator->getLastMapTable(),
						   val_id, NULL);
	
	// Transfer the information on rowsets that is in this host variable
	// into its attribute so we know this information at run time
	if (op == ITM_HOSTVAR || op == ITM_DYN_PARAM)
	  {
	    Attributes *attr = map->getAttr();
	    UInt32 rowsetInfo;
	    
	    if (op == ITM_HOSTVAR)
	      {
		HostVar *hv = (HostVar *) (val_id.getItemExpr());
		rowsetInfo = hv->getRowsetInfo();
		if (blankHV)
		  {
		    attr->setBlankHV();
		  }
	      }
	    else  // (op == ITM_DYN_PARAM)
	      {
		DynamicParam *dp = (DynamicParam *) (val_id.getItemExpr());
		rowsetInfo = dp->getRowsetInfo();

		if (dp->isDPRowsetForInputSize())
		  rwrsInputSizeIndex = entry;
		else if (dp->isRowwiseRowsetInputMaxRowlen())
		  rwrsMaxInputRowlenIndex = entry;
		else if (dp->isRowwiseRowsetInputBuffer())
		  rwrsBufferAddrIndex = entry;
		else if (dp->isRowwiseRowsetPartnNum())
		  rwrsPartnNumIndex = entry;
	      }
	    
	    attr->setRowsetInfo((Int16)rowsetInfo);
	  }
	
	if ((op == ITM_DYN_PARAM) &&
	    ((DynamicParam *)item_expr)->isRowInRowwiseRowset())
	  {
	    rwrsVars.insert(val_id);
	  }
	else if (op == ITM_CACHE_PARAM)
	  {
	    // This is a parameter generated by Query Caching
	    cacheVars.insert(val_id);
	  }
	else
	  {
	    newInputVars.insert(val_id);
	    entry++;
	  }
      }
  } // for
  
  Int32 num_tupps = 2; /* atp_index 0 for constants, 1 for temps */

  // create a row(tuple) with input param/hostvar values and pass
  // it to the child.
  // assign offset to elements in the input vars list.
  // Offsets are assigned in the input row tuple (atp index = 2).
  Attributes ** attrs = new(generator->wHeap())
	Attributes * [newInputVars.entries()];
  for (i = 0; i < newInputVars.entries(); i++)
    {
      attrs[i] = generator->addMapInfo(newInputVars[i], NULL)->getAttr();
    }

  ULng32 input_vars_size = 0;
  exp_gen->processAttributes(newInputVars.entries(), attrs,
			     ExpTupleDesc::SQLARK_EXPLODED_FORMAT,
			     input_vars_size, 0 /*atp*/, num_tupps/*atpIdx*/);

  //++Triggers,
  // Save the offsets of triggerStatus and UniqueExecuteId,
  // so ex_root_tcb can set it's value
  Lng32 triggersStatusOffset = -1;
  Lng32 uniqueExecuteIdOffset = -1;

  for (i = 0; i < newInputVars.entries(); i++)
    {
      ItemExpr * item_expr = (newInputVars)[i].getItemExpr();
      if (item_expr->getOperatorType() == ITM_UNIQUE_EXECUTE_ID)
	uniqueExecuteIdOffset = attrs[i]->getOffset();
      if (item_expr->getOperatorType() == ITM_GET_TRIGGERS_STATUS)
	{
	  GenAssert(getTriggersList()->entries()>0,
		    "No triggers, yet TriggerStatusOffset != -1");
	  triggersStatusOffset = attrs[i]->getOffset();
	}
    }
  
  //--Triggers,

  num_tupps += ((newInputVars.entries() > 0) ? 1 : 0); // plus 1 to hold the input
                                                      // params and hostvars.

  if (updateCurrentOf())
    {
      GenAssert(pkeyList().entries() > 0, "pkeyList().entries() must be > 0");

      // create a row(tuple) with pkey hostvar values and pass
      // it to the child.
      // assign offset to elements in the pkeyList.
      // Offset is assigned at atp index which one greater than where
      // the input num_tupps is.
      Attributes ** attrs = new(generator->wHeap())
	Attributes * [pkeyList().entries()];
      for (i = 0; i < pkeyList().entries(); i++)
	{
	  attrs[i] = generator->addMapInfo(pkeyList()[i], NULL)->getAttr();
	}

      exp_gen->processAttributes(pkeyList().entries(), attrs,
				 ExpTupleDesc::SQLARK_EXPLODED_FORMAT,
				 pkey_len,0/*atp*/,num_tupps/*atpIdx*/);
      num_tupps += 1;
    }

  // Process expressions generated by Query Caching.
  Attributes ** cachedAttrs = NULL;
  if (cacheVars.entries() > 0) {
    cachedAttrs = new(generator->wHeap())
	Attributes * [cacheVars.entries()];
    for (i = 0; i < cacheVars.entries(); i++)
    {
      cachedAttrs[i] = generator->addMapInfo(cacheVars[i], NULL)->getAttr();
    }

    exp_gen->processAttributes(cacheVars.entries(), cachedAttrs,
			       ExpTupleDesc::SQLARK_EXPLODED_FORMAT,
			       cacheVarsSize,0/*atp*/,num_tupps/*atpIdx*/);
    num_tupps += 1;
  }

  // Space needed for query caching. This is where the values of ConstantParameters
  // will go
  //  char *queryCacheParameterBuffer = (char *) new (space) char[cacheVarsSize];
  NABoolean qCacheInfoIsClass = FALSE;
  if (CmpCommon::getDefault(QUERY_CACHE_RUNTIME) == DF_ON)
    qCacheInfoIsClass = TRUE;

  char *parameterBuffer = (char *) new (space) char[cacheVarsSize];
  char *qCacheInfoBuf = NULL;
  if (qCacheInfoIsClass)
    {
      QCacheInfo *qCacheInfo =
	(QCacheInfo *) new (space) char[sizeof(QCacheInfo)];
      qCacheInfo->setParameterBuffer(parameterBuffer);
      qCacheInfoBuf = (char*)qCacheInfo;
    }
  else
    qCacheInfoBuf = parameterBuffer;

  // Check for reasons why the query plan should not be cached.
  // Note: This does not influence the use of cache parameters,
  // it's too late at this time to undo that.
  const LIST(CSEInfo *) *cseInfoList = CmpCommon::statement()->getCSEInfoList();

  if (cseInfoList &&
      CmpCommon::getDefault(CSE_CACHE_TEMP_QUERIES) == DF_OFF)
    for (CollIndex i=0; i<cseInfoList->entries(); i++)
      if (cseInfoList->at(i)->usesATempTable())
        generator->setNonCacheableCSEPlan(TRUE);

  // compute offsets for rwrs attrs. Offsets are computed separately
  // for rwrs vars since these values will be moved as part of input
  // row at runtime. This input row should only contain values which are
  // being inserted (ex, in the VALUES clause) and not any other input
  // values (like, input size, buffer, etc). 
  // If rwrs vars was included in newInputVars before computing
  // the offsets, then these offsets will also include the non-rwrs
  // vars which will not be correct.
  //
  // Do not assign any atp index at this time.
  // atp index will be determined at runtime
  // when the actual rows that are extracted from the rowset, 
  // processed and moved up the queue.
  Attributes ** rwrsAttrs = NULL;

  // next var is used if buffer need to be decompressed using the unicode
  // decoding alogorithm. 
  NABoolean useUnicodeDcompress = FALSE;

  if (rwrsVars.entries() > 0) 
    {
      rwrsAttrs = new(generator->wHeap())
	Attributes * [rwrsVars.entries()];
      for (i = 0; i < rwrsVars.entries(); i++)
	{
	  rwrsAttrs[i] = generator->addMapInfo(rwrsVars[i], NULL)->getAttr();

	  if (rwrsAttrs[i]->getCharSet() != CharInfo::ISO88591)
	    useUnicodeDcompress = TRUE;
	}
      
      // assign offsets.
      // No real atp index is to be assigned.
      // Cannot make it -1 as processAttrs doesn't like that.
      // Make atp index to be SHRT_MAX (out of reach).
      ULng32 len;
      exp_gen->processAttributes(rwrsVars.entries(), rwrsAttrs,
				 ExpTupleDesc::SQLARK_EXPLODED_FORMAT,
				 len, 
				 0/*atp*/, SHRT_MAX/*atpIdx*/);
      rwrsMaxInternalRowlen = len;
    }

  if (rwrsInfo)
    {
      rwrsInfo->setRwrsInfo(rwrsMaxSize, rwrsInputSizeIndex,
			    rwrsMaxInputRowlenIndex, rwrsBufferAddrIndex,
			    rwrsPartnNumIndex,
			    rwrsMaxInternalRowlen);

      if (rwrsInfo->rwrsIsCompressed())
	rwrsInfo->setUseUnicodeDcompress(useUnicodeDcompress);
    }

  // generate the input expression to move in hostvar/param values
  // from user area.
  // Include rwrs in newInputVars before generating the input expr
  // since we want all of these vars to be returned to the used when
  // they are 'described' at runtime.
  if ((newInputVars.entries() > 0) ||
      (rwrsVars.entries() > 0))
    {
      newInputVars.insert(rwrsVars);
      exp_gen->generateInputExpr(newInputVars, ex_expr::exp_INPUT_OUTPUT,
				 &input_expr);
    }

  ex_cri_desc * cri_desc = new(space) ex_cri_desc(num_tupps, space);
  generator->setCriDesc(cri_desc, Generator::DOWN);
  generator->setInputExpr((void *)input_expr);

  ExplainDesc *explainDesc = NULL;

  if(!generator->explainDisabled())
    {
      // Create a space object for the explain fragment
      if(generator->getExplainFragDirIndex() == NULL_COLL_INDEX)
	{
	  // Create an Explain Fragment
	  generator->setExplainFragDirIndex(
	       generator->getFragmentDir()->pushFragment(FragmentDir::EXPLAIN,0));
	  generator->getFragmentDir()->popFragment();
	}

      ExplainFunc explainFunc;
      TrafDesc *explainDescStruct = explainFunc.createVirtualTableDesc();

      Space *explainSpace = generator->getFragmentDir()->
	getSpace(generator->getExplainFragDirIndex());

      TrafTableDesc *tableDesc = explainDescStruct->tableDesc();

      // Determine the length of the Explain Tuple.
      Lng32 recLength = tableDesc->record_length;

      // Determine the number of columns in the Explain Tuple.
      Lng32 numCols = tableDesc->colcount;

      explainDesc =
	new(explainSpace) ExplainDesc(numCols, recLength, explainSpace);

      TrafDesc *cols = tableDesc->columns_desc;

      // For each column of the Virtual Explain Table, extract the
      // relevant info. from the table desc and put it into the ExplainDesc
      for(Int32 c = 0; c < numCols; c++ /* no pun intended */)
	{
	  TrafColumnsDesc *colsDesc = (cols->columnsDesc());

	  explainDesc->setColDescr(c,
				   colsDesc->datatype,
				   colsDesc->length,
				   colsDesc->offset,
				   colsDesc->isNullable());

	  cols = cols->next;
	}

      explainFunc.deleteVirtualTableDesc(explainDescStruct);

      compFragDir->setTopObj(generator->getExplainFragDirIndex(),
			     (char *)explainDesc);
    }

  // Take note of whether this is a parallel extract query before
  // generating the child tree.
  NABoolean isExtractProducer = (numExtractStreams_ > 0 ? TRUE : FALSE);
  NABoolean isExtractConsumer =
    (childOperType() == REL_EXTRACT_SOURCE ? TRUE : FALSE);

  // the tree below needs to know if this is a LRU operation, hence
  // make this check before the children are codeGened.
  if (containsLRU())
  {
    generator->setLRUOperation(TRUE);
  }
  if (getTolerateNonFatalError() == RelExpr::NOT_ATOMIC_) 
  {
    generator->setTolerateNonFatalError(TRUE);
  }

  // Copy #BMOs value from Root node into the fragment
  compFragDir->setNumBMOs(myFragmentId, getNumBMOs());
  compFragDir->setBMOsMemoryUsage(myFragmentId, getBMOsMemoryUsage().value());

  // generate child tree
  child(0)->codeGen(generator);
  ComTdb * child_tdb = (ComTdb *)(generator->getGenObj());
  if (child_tdb == (ComTdb *)NULL)
      childTdbIsNull = TRUE;


  // Remap the allocation of ESPs to Nodes/CPUs.
  if (ActiveSchemaDB()->getDefaults().getAsLong(AFFINITY_VALUE) == -2)
     generator->remapESPAllocationRandomly();
  else
     generator->remapESPAllocationAS();

  generator->compilerStatsInfo().affinityNumber()
    = generator->getAffinityValueUsed();

  // if an output expression is present, generate it.
  if (compExpr_.entries() > 0)
  {
    // Special cases to consider are
    // * stored procedure result sets
    // * parallel extract consumers
    // 
    // In these plans we want special table and column names in the
    // output expression. The names will come from the root's child
    // node and be pointed to by these two variables. For all other
    // ("normal") statements, these two pointers will remain NULL.
    //
    ConstNAStringPtr *colNamesForExpr = NULL;
    ConstQualifiedNamePtr *tblNamesForExpr = NULL;

    OperatorTypeEnum childType =
      child(0)->castToRelExpr()->getOperatorType();

    ComUInt32 numColumns = getRETDesc()->getDegree();

    if ((childType == REL_SP_PROXY || isExtractConsumer) &&
        numColumns > 0)
    {
      ProxyFunc *proxy;

      if (childType == REL_SP_PROXY)
      {
        // This is a stored procedure result set
        proxy = (ProxyFunc *) child(0)->castToRelExpr();
      }
      else
      {
        // This is an extract consumer. The extract operator is not
        // the direct child of the root. An exchange operator sits
        // between the two.
        GenAssert(childType == REL_EXCHANGE,
                  "Child of root should be exchange for consumer query");
        GenAssert(child(0)->child(0),
                  "Child of root should not be a leaf for consumer query");
                  
        OperatorTypeEnum grandChildType = 
          child(0)->child(0)->castToRelExpr()->getOperatorType();

        GenAssert(grandChildType == REL_EXTRACT_SOURCE,
                  "Grandchild of root has unexpected type for consumer query");

        proxy = (ProxyFunc *) child(0)->child(0)->castToRelExpr();
      }

      // Populate the table and column name collections that will be
      // used below to generate the output expression.
      colNamesForExpr = new (generator->wHeap())
        ConstNAStringPtr[numColumns];
      tblNamesForExpr = new (generator->wHeap())
        ConstQualifiedNamePtr[numColumns];

      for (ComUInt32 i = 0; i < numColumns; i++)
      {
        colNamesForExpr[i] = proxy->getColumnNameForDescriptor(i);
        tblNamesForExpr[i] = proxy->getTableNameForDescriptor(i);
      }
    }

    exp_gen->generateOutputExpr(compExpr_,
                                ex_expr::exp_INPUT_OUTPUT,
                                &output_expr,
                                getRETDesc(), 
                                getSpOutParams(),
                                colNamesForExpr,
                                tblNamesForExpr);
  }

  if (getPredExprTree())
    {
      //      ItemExpr * newPredTree = executorPred().rebuildExprTree(ITM_AND,TRUE,TRUE);
      exp_gen->generateExpr(getPredExprTree()->getValueId(), ex_expr::exp_SCAN_PRED,
			    &pred_expr);
    }

  // if child's primary key columns are to be returned to be passed
  // on to UPDATE WHERE CURRENT OF query, generate an
  // expression to compute the pkey row.
  ex_cri_desc * work_cri_desc = NULL;

  if (updatableSelect() == TRUE)
    {
      GenAssert(pkeyList().entries() > 0, "pkeyList().entries() must be > 0");

      work_cri_desc = new(space) ex_cri_desc(3, space);

      exp_gen->generateContiguousMoveExpr(pkeyList(),
					  1, // add convert nodes,
					  1, 2,
					  ExpTupleDesc::SQLARK_EXPLODED_FORMAT,
					  pkey_len, &pkey_expr,
					  NULL, ExpTupleDesc::SHORT_FORMAT);
    }

  // if this is an 'update where current of' query, pass in
  // the fetched cursor name or hvar number root tdb.
  char * fetchedCursorName = NULL;
  short  fetchedCursorHvar = -1;
  if (updateCurrentOf())
    {
      if (currOfCursorName_->getOperatorType() == ITM_CONSTANT)
	{
	  // cursor name is specified as a literal
	  NABoolean tv;
	  ConstValue * cv = currOfCursorName_->castToConstValue(tv);

	  fetchedCursorName =
	    space->allocateAndCopyToAlignedSpace((char *)(cv->getConstValue()),
						 cv->getStorageSize(),
						 0);
	}
      else
	{
	  // cursor name was specified as a hvar
	  HostVar * cursorHvar = (HostVar *)currOfCursorName_;

	  // search for this hostvar in the input hvar list
	  for (i = 0; i < inputVars().entries(); i++)
	    {
	      ValueId val_id = inputVars()[i];
	      if (cursorHvar->getOperatorType() == ITM_HOSTVAR)
		{
		  HostVar * hv = (HostVar *)(val_id.getItemExpr());

		  if (hv->getName() == cursorHvar->getName())
		    fetchedCursorHvar = (short)i+1; // 1-based
		}
	    } // more input

	} // cursor name is in a hvar
    }

  // Create a list of update columns for UPDATE CURRENT OF or updateable
  // SELECT statements (cursors). For UPDATE CURRENT OF, the update columns
  // are obtained from the GenericUpate Node. For cursors, the update columns
  // are obtained from this (RelRoot) node.
  Lng32 numUpdateCol = 0;
  Lng32 *updateColList = NULL;

  if (updateCurrentOf()) // UPDATE/DELETE ... where CURRENT OF query.
  {
    GenAssert(updateCol().entries() == 0,
              "UPDATE CURRENT OF: updateCol non-zero");

    // Get the update node.
    GenericUpdate *update = (GenericUpdate*)generator->updateCurrentOfRel();

    GenAssert(update != NULL, "UPDATE CURRENT OF: NULL update node");

    /*
    // create the update col list for UPDATE...WHERE CURRENT OF CURSOR only.
    // The updateCurrentOf() is set for both UPDATE and DELETE queries.
    if ((update->getOperatorType() == REL_DP2_UPDATE_CURSOR) ||
	(update->getOperatorType() == REL_DP2_UPDATE_UNIQUE))
      {
	// Get the list of assignment expressions from the STOI of the
	// update node.
        SqlTableOpenInfo *updateStoi = update->getOptStoi()->getStoi();

	// Allocate an array for the column list.
	numUpdateCol = updateStoi->getColumnListCount();

	GenAssert(numUpdateCol > 0,
                  "UPDATE CURRENT OF: No update columns");

	updateColList = new(space) Lng32[numUpdateCol];

	// Populate the array with the update columns from the left side
	// of each expression which is a column.
	for (i = 0; (Lng32)i < numUpdateCol; i++)
	  {
            updateColList[i] = updateStoi->getUpdateColumn(i);
	  }
      } // update...where current of.
    */
  }
  else if (updatableSelect())
    {
      numUpdateCol = updateCol().entries();
      
      if (numUpdateCol > 0)
        {
          // Allocate an array for the column list.
      updateColList = new(space) Lng32[numUpdateCol];

      // Populate the array with the update columns of this node.
      for (i = 0; (Lng32)i < numUpdateCol; i++)
      {
        ValueId val_id = updateCol()[i];
        GenAssert(val_id.getItemExpr()->getOperatorType() == ITM_BASECOLUMN,
                  "UpdateCol should be BaseColumn");
        BaseColumn *col = (BaseColumn*)val_id.getItemExpr();
        updateColList[i] = col->getColNumber();
      }
    }
    else
    {
      // All columns are updateable.
      numUpdateCol = -1;
    }
  }

  // copy all the tables open information into the generator space
  // and pass it to the root tdb, which is used to check the
  // security when opening the sql tables or views.
  short noOfTables = (short) generator->getSqlTableOpenInfoList().entries();
  SqlTableOpenInfo **stoiList;
  stoiList = new (space) SqlTableOpenInfo*[noOfTables];
  
  // The Executor Statement class has logic to retry blown away
  // opens on some statements. We can safely do so if we know that
  // disk has not been dirtied, and no rows have been returned
  // to the application.

  // The Executor can deduce this if the blown away open occurs
  // on the first input row, and if the plan writes to at most
  // one object. This follows because an open can be blown away
  // only if no locks are held on any partition of the object.

  // The two variables below are used to compute if the plan
  // accesses more than one object. If not, and if the query is
  // an IUD, we will flag the root tdb as retryable.

  NABoolean moreThanOneTable = FALSE;
  char *firstTable = NULL;

  // ++ Triggers
  // While copying the stoi info, make sure the subjectTable flag is
  // not set more than once for the same table ansi name
  LIST(NAString) *subjectTables = NULL;
  if (getTriggersList())
    subjectTables = new (generator->wHeap())
      LIST(NAString) (generator->wHeap());
  short j=0;

  for (; j < noOfTables; j++)
  {
    stoiList[j] = new (space) SqlTableOpenInfo;
    SqlTableOpenInfo * genStoi =
		(SqlTableOpenInfo *)generator->getSqlTableOpenInfoList()[j];
    *(stoiList[j]) = *genStoi;

    if (moreThanOneTable)
    {
      // No need to check any further.
    }
    else
    {
      if (firstTable == NULL)
      {
        firstTable = genStoi->fileName();
      }
      else if (stricmp( firstTable, genStoi->fileName()))
      {
        // there is more than one distinct object name in the Stoi list
        moreThanOneTable = TRUE;
      }
    }
    stoiList[j]->setFileName(new (space) char[strlen(genStoi->fileName()) + 1]);
    strcpy(stoiList[j]->fileName(), genStoi->fileName());

    stoiList[j]->setAnsiName(new (space) char[strlen(genStoi->ansiName()) + 1]);
    strcpy(stoiList[j]->nonConstAnsiName(), genStoi->ansiName());

    // -- Triggers
    // Prevent duplicate entries for the same subject table
    // and entries for views
    NAString const ansiName(genStoi->ansiName(), generator->wHeap());
    if (genStoi->subjectTable() && subjectTables &&
	!(subjectTables->contains(ansiName)) && !genStoi->isView())
    {
      stoiList[j]->setSubjectTable(TRUE);
      subjectTables->insert(ansiName);
    }
    else
      stoiList[j]->setSubjectTable(FALSE);

    if (genStoi->getColumnListCount())
    {
      stoiList[j]->setColumnList(new (space)
                     short[genStoi->getColumnListCount()]);
      for (short k = 0; k < genStoi->getColumnListCount(); k++)
      {
        stoiList[j]->setUpdateColumn(k,genStoi->getUpdateColumn(k));
      }
    }
  }

  // copy the triggers list into the generator space
  // and pass it to the root tdb, where it is used to check the
  // enable/disable status of triggers.
  short triggersCount = 0;
  ComTimestamp *triggersList = NULL;
  if (getTriggersList())
  {
    GenAssert(subjectTables && (subjectTables->entries() > 0),
	      "Mismatch: Triggers without Subject Tables");
    delete subjectTables;
    subjectTables = NULL;

    triggersCount = (short) getTriggersList()->entries();
    triggersList = new (space) ComTimestamp[triggersCount];

    for (short k=0; k < triggersCount; k++)
      triggersList[k] = getTriggersList()->at(k);
  }

  // copy uninitializedMvList into generator space 
  // to pass to root tdb  
  UninitializedMvName *newMvList = NULL; 
  short uninitializedMvCount = 0;  
  
  if (uninitializedMvList_) 
  {            
      uninitializedMvCount = (short)uninitializedMvList_->entries();
      if( uninitializedMvCount != 0 )
      {
          newMvList = new (space) UninitializedMvName[uninitializedMvCount];
          for( short i = 0; i < uninitializedMvCount; i++ )
          {          
              UninitializedMvName *pMvName = uninitializedMvList_->at(i);

              GenAssert( pMvName, "UninitializedMvName is invalid." );

              newMvList[i].setPhysicalName( pMvName->getPhysicalName() );
              newMvList[i].setAnsiName( pMvName->getAnsiName() );                            
          }
      }
  } 


  // if there were any views referenced in the query, copy the stoi
  // to root tdb. This is used at runtime to check for existence.
  Queue * viewStoiList = NULL;
  if (getViewStoiList().entries() > 0)
    {
      for (CollIndex i = 0; i < getViewStoiList().entries(); i++)
	{

	  if (! viewStoiList)
	    viewStoiList = new(space) Queue(space);

	  SqlTableOpenInfo * stoi = new(space) SqlTableOpenInfo;
	  *stoi = *getViewStoiList()[i]->getStoi();

	  stoi->setFileName(
	    new(space)  char[strlen(getViewStoiList()[i]->getStoi()->fileName()) + 1]);
	  strcpy(stoi->fileName(), getViewStoiList()[i]->getStoi()->fileName());

	  stoi->setAnsiName(
	    new(space)  char[strlen(getViewStoiList()[i]->getStoi()->ansiName()) + 1]);
	  strcpy(stoi->nonConstAnsiName(), getViewStoiList()[i]->getStoi()->ansiName());

          if (getViewStoiList()[i]->getStoi()->getColumnListCount())
	  {
	    stoi->setColumnList(new (space)
	      short[getViewStoiList()[i]->getStoi()->getColumnListCount()]);
	    for (short k = 0; k < getViewStoiList()[i]->getStoi()->getColumnListCount(); k++)
	      {
		stoi->setUpdateColumn(k,getViewStoiList()[i]->getStoi()->getUpdateColumn(k));
	      }
	  }

	  if (CmpCommon::getDefault(VALIDATE_VIEWS_AT_OPEN_TIME) == DF_ON)
	    stoi->setValidateViewsAtOpenTime(TRUE);
          else
            stoi->setValidateViewsAtOpenTime(FALSE);

	  viewStoiList->insert(stoi);

	  // if this view name was used as a variable(hvar, envvar or define),
	  // then add it to the latename info list.
	  HostVar * hv = getViewStoiList()[i]->getCorrName().getPrototype();
	  if (hv != NULL)
	    {
	      LateNameInfo* lateNameInfo = new(generator->wHeap()) LateNameInfo();

	      char * varName;
	      GenAssert(hv->getName().data(), "Hostvar pointer must have name");

	      lateNameInfo->setEnvVar(hv->isEnvVar());

	      lateNameInfo->setCachedParam(hv->isCachedParam());

	      varName = convertNAString(hv->getName(), generator->wHeap());
	      strcpy(lateNameInfo->variableName(), varName);

	      char * prototypeValue =  convertNAString(hv->getPrototypeValue(),
						       generator->wHeap());
	      char * compileTimeAnsiName = prototypeValue;
	      lateNameInfo->setVariable(1);

	      lateNameInfo->setView(1);

              lateNameInfo->setCompileTimeName(compileTimeAnsiName, space);
	      lateNameInfo->setLastUsedName(compileTimeAnsiName, space);
	      lateNameInfo->setNameSpace(COM_TABLE_NAME);

	      lateNameInfo->setInputListIndex(-1);

	      generator->addLateNameInfo(lateNameInfo);

	    } // hv
	} // for
    }

  // UDR Security
  short noOfUdrs = generator->getBindWA()->getUdrStoiList().entries ();

  SqlTableOpenInfo **udrStoiList = NULL;
  if ( noOfUdrs )
  {
    udrStoiList = new (space) SqlTableOpenInfo*[noOfUdrs];
    BindWA *bindWA = generator->getBindWA ();

    for (short udrIdx=0; udrIdx < noOfUdrs; udrIdx++)
    {
      udrStoiList[udrIdx] = new (space) SqlTableOpenInfo;
      SqlTableOpenInfo *genUdrStoi =
       (SqlTableOpenInfo *)bindWA->getUdrStoiList()[udrIdx]->getUdrStoi();

      *(udrStoiList[udrIdx]) = *genUdrStoi;

      udrStoiList[udrIdx]->setAnsiName(
			 new (space)  char[strlen(genUdrStoi->ansiName()) + 1]
				      );
      strcpy(udrStoiList[udrIdx]->nonConstAnsiName(), genUdrStoi->ansiName());
    }
  }

  // setting transaction type flags in the transmode object
  // Determines what type of transaction will be started for this statement,
  // if autocommit is ON.

  // setting accessMode to read_write if it was set to read_only by MX.
  // if isolation_level is read_uncommitted we set accessmode to read only
  // This causes trouble when we try to do DDL or IUD so we are resetting
  // accessMode here. From here on accesMode is used only to start the transaction
  if ((transMode->accessMode() == TransMode::READ_ONLY_) &&
      (generator->needsReadWriteTransaction()))
	transMode->accessMode() = TransMode::READ_WRITE_ ;


  if (generator->withNoRollbackUsed() ||
      (transMode->getRollbackMode() == TransMode::NO_ROLLBACK_))
  {
      if (generator->withNoRollbackUsed())
        transMode->rollbackMode() = TransMode::NO_ROLLBACK_IN_IUD_STATEMENT_ ;

      //      if (childOperType().match(REL_ANY_GEN_UPDATE))
      //        generator->setAqrEnabled(FALSE);

      // AIInterval is set to don't abort (i.e. 0). 
      // A setting of -2 is equivalent to a setting of 0 but has the additional meaning
      // that it will never be overriden by the executor.
      if (transMode->getAutoAbortIntervalInSeconds() == -1)
        transMode->autoAbortIntervalInSeconds() = -2;
  }
  else if ((NOT generator->needsReadWriteTransaction()) &&
	    transMode->accessMode() != TransMode::READ_ONLY_SPECIFIED_BY_USER_ &&
	    containsLRU() == FALSE &&
	    updatableSelect() == FALSE)
  {
    transMode->accessMode() = TransMode::READ_ONLY_ ;
  }

  if (transMode->getAutoAbortIntervalInSeconds() == -1)
  {
      if (transMode->accessMode() == TransMode::READ_ONLY_SPECIFIED_BY_USER_)
	transMode->autoAbortIntervalInSeconds() = -2;
      else if (transMode->accessMode() == TransMode::READ_ONLY_)
	transMode->autoAbortIntervalInSeconds() = 0;
  }

  // create the latename info List to be passed on to root_tdb.
  LateNameInfoList * lnil = NULL;
  Int32 numEntries = 0;
  if  (generator->getLateNameInfoList().entries() > 0)
    numEntries = generator->getLateNameInfoList().entries();
  lnil =
    (LateNameInfoList *)
      space->allocateMemory( sizeof(LateNameInfoList) +
                             (numEntries * sizeof(LateNameInfo)) );

  // Initialize LNIL from real LNIL object (this copies vtblptr into lnil).
  LateNameInfoList lnild;
  memcpy((char *)lnil,&lnild,sizeof(LateNameInfoList));

  lnil->setNumEntries(generator->getLateNameInfoList().entries());

  // This allocates an array of 64-bit pointers in lnil.
  lnil->allocateList(space,numEntries);

  // This sets up the array elements to point to the LateNameInfo objects.
  for (j = 0; j < numEntries; j++)
    lnil->setLateNameInfo(j,((LateNameInfo *)(lnil + 1)) + j);

  NABoolean viewPresent = FALSE;
  NABoolean variablePresent = FALSE;

  // olt opt is only done for tablenames which are literals
  NABoolean doTablenameOltOpt = TRUE;
  if  (generator->getLateNameInfoList().entries() > 0)
    {
      for (CollIndex i = 0;
	   i < generator->getLateNameInfoList().entries(); i++)
	{
	  LateNameInfo * tgt = &(lnil->getLateNameInfo(i));
	  LateNameInfo * src = (LateNameInfo *)generator->getLateNameInfoList()[i];
	  if (src->isVariable())
	    {
              doTablenameOltOpt = FALSE;
	    }

	  // *tgt = *src wouldn't work since it doesn't copy over the vtblptr.
	  memmove(tgt,src,sizeof(LateNameInfo));
	  // find the position of this hostvar in input var list.
	  if ((src->isVariable()) && (! src->isEnvVar()))
	    {
	      if (tgt->isCachedParam())
		{
		  tgt->setCachedParamOffset((Lng32)cachedAttrs[tgt->getInputListIndex()-1]->getOffset());
		}
	      else
		{
		  NABoolean found = FALSE;
		  for (CollIndex i = 0; ((i < newInputVars.entries()) && (! found)); i++)
		    {
		      ValueId val_id = newInputVars[i];
		      ItemExpr * item_expr = val_id.getItemExpr();
		      if (item_expr->getOperatorType() == ITM_HOSTVAR)
			{
			  HostVar * inputHV = (HostVar *)item_expr;
			  if ((inputHV->getName().length() == strlen(src->variableName())) &&
			      (strcmp(inputHV->getName().data(), src->variableName()) == 0))
			    {
			      found = TRUE;
			      tgt->setInputListIndex((short)(i+1));
			    }
			} // hostvar in input list
		    } // for

		  if (! found)
		    GenAssert(0, "Must find prototype hvar in input hvar");
		}
	    } // not an env var or a define.

      if (tgt->compileTimeAnsiName()[0] == '\\')
        {
	  if (NOT tgt->isVariable())
	    {
              tgt->setAnsiPhySame(TRUE);
	    }
	  else
	    {
	      if (tgt->isEnvVar())
		tgt->setAnsiPhySame(TRUE);
	      else
		{
		  // hostvar
		  // If prototype is a fully qualified name, then
		  // ansi-phy names are the same.
		  if (tgt->compileTimeAnsiName()[0] == '\\')
		    tgt->setAnsiPhySame(TRUE);
		};
	    }
        }
      else
        {
	  if (tgt->isVariable())
	    {
	      QualifiedName qn(tgt->compileTimeAnsiName(), 1,
			       generator->wHeap(),
			       generator->getBindWA());
	      qn.applyDefaults(generator->currentCmpContext()->schemaDB_->getDefaultSchema());
	      char * compileTimeAnsiName = space->AllocateAndCopyToAlignedSpace(
		   qn.getQualifiedNameAsAnsiString(), 0);
              tgt->setCompileTimeName(compileTimeAnsiName, space);
	    }
	} // else
      
      if (tgt->isView())
	viewPresent = TRUE;
      
      if (tgt->isVariable())
	variablePresent = TRUE;

      if (tgt->lastUsedAnsiName()[0] != '\0')
      {
	// VO, Metadata Indexes
	if (tgt->getNameSpace() == COM_INDEX_NAME)
	  // This lni is for an index - don't copy the compile time ansi name if the
	  // query is from a system module
	  if ( (generator->currentCmpContext()->internalCompile() != CmpContext::INTERNAL_MODULENAME) &&
	       !CmpCommon::statement()->isSMDRecompile() )
	    tgt->setLastUsedName(tgt->compileTimeAnsiName(),space);
      }

      // Special handling for case where we are recompiling a system module 
      // query. We need to resolve the name here since it will not go 
      // through the resolveNames in the CLI. Do this only for NSK
	} // for
    }

  lnil->setViewPresent(viewPresent);

  lnil->setVariablePresent(variablePresent);

  // Generate info to do similarity check.
  TrafQuerySimilarityInfo * qsi = genSimilarityInfo(generator);

  // generate the executor fragment directory <exFragDir> (list of all
  // fragments of the plan that are executed locally or are downloaded
  // to DP2 or to ESPs) from the generator's copy <compFragDir> and attach
  // it to the root_tdb
  NABoolean fragmentQuotas = CmpCommon::getDefault(ESP_MULTI_FRAGMENTS) == DF_ON;
  ExFragDir *exFragDir =
    new(space) ExFragDir(compFragDir->entries(),space,
                         CmpCommon::getDefault(ESP_MULTI_FRAGMENTS) == DF_ON, 
                         fragmentQuotas, 
                         (UInt16)CmpCommon::getDefaultLong(ESP_MULTI_FRAGMENT_QUOTA_VM),
                           (UInt8)CmpCommon::getDefaultLong(ESP_NUM_FRAGMENTS));

  // We compute the space needed in execution time for input Rowset variables
  for (i = 0; i < inputVars().entries(); i++)
  {
      ValueId val_id = inputVars()[i];
      ItemExpr * item_expr = val_id.getItemExpr();
      OperatorTypeEnum op = item_expr->getOperatorType();
      if (op == ITM_HOSTVAR) {
        HostVar *hostVar = (HostVar *) item_expr;
        if (hostVar->getType()->getTypeQualifier() == NA_ROWSET_TYPE) {
          Lng32 thisSize = hostVar->getType()->getTotalSize();
          input_vars_size += thisSize;
        }
      }
  }

  // find out if this is a delete where current of query.
  NABoolean delCurrOf = FALSE;
  short baseTablenamePosition = -1;
  if (fetchedCursorName || (fetchedCursorHvar >= 0)) // upd/del curr of
    {
      if (childOperType() == REL_UNARY_DELETE)
	delCurrOf = TRUE;
      else
	delCurrOf = FALSE;
    }

  // The ansi names of the table specified in the cursor stmt must match
  // the name specified in the upd/del where curr of stmt. This check
  // is done at runtime.
  // basetablenameposition is the index in the latenameinfolist of
  // the entry whose lastUsedAnsiName contains the name of the table.
  baseTablenamePosition = -1;
  if (updatableSelect())
    {
      // if this is an updatable select, find the ansi name of the basetable.
      // This name will be used at runtime to compare to the tablename
      // specified in an 'upd/del where current of' stmt. The two tablenames
      // must be the same.
      for (Int32 n = 0; n < noOfTables; n++)
	{
	  SqlTableOpenInfo * stoi = stoiList[n];

	  if (NOT stoi->isIndex())
	    {
	      if (baseTablenamePosition == -1)
		{
		  baseTablenamePosition = n;
		}
	    }
	}
      if (baseTablenamePosition == -1)
	{
	  // no base table access used. Only index access is used.
	  // The ansiname field in latenameInfo struct is the ansi name
	  // of the base table. Use that.
	  baseTablenamePosition = 0;
	}
    }
  else if (updateCurrentOf())
    {
      // if this is an update/delete current of query, find the index of
      // the base table. There might be other tables used in the plan
      // for index maintanence and they will either be indices or
      // specialTables with the special type being an INDEX_TABLE.
      // Look only for the true base tables.
      for (Int32 n = 0; n < noOfTables; n++)
	{
	  SqlTableOpenInfo * stoi = stoiList[n];

	  if ((NOT stoi->isIndex()) &&
	      (NOT stoi->specialTable()) &&
              (stoi->getUpdateAccess() ||
               stoi->getDeleteAccess() ))
	    {
	      if (baseTablenamePosition == -1)
		{
		  baseTablenamePosition = n;
		}
	    }
	}

      if (baseTablenamePosition == -1)
	{
	  // No base table found in the stoi list.
	  // Raise an error.
	  GenAssert(0, "Must find updelTableNamePosition!");
	}
    }

  // find out if this was an update,delete or insert query.
  NABoolean updDelInsert = FALSE;
  if (childOperType().match(REL_ANY_GEN_UPDATE))
    updDelInsert = TRUE;

  // Do OLT optimization if:
  //  -- OLT optimization is possible
  //  -- and no upd/del where current of
  //  -- and no late name resolution
  //  -- and no views in query
  NABoolean doOltQryOpt = FALSE;
  if ((oltOptInfo().oltCliOpt()) &&
      (viewStoiList == NULL) &&          // no views
      (doTablenameOltOpt == TRUE) &&                  // no late name info
      (fetchedCursorName == NULL) &&     // no upd/del curr of
      (fetchedCursorHvar < 0) &&
      (delCurrOf == FALSE) &&
      (getFirstNRows() == -1))          // no firstn specified
    {
      doOltQryOpt = TRUE;
    }

  // At runtime, we try to internally reexecute a statement in case of
  // lost opens, if that query has not affected the database(inserted/updated/
  // deleted a row), or a row has not been returned to the application.
  // Do not retry for lost opens of IUD queries if there are more
  // than one tables in the query. This is because we don't know if the db
  // was affected when the open was lost on the non-IUD table in the query.
  // For ex: in an insert...select query, an open could be blown away for
  // the select part of the query.
  // If there is only one table in this query, then that row will get locked
  // during IUD and the open could not be blown away.
  // If some day we put in a scheme to detect that the database
  // was not affected for a multi-table IUD, we can retry for lost
  // opens.
  NABoolean retryableStmt = TRUE;

  if (generator->aqrEnabled())
    {
      retryableStmt = FALSE;
    }

  if (updDelInsert && moreThanOneTable)
    retryableStmt = FALSE;

  if (childOperType() == REL_DDL)
    retryableStmt = FALSE;

  if (isExtractProducer || isExtractConsumer)
    retryableStmt = FALSE;

  // For now we mark statements containing UDRs as non-retryable.
  // This is to avoid executing a stored procedure body multiple times
  // inside a single application request. Currently the only UDR-
  // containing statment is CALL.
  //
  // There are scenarios however in which it would be correct (and
  // helpful) to retry a UDR-containing statement. Perhaps in the
  // future the restriction can be lifted in some cases.  Safe retry
  // scenarios include a subquery input parameter returning a blown
  // away open error before the stored procedure body has executed,
  // and UDR bodies that only do computation and not transactional work.
  if (noOfUdrs > 0)
    retryableStmt = FALSE;

  short maxResultSets = generator->getBindWA()->getMaxResultSets();

  char *queryCostInfoBuf = NULL;
  QueryCostInfo *queryCostInfo =
    (QueryCostInfo *) new (space) char[sizeof(QueryCostInfo)];
  // fill in cost. Taken from explain code in GenExplain.cpp
  if (getRollUpCost())
    {
      double cpu, io, msg, idle, seqIOs, randIOs, total, cardinality;
      double totalMemPerCpu, totalMemPerCpuInKB;
      short maxCpuUsage;
      Lng32 dummy;
      Cost const *operatorCost = getRollUpCost();
      const NABoolean inMaster = generator->getEspLevel() == 0;
      operatorCost->getExternalCostAttr(cpu, io, msg, idle, seqIOs, randIOs, total, dummy);
//      operatorCost->getOcmCostAttr(cpu, io, msg, idle, dummy);
//      total = MINOF(operatorCost->convertToElapsedTime(), 1e32).getValue();

      cardinality = MINOF(getEstRowsUsed(), 1e32).value();

      // get the totalMem that is being used divide by max dop to get an 
      // an estimate of memory usage per cpu. Convert to KB units.
      totalMemPerCpu = 
	generator->getTotalEstimatedMemory() /
	((generator->compilerStatsInfo().dop() > 0) ? 
	 generator->compilerStatsInfo().dop() : 1);
      totalMemPerCpuInKB = totalMemPerCpu / 1024 ;
      maxCpuUsage = generator->getMaxCpuUsage() ;
      queryCostInfo->setCostInfo(cpu, io, msg, idle, seqIOs, randIOs, total,
                                 cardinality, totalMemPerCpuInKB, maxCpuUsage);

      // if resourceUsage need to be set (low/medium/high), set it here.
      // For now, set to 0 which indicates that this value is not 
      // being returned.
      queryCostInfo->setResourceUsage(0);
    }
  
  queryCostInfoBuf = (char*)queryCostInfo;
  //
  // CompilationStatsData  
  CompilationStats* stats = CURRENTSTMT->getCompilationStats();
  char *compilerId = new (space) char[COMPILER_ID_LEN];
  str_cpy_all(compilerId, generator->currentCmpContext()->getCompilerId(),
              COMPILER_ID_LEN);
  Int32 cLen = stats->getCompileInfoLen();
  //
  // make it 1 at minimum
  cLen = ( cLen < 1 ) ? 1 : cLen;

  char *compileInfo = new (space) char[cLen];
  stats->getCompileInfo(compileInfo);      
  //
  // Some of the fields are set here but modified later after generator phase is
  // complete (such as compileEndTime, CMP_PHASE_ALL, and CMP_PHASE_GENERATOR)
  CompilationStatsData *compilationStatsData =
    (CompilationStatsData *) new (space) 
        CompilationStatsData(stats->compileStartTime(),
            stats->compileEndTime(),  
            compilerId, 
            stats->cmpPhaseLength(CompilationStats::CMP_PHASE_ALL),
            stats->cmpPhaseLength(CompilationStats::CMP_PHASE_BINDER),
            stats->cmpPhaseLength(CompilationStats::CMP_PHASE_NORMALIZER),
            stats->cmpPhaseLength(CompilationStats::CMP_PHASE_ANALYZER),
            stats->cmpPhaseLength(CompilationStats::CMP_PHASE_OPTIMIZER),
            stats->cmpPhaseLength(CompilationStats::CMP_PHASE_GENERATOR), 
            stats->metadataCacheHits(),
            stats->metadataCacheLookups(),
            stats->getQueryCacheState(),
            stats->histogramCacheHits(),
            stats->histogramCacheLookups(),
            stats->stmtHeapCurrentSize(),
            stats->cxtHeapCurrentSize(),
            stats->optimizationTasks(),
            stats->optimizationContexts(),
            stats->isRecompile(),
            compileInfo,
            stats->getCompileInfoLen());  
  //
  // CompilerStats 
  char *compilerStatsInfoBuf = NULL;
  CompilerStatsInfo *compilerStatsInfo =
    (CompilerStatsInfo *) new (space) char[sizeof(CompilerStatsInfo)];
  compilerStatsInfoBuf = (char*)compilerStatsInfo;
  *compilerStatsInfo = generator->compilerStatsInfo();  

  // remove the duplicated entries from the schema label list, and put the
  // unique entries in TDB. During execution time, we will check the 
  // LastModTimestamp of the schema label. If the lastModTimestamp has changed,
  // a timestamp mismatch will be returned, allowing for recompilation of the
  // query


  NABoolean validateSSTSFlag = TRUE;

  CollIndex numObjectUIDs = generator->objectUids().entries();
  Int64 *objectUIDsPtr = NULL;
  if (numObjectUIDs > 0)
    {
      objectUIDsPtr  = new (space) Int64[numObjectUIDs];
      for (CollIndex i = 0; i < numObjectUIDs; i++)
        objectUIDsPtr[i] = generator->objectUids()[i];
    }
  
  Queue * listOfSnapshotscanTables =  NULL;
  NAString tmpLocNAS;
  char * tmpLoc = NULL;
  Int64 numObjectNames = generator->objectNames().entries();
  if (numObjectNames >0)
  {
    listOfSnapshotscanTables = new(space) Queue(space);
    for (Lng32 i=0 ; i <generator->objectNames().entries(); i++)
    {
     char * nm = space->allocateAlignedSpace(generator->objectNames()[i].length() + 1);
     strcpy(nm, generator->objectNames()[i].data());
     listOfSnapshotscanTables->insert(nm);
    }

    tmpLocNAS = generator->getSnapshotScanTmpLocation();
    CMPASSERT(tmpLocNAS[tmpLocNAS.length()-1] =='/');
    tmpLoc = space->allocateAlignedSpace(tmpLocNAS.length() + 1);
    strcpy(tmpLoc, tmpLocNAS.data());
  }


  // for describe type commands(showshape, showplan, explain) we don't
  // need to pass in the actual param values even if the query contains
  // params. Reset input_expr. This is done to avoid returning
  // an error later if the actual param value is not set.
 OperatorTypeEnum child_op_type = childOperType();
  if (child_op_type == REL_EXE_UTIL || child_op_type == REL_DESCRIBE)
  {
    RelExpr * lc = child(0)->castToRelExpr();
    OperatorTypeEnum actual_op_type = lc->getOperatorType();

    if (actual_op_type == REL_EXE_UTIL)
    {
      ExeUtilExpr *e = (ExeUtilExpr *)lc;
      if (e->getExeUtilType() == ExeUtilExpr::DISPLAY_EXPLAIN_)
        input_expr = NULL;
    }
    else if (actual_op_type == REL_DESCRIBE)
    {
       Describe *d = (Describe *)lc;
       if (d->getFormat() == Describe::SHAPE_ 
         ||  d->getFormat() == Describe::PLAN_)
           input_expr = NULL;
    }
  }

  // ---------------------------------------------------------------------
  // now initialize the previously allocated root tdb. note that this
  // init *must* come before we fill in the exFragDir's info because there
  // we compute how much space is used by the fragment the root is in.
  // This init() call passes in the space object. The root might allocate
  // more space for its uses inside init().
  // ---------------------------------------------------------------------
  root_tdb->init(child_tdb,
                 cri_desc, // input to child
                 (InputOutputExpr *)input_expr,
                 (InputOutputExpr *)output_expr,
                 input_vars_size,
                 pkey_expr,
                 pkey_len,
                 pred_expr,
                 work_cri_desc,
                 exFragDir,
                 transMode,
                 fetchedCursorName,
                 fetchedCursorHvar,
		 delCurrOf,
                 numUpdateCol,
                 updateColList,
                 (outputVarCntValid() && outputVarCnt()),
                 noOfTables,
                 getFirstNRows(),
                 userInputVars,
                 (getRollUpCost() ?
                  getRollUpCost()->displayTotalCost().getValue() : 0),
                 stoiList,
                 lnil,
                 viewStoiList,
                 qsi,
                 space,
		 uniqueExecuteIdOffset, //++ Triggers -
		 triggersStatusOffset,
		 triggersCount,
		 triggersList,
                 (short)generator->getTempTableId(),
		 (short)baseTablenamePosition,
		 updDelInsert,
		 retryableStmt,
		 getGroupAttr()->isStream(),
		 // next flag is set for destructive stream access protocol.
		 // Not needed for hbase/seabase access.
		 (getGroupAttr()->isEmbeddedUpdateOrDelete() &&
		  (NOT hdfsAccess())),
		 CmpCommon::getDefaultNumeric(STREAM_TIMEOUT),
		 generator->getPlanId(),
		 qCacheInfoBuf,
		 cacheVarsSize,
		 udrStoiList,
		 noOfUdrs,
                 maxResultSets,
		 queryCostInfoBuf,
		 newMvList,
		 uninitializedMvCount,
		 compilerStatsInfoBuf,
		 rwrsInfoBuf,
                 numObjectUIDs ,
                 objectUIDsPtr,
                 compilationStatsData,
                 tmpLoc,
                 listOfSnapshotscanTables);

  root_tdb->setTdbId(generator->getAndIncTdbId());
  
  if (childTdbIsNull)
     root_tdb->setChildTdbIsNull(); 
  if (generator->explainInRms())
     root_tdb->setExplainInRms();

  OperatorTypeEnum childOper = childOperType();

  if (qCacheInfoIsClass)
    root_tdb->setQCacheInfoIsClass(TRUE);

  if (getHostArraysArea() && getHostArraysArea()->getRowwiseRowset())
    {
      root_tdb->setRowwiseRowsetInput(TRUE);
    }
  else
    {
      NABoolean singleRowInput = TRUE;
      if ((input_expr) && ((InputOutputExpr *)input_expr)->isCall())
	singleRowInput = FALSE;

      if (CmpCommon::getDefault(COMP_BOOL_92) == DF_OFF)
	singleRowInput = FALSE;

      root_tdb->setSingleRowInput(singleRowInput);
    }

  if (childOper == REL_DDL)
    {
      root_tdb->setDDLQuery(TRUE);
    }

    root_tdb->setCIFON(isCIFOn_);
    if (generator->currentCmpContext()->isEmbeddedArkcmp())
      //if (IdentifyMyself::GetMyName() == I_AM_EMBEDDED_SQL_COMPILER)
      root_tdb->setEmbeddedCompiler(TRUE);
   else
     root_tdb->setEmbeddedCompiler(FALSE);
  // We check to see if this tree corresponds to a compound statement so
  // we know this at execution time

  RelExpr* checkNode = child(0);

  if ( checkNode->getOperatorType() == REL_EXCHANGE )
    checkNode = checkNode->child(0);

  if ( checkNode->getOperatorType() == REL_PARTITION_ACCESS )
    checkNode = checkNode->child(0);

  if (checkNode->getOperatorType() == REL_COMPOUND_STMT ||
      (checkNode->getOperatorType() == REL_UNION ||
       checkNode->getOperatorType() == REL_MERGE_UNION)
      &&
      ((Union *) (RelExpr *) checkNode)->getUnionForIF()) {
    root_tdb->setCompoundStatement();
  }

  root_tdb->setDoOltQueryOpt(doOltQryOpt);

  root_tdb->setQueryType(ComTdbRoot::SQL_OTHER);

  // set the EMS Event Experience Level information
  // the default is ADVANCED if it is not specified
  if (CmpCommon::getDefault(USER_EXPERIENCE_LEVEL) == DF_BEGINNER)
  {
      root_tdb->setEMSEventExperienceLevelBeginner(TRUE);
  } 
  if (CmpCommon::getDefault(UNC_PROCESS) == DF_ON)
  {
      root_tdb->setUncProcess(TRUE);
  }

  
  // If this is a ustat query set the query type so WMS can monitor it
  if (childOper == REL_DDL)
    {
      DDLExpr *ddlExpr = (DDLExpr *)child(0)->castToRelExpr();
      char * stmt = ddlExpr->getDDLStmtText();
      NAString ddlStr = NAString(stmt);
      ddlStr = ddlStr.strip(NAString::leading, ' ');
      // If this is a ustat statement, set the type 
      Int32 foundUpdStat = 0;
      
      // check if the first token is UPDATE
      size_t position = ddlStr.index("UPDATE", 0, NAString::ignoreCase);
      if (position == 0)
        {
          // found UPDATE. See if the next token is STATISTICS.
          ddlStr = ddlStr(6, ddlStr.length()-6); // skip over UPDATE
          ddlStr = ddlStr.strip(NAString::leading, ' ');
          
          position = ddlStr.index("STATISTICS", 0, NAString::ignoreCase);
          if (position == 0)
            foundUpdStat = -1;
        }
      if (foundUpdStat)
        { 
          root_tdb->setQueryType(ComTdbRoot::SQL_CAT_UTIL);     
        }
    }
  // Disable Cancel for some queries.  But start the logic with 
  // "all queries can be canceled."
  root_tdb->setMayNotCancel(FALSE);

  // Disallow cancel.
  if (CmpCommon::getDefault(COMP_BOOL_20) == DF_ON)
    root_tdb->setMayNotCancel(TRUE);

  if (generator->mayNotCancel())
    root_tdb->setMayNotCancel(TRUE);

  if (updDelInsert)
    {
      if ((childOper == REL_UNARY_INSERT) ||
	  (childOper == REL_LEAF_INSERT) ||
	  (childOper == REL_INSERT_CURSOR))
	root_tdb->setQueryType(ComTdbRoot::SQL_INSERT_NON_UNIQUE);
      else if ((childOper == REL_UNARY_UPDATE) ||
	       (childOper == REL_LEAF_UPDATE) ||
	       (childOper == REL_UPDATE_CURSOR))
	root_tdb->setQueryType(ComTdbRoot::SQL_UPDATE_NON_UNIQUE);
      else if ((childOper == REL_UNARY_DELETE) ||
	       (childOper == REL_LEAF_DELETE) ||
	       (childOper == REL_DELETE_CURSOR))
	root_tdb->setQueryType(ComTdbRoot::SQL_DELETE_NON_UNIQUE);
    }
  
  if (output_expr)
    root_tdb->setQueryType(ComTdbRoot::SQL_SELECT_NON_UNIQUE);
  
  if ((updDelInsert) &&
      (root_tdb->getQueryType() == ComTdbRoot::SQL_INSERT_NON_UNIQUE) &&
      (rwrsInfo))
    {
      root_tdb->setQueryType(ComTdbRoot::SQL_INSERT_RWRS);
    }
  else if ((child(0)) &&
	   (child(0)->castToRelExpr()->getOperatorType() == REL_UTIL_INTERNALSP))
    {
       root_tdb->setQueryType(ComTdbRoot::SQL_CAT_UTIL);
    }
  else if ((child(0)) &&
	   (child(0)->castToRelExpr()->getOperatorType() == REL_DESCRIBE))
    {
      root_tdb->setSubqueryType(ComTdbRoot::SQL_DESCRIBE_QUERY);
    }
  else if ((child(0)) &&
	   (child(0)->castToRelExpr()->getOperatorType() == REL_EXE_UTIL))
    {
      root_tdb->setQueryType(ComTdbRoot::SQL_EXE_UTIL);
      ExeUtilExpr * exeUtil = (ExeUtilExpr*)child(0)->castToRelExpr();
      if (exeUtil->getExeUtilType() == ExeUtilExpr::CREATE_TABLE_AS_)
      {
        if (CmpCommon::getDefault(REDRIVE_CTAS) == DF_OFF)
	  root_tdb->setQueryType(ComTdbRoot::SQL_INSERT_NON_UNIQUE);
        else
          root_tdb->setSubqueryType(ComTdbRoot::SQL_STMT_CTAS);
      }
      else if (exeUtil->getExeUtilType() == ExeUtilExpr::GET_STATISTICS_)
          root_tdb->setSubqueryType(ComTdbRoot::SQL_STMT_GET_STATISTICS);
      else if (exeUtil->getExeUtilType() == ExeUtilExpr::DISPLAY_EXPLAIN_)
	{
          root_tdb->setSubqueryType(ComTdbRoot::SQL_DISPLAY_EXPLAIN);

	   if (CmpCommon::getDefault(EXE_UTIL_RWRS) == DF_ON)
	     root_tdb->setExeUtilRwrs(TRUE);
	}
       else if (exeUtil->getExeUtilType() == ExeUtilExpr::HBASE_COPROC_AGGR_)
          root_tdb->setQueryType(ComTdbRoot::SQL_SELECT_NON_UNIQUE);
       else if (exeUtil->getExeUtilType() == ExeUtilExpr::HBASE_LOAD_)
       {
         root_tdb->setSubqueryType(ComTdbRoot::SQL_STMT_HBASE_LOAD);
       }
       else if (exeUtil->getExeUtilType() == ExeUtilExpr::HBASE_UNLOAD_)
       {
         root_tdb->setSubqueryType(ComTdbRoot::SQL_STMT_HBASE_UNLOAD);
       }
       else if (exeUtil->getExeUtilType() == ExeUtilExpr::LOB_EXTRACT_)
	 {
	   root_tdb->setSubqueryType(ComTdbRoot::SQL_STMT_LOB_EXTRACT);
	 }
       else if(exeUtil->getExeUtilType() == ExeUtilExpr::LOB_UPDATE_UTIL_)
         {
           root_tdb->setSubqueryType(ComTdbRoot::SQL_STMT_LOB_UPDATE_UTIL
); 
         }

      else if (exeUtil->isExeUtilQueryType())
	{
	   root_tdb->setQueryType(ComTdbRoot::SQL_EXE_UTIL);
	}
    }
  else if ((child(0)) &&
	   (child(0)->castToRelExpr()->getOperatorType() == REL_DDL))
    {
      DDLExpr *ddlExpr = (DDLExpr *)child(0)->castToRelExpr();
      
      if (ddlExpr->producesOutput())
        root_tdb->setQueryType(ComTdbRoot::SQL_EXE_UTIL);     
    }
  else if (generator->getBindWA()->hasCallStmts())
  {
    // In this version of the compiler we assume any statement that
    // contains UDRs is either a CALL statement.
    if (maxResultSets > 0)
      root_tdb->setQueryType(ComTdbRoot::SQL_CALL_WITH_RESULT_SETS);
    else
      root_tdb->setQueryType(ComTdbRoot::SQL_CALL_NO_RESULT_SETS);
  }
  else
  {
    OperatorTypeEnum currChildOper = 
      child(0)->castToRelExpr()->getOperatorType();
    
    if (currChildOper == REL_CONTROL_QUERY_DEFAULT)
    {
      root_tdb->setMayNotCancel(TRUE);
      ControlQueryDefault * cqd = 
        (ControlQueryDefault*)child(0)->castToRelExpr();
      if (cqd->dynamic())
      {
        if (cqd->getAttrEnum() == CATALOG)
          root_tdb->setQueryType(ComTdbRoot::SQL_SET_CATALOG); 
        else if (cqd->getAttrEnum() == SCHEMA) 
          root_tdb->setQueryType(ComTdbRoot::SQL_SET_SCHEMA); 
        else
          root_tdb->setQueryType(ComTdbRoot::SQL_CONTROL); 
      }
      else
        root_tdb->setQueryType(ComTdbRoot::SQL_CONTROL); 
    }
    else if ((currChildOper == REL_CONTROL_QUERY_SHAPE) ||
             (currChildOper == REL_CONTROL_TABLE))
    {
      root_tdb->setMayNotCancel(TRUE);
      root_tdb->setQueryType(ComTdbRoot::SQL_CONTROL);
    }
    else if (currChildOper == REL_TRANSACTION)
    {
      root_tdb->setMayNotCancel(TRUE);
      if (((RelTransaction*)child(0)->castToRelExpr())->getType() == SET_TRANSACTION_)
        root_tdb->setQueryType(ComTdbRoot::SQL_SET_TRANSACTION); 
    }
    else if (currChildOper == REL_SP_PROXY)
    {
      // This is a stored procedure result set
      root_tdb->setQueryType(ComTdbRoot::SQL_SP_RESULT_SET);
    }
    else if (currChildOper == REL_EXE_UTIL)
    {
      ExeUtilExpr * exeUtil = (ExeUtilExpr*)child(0)->castToRelExpr();
      if (exeUtil->getExeUtilType() == ExeUtilExpr::CREATE_TABLE_AS_)
	root_tdb->setQueryType(ComTdbRoot::SQL_INSERT_NON_UNIQUE);
    }
    else if (REL_EXPLAIN == currChildOper)
      root_tdb->setMayNotCancel(TRUE);
    else if (REL_SET_TIMEOUT == currChildOper)
      root_tdb->setMayNotCancel(TRUE);
    else if (REL_CONTROL_RUNNING_QUERY == currChildOper)
      root_tdb->setMayNotCancel(TRUE);
  }

  if (generator->isFastExtract())
  {
    root_tdb->setQueryType(ComTdbRoot::SQL_SELECT_UNLOAD);
  }

  if (child(0) && child(0)->castToRelExpr() && 
      child(0)->castToRelExpr()->getOperator().match(REL_ANY_HBASE))
    {
      RelExpr * childExpr = child(0)->castToRelExpr();
      OperatorTypeEnum currChildOper = childExpr->getOperatorType();
      
      if ((childExpr->getOperator().match(REL_ANY_HBASE_GEN_UPDATE)) &&
	  (NOT output_expr))
	{
	  GenericUpdate * gu = (GenericUpdate *)childExpr;
	  
	  if (gu->uniqueHbaseOper())
	    {
	      if (currChildOper == REL_HBASE_UPDATE)
		root_tdb->setQueryType(ComTdbRoot::SQL_UPDATE_UNIQUE);
	      else if (currChildOper == REL_HBASE_DELETE)
		root_tdb->setQueryType(ComTdbRoot::SQL_DELETE_UNIQUE);
	      else
		root_tdb->setQueryType(ComTdbRoot::SQL_INSERT_UNIQUE);
	    }
	  else
	    {
	      if (currChildOper == REL_HBASE_UPDATE)
		root_tdb->setQueryType(ComTdbRoot::SQL_UPDATE_NON_UNIQUE);
	      else if (currChildOper == REL_HBASE_DELETE)
		root_tdb->setQueryType(ComTdbRoot::SQL_DELETE_NON_UNIQUE);
	      else
		root_tdb->setQueryType(ComTdbRoot::SQL_INSERT_NON_UNIQUE);
	    }
	}
      else if (currChildOper == REL_HBASE_ACCESS)
	{
	  HbaseAccess * ha = (HbaseAccess *)childExpr;
	  if (ha->uniqueHbaseOper())
	    root_tdb->setQueryType(ComTdbRoot::SQL_SELECT_UNIQUE);
	  else
	    root_tdb->setQueryType(ComTdbRoot::SQL_SELECT_NON_UNIQUE);
	}
    }

  // To help determine if it is safe to suspend.
  if (child(0) && 
      child(0)->castToRelExpr())
  {
    OperatorTypeEnum currChildOper = 
        child(0)->castToRelExpr()->getOperatorType();
    if ((REL_DDL == currChildOper) ||
        (REL_TRANSACTION == currChildOper) ||
        (REL_EXE_UTIL == currChildOper))
      root_tdb->setMayAlterDb(TRUE);

    if (REL_LOCK == currChildOper)
      root_tdb->setSuspendMayHoldLock(TRUE);
  }

  if (generator->anySerialiableScan())
      root_tdb->setSuspendMayHoldLock(TRUE);
  
  root_tdb->setOdbcQuery(CmpCommon::getDefault(ODBC_PROCESS) == DF_ON);

  if (generator->getTolerateNonFatalError()) {
    root_tdb->setTolerateNonFatalError(TRUE);
    if (CmpCommon::getDefault(NOT_ATOMIC_FAILURE_LIMIT,0) == DF_SYSTEM)
      root_tdb->setNotAtomicFailureLimit(ComCondition::NO_LIMIT_ON_ERROR_CONDITIONS);
    else
      root_tdb->setNotAtomicFailureLimit(CmpCommon::getDefaultLong(NOT_ATOMIC_FAILURE_LIMIT));
  }

  if (generator->embeddedIUDWithLast1()) {
    root_tdb->setEmbeddedIUDWithLast1(TRUE);
  }

  if (generator->embeddedInsert()) {
    root_tdb->setEmbeddedInsert(TRUE);
  }

  if (containsLRU())
    {
      root_tdb->setLRUOperation(TRUE);
    }

  if (generator->aqrEnabled())
    root_tdb->setAqrEnabled(TRUE);

  if (generator->cantReclaimQuery())
    root_tdb->setCantReclaimQuery(TRUE);

    // if a transaction is needed at runtime to execute this query,
  // set that information in the root tdb. Generator synthesized
  // this information based on the kind of query or if START_XN
  // define was set.
  // Certain queries (insert, update, delete) ALWAYS require a transaction
  // at runtime.
  // After parser support for REPEATABLE ACCESS, etc, is in, this
  // information will come from the parse tree for scans.
  if (generator->isTransactionNeeded())
    {
      root_tdb->setTransactionReqd();

      if (generator->foundAnUpdate())
	{
	  if (generator->updAbortOnError() == TRUE)
	    {
	      // if transaction has to be aborted at runtime after an error,
	      // set that info in root_tdb.
	      root_tdb->setUpdAbortOnError(-1);
	    }
	  else if (generator->updPartialOnError() == TRUE)
	    {
	      root_tdb->setUpdPartialOnError(-1);
	    }
	  else if (generator->updErrorInternalOnError() == TRUE)
	    {
	      root_tdb->setUpdErrorOnError(-1);
	    }
	  else if (generator->updErrorOnError() == FALSE)
	    {
	      if (generator->updSavepointOnError() == TRUE)
		{
		  root_tdb->setUpdSavepointOnError(-1);
		}
	      else
		root_tdb->setUpdAbortOnError(-1);
	    }
	  else
	    root_tdb->setUpdErrorOnError(-1);
	}
      else
	{
	  root_tdb->setUpdErrorOnError(-1);
	}
    } // transactionNeeded

  if ((oltOptLean()) &&
      (doOltQryOpt))
    {
      if ((NOT root_tdb->getUpdAbortOnError()) &&
	  (NOT root_tdb->getUpdSavepointOnError()) &&
	  (NOT root_tdb->getUpdPartialOnError()) &&
	  (retryableStmt) &&
	  (NOT root_tdb->thereIsACompoundStatement()))
	{
	  root_tdb->setDoOltQueryOptLean(TRUE);

	  child_tdb->setDoOltQueryOptLean(TRUE);
	}
    }

  if (generator->dp2XnsEnabled())
    {
      root_tdb->setDp2XnsEnabled(generator->dp2XnsEnabled());
    }

  
  if (generator->processLOB())
    root_tdb->setProcessLOB(TRUE);
 

  // Self-referencing updates
  if (avoidHalloween_)
  {
    if (Generator::DP2LOCKS == generator->getHalloweenProtection())
    {
      // Plan was generated without resetting the generator's 
      // HalloweenProtectionType from DP2Locks, therefore we are
      // using DP2 locks, and cannot allow auto commit off.
      root_tdb->setCheckAutoCommit(TRUE);
    }
  }
  else if (CmpCommon::getDefault(AQR_WNR_DELETE_NO_ROWCOUNT) == DF_ON)
  {
    // Allow non-ACID AQR of NO ROLLBACK DELETE that may have changed 
    // target. Query type (DELETE vs others) and WNR will be evaluated
    // at runtime.
    root_tdb->setAqrWnrDeleteContinue(TRUE);
  }
  if (CmpCommon::getDefault(PSHOLD_CLOSE_ON_ROLLBACK) == DF_ON)
    root_tdb->setPsholdCloseOnRollback(TRUE);
  else
    root_tdb->setPsholdCloseOnRollback(FALSE);
  if (CmpCommon::getDefault(PSHOLD_UPDATE_BEFORE_FETCH) == DF_ON)
    root_tdb->setPsholdUpdateBeforeFetch(TRUE);
  else
    root_tdb->setPsholdUpdateBeforeFetch(FALSE);

  root_tdb->setAbendType(
    (Lng32) CmpCommon::getDefaultNumeric(COMP_INT_38) );

  double cpuLimitCheckFreq = CmpCommon::getDefaultNumeric(COMP_INT_48);
  if (cpuLimitCheckFreq > SHRT_MAX)
    cpuLimitCheckFreq = SHRT_MAX;
  root_tdb->setCpuLimitCheckFreq((short) cpuLimitCheckFreq);

  // Config query execution limits.
  Lng32 cpuLimit = (Lng32) CmpCommon::getDefaultNumeric(QUERY_LIMIT_SQL_PROCESS_CPU);
  if (cpuLimit > 0)
    root_tdb->setCpuLimit(cpuLimit);  

  if (CmpCommon::getDefault(QUERY_LIMIT_SQL_PROCESS_CPU_DEBUG) == DF_ON)
    root_tdb->setQueryLimitDebug();

  if (generator->inMemoryObjectDefn())
    root_tdb->setInMemoryObjectDefn(TRUE);
	
  if (CmpCommon::getDefault(READONLY_CURSOR) == DF_ON)
    root_tdb->setCursorType(SQL_READONLY_CURSOR);
  else
    root_tdb->setCursorType(SQL_UPDATABLE_CURSOR);
	
  if (CmpCommon::getDefault(WMS_QUERY_MONITORING) == DF_ON)
    root_tdb->setWmsMonitorQuery(TRUE);
  else
    root_tdb->setWmsMonitorQuery(FALSE);

  if (CmpCommon::getDefault(WMS_CHILD_QUERY_MONITORING) == DF_ON)
    root_tdb->setWmsChildMonitorQuery(TRUE);
  else
    root_tdb->setWmsChildMonitorQuery(FALSE);

  if (hdfsAccess())
    root_tdb->setHdfsAccess(TRUE);

  if(generator->hiveAccess())
    root_tdb->setHiveAccess(TRUE);

  root_tdb->setBmoMemoryLimitPerNode(ActiveSchemaDB()->getDefaults().getAsDouble(BMO_MEMORY_LIMIT_PER_NODE_IN_MB));
  root_tdb->setEstBmoMemoryPerNode(generator->getTotalBMOsMemoryPerNode().value());

  Int32 numSikEntries = securityKeySet_.entries();
  if (numSikEntries > 0)
  {
    ComSecurityKey * sikValues = new (space) ComSecurityKey[numSikEntries];

    for (Int32 sv = 0; sv < numSikEntries; sv++)
      sikValues[sv] = securityKeySet_[sv];

    SecurityInvKeyInfo * sikInfo = new (space) SecurityInvKeyInfo(
                                     numSikEntries, sikValues); 
    root_tdb->setSikInfo(sikInfo);
  }

  if (!generator->explainDisabled())
    {
      // finish up EXPLAIN
      ExplainTuple *rootExplainTuple =
	addExplainInfo(root_tdb, 0, 0, generator);
      explainDesc->setExplainTreeRoot(rootExplainTuple);

      ExplainTuple *childExplainTuple = generator->getExplainTuple();

      rootExplainTuple->child(0) = childExplainTuple;
      if(childExplainTuple)
	{
	  childExplainTuple->setParent(rootExplainTuple);
	  rootExplainTuple->setChildSeqNum(
	       0,
	       childExplainTuple->getSeqNum());
	}

      generator->setExplainTuple(rootExplainTuple);
    }

  // Generate a list of scratch file options
  exFragDir->setScratchFileOptions(genScratchFileOptions(generator));

  // move ESP nodemask into frag dir
  exFragDir->setNodeMask((ULng32) getDefault(PARALLEL_ESP_NODEMASK));

  // generate the partition input data descriptor from the compile-time
  // partitioning attributes
  ExPartInputDataDesc **partInputDataDescs =
    new(generator->wHeap()) ExPartInputDataDesc *[compFragDir->entries()];
  ExEspNodeMap **nodeMap =
    new(generator->wHeap()) ExEspNodeMap *[compFragDir->entries()];
  for (i = 0; i < compFragDir->entries(); i++)
    {
      if (compFragDir->getPartitioningFunction(i) != NULL)
	{
	  // This fragment has partitioning info, generate it
	  ((PartitioningFunction *) compFragDir->getPartitioningFunction(i))->
	    codeGen(generator,
		    compFragDir->getPartInputDataLength(i));
	  partInputDataDescs[i] =
	    (ExPartInputDataDesc *) (generator->getGenObj());
	  NodeMap::codeGen(compFragDir->getPartitioningFunction(i),
			   compFragDir->getNumESPs(i),
			   generator);
	  nodeMap[i] = (ExEspNodeMap *) (generator->getGenObj());
	}
      else
        {
	  partInputDataDescs[i] = NULL;
          nodeMap[i] = NULL;
        }
    }

  // remove maptable for child tree
  generator->removeAll(map_table);

  // remove my map table
  generator->removeLast();
  generator->setMapTable(NULL);

  // move data entry by entry from the generator's copy into the executor copy
  Lng32 offset = 0;
  Lng32 currLength;
  Lng32 compressThreshold = getDefault(FRAG_COMPRESSION_THRESHOLD);
  NABoolean anyEspFragments = FALSE;

  for (i = 0; i < compFragDir->entries(); i++)
    {
      // translate fragment type enums
      ExFragDir::ExFragEntryType runTimeType = ExFragDir::MASTER;
      currLength = compFragDir->getFragmentLength(i);
      compilerStatsInfo->totalFragmentSize() += currLength;
      switch (compFragDir->getType(i))
	{
	case FragmentDir::MASTER:
	  runTimeType = ExFragDir::MASTER;
	  compilerStatsInfo->masterFragmentSize() += currLength;
	  break;
	case FragmentDir::DP2:
	  runTimeType = ExFragDir::DP2;
	  compilerStatsInfo->dp2FragmentSize() += currLength;
	  break;
	case FragmentDir::ESP:
	  runTimeType = ExFragDir::ESP;
          anyEspFragments = TRUE;
	  compilerStatsInfo->espFragmentSize() += currLength;
	  break;
	case FragmentDir::EXPLAIN:
	  runTimeType = ExFragDir::EXPLAIN;
	  compilerStatsInfo->masterFragmentSize() += currLength;
	  break;
	default:
	  ABORT("Internal error, invalid fragment type");
	}

      // take the pointer of the top-level object in this fragment and
      // convert it to a fragment-relative offset
      Lng32 offsetOfTopNode = compFragDir->getSpace(i)->
	convertToOffset((char *)(compFragDir->getTopNode(i)));

      // now set the values of the previously allocated directory entry

      NABoolean mlimitPerNode = CmpCommon::getDefaultLong(BMO_MEMORY_LIMIT_PER_NODE_IN_MB) > 0;
      UInt16 BMOsMemoryUsage = 0;
      if (mlimitPerNode == TRUE)
        BMOsMemoryUsage = (UInt16)compFragDir->getBMOsMemoryUsage(i);
      else if (compFragDir->getNumBMOs(i) > 1 ||
               (compFragDir->getNumBMOs(i) == 1 && CmpCommon::getDefault(EXE_SINGLE_BMO_QUOTA) == DF_ON))
        BMOsMemoryUsage = (UInt16)CmpCommon::getDefaultLong(EXE_MEMORY_AVAILABLE_IN_MB);

      exFragDir->set(i,
		     runTimeType,
		     (ExFragId) compFragDir->getParentId(i),
		     offset,
		     currLength,
		     -offsetOfTopNode,
		     partInputDataDescs[i],
		     nodeMap[i],
		     compFragDir->getNumESPs(i),
		     compFragDir->getEspLevel(i),
		     compFragDir->getNeedsTransaction(i),
                     (compressThreshold > 0 &&
                      runTimeType == ExFragDir::ESP &&
                      compressThreshold <= compFragDir->getNumESPs(i))?
                       TRUE: FALSE,  // DP2 fragment will be compressed later
                                     // if parent ESP fragment is compressed
                                     // see executor/ex_frag_rt.cpp
		     compFragDir->getSoloFragment(i),
		     BMOsMemoryUsage,
		     compFragDir->getNumBMOs(i) > 0
                     );
      offset += currLength;
    } // for each fragment

  compilerStatsInfo->totalFragmentSize() /= 1024;
  compilerStatsInfo->masterFragmentSize() /= 1024;
  compilerStatsInfo->espFragmentSize() /= 1024;
  compilerStatsInfo->dp2FragmentSize() /= 1024;
  compilerStatsInfo->collectStatsType() = generator->collectStatsType();
  compilerStatsInfo->udr() = noOfUdrs;
  compilerStatsInfo->ofMode() = generator->getOverflowMode();
  compilerStatsInfo->ofSize() = 0;
  compilerStatsInfo->bmo() = generator->getTotalNumBMOs();
  compilerStatsInfo->queryType() = (Int16)root_tdb->getQueryType();
  compilerStatsInfo->subqueryType() = (Int16)root_tdb->getSubqueryType();
  compilerStatsInfo->bmoMemLimitPerNode() = root_tdb->getBmoMemoryLimitPerNode();
  compilerStatsInfo->estBmoMemPerNode() = root_tdb->getEstBmoMemoryPerNode();

  NADELETEBASIC(partInputDataDescs, generator->wHeap());
  NADELETEBASIC(nodeMap, generator->wHeap());

  // Genesis 10-990114-6293:
  // don't recompile a SELECT query if transmode changes to READ ONLY.
  if (readOnlyTransIsOK()) root_tdb->setReadonlyTransactionOK();

  // Inserts into non-audited indexes do not need to run in a transaction,
  // if one does not exist. If one exists (which is the case during a create
  // index operation), need to pass transid to all ESPs during the load
  // index phase, otherwise they will get error 73s returned when they open
  // the index. Store this information in the root TDB, so that the transaction
  // can be passed to ESPs if needed.  Dp2Insert::codeGen has set this
  // generator flag.

  NABoolean recompWarn =
    (CmpCommon::getDefault(RECOMPILATION_WARNINGS) == DF_ON);
  if (recompWarn) root_tdb->setRecompWarn();

  // Set the FROM_SHOWPLAN flag if the statement is from a showplan
  const NAString * val =
    ActiveControlDB()->getControlSessionValue("SHOWPLAN");
  if ( !(childOperType_ == REL_CONTROL_SESSION)
       && (val) && (*val == "ON") )
    root_tdb->setFromShowplan();

  if (CmpCommon::getDefault(EXE_LOG_RETRY_IPC) == DF_ON)
    root_tdb->setLogRetriedIpcErrors(TRUE);

  if (anyEspFragments)
  {
    if (generator->getBindWA()->queryCanUseSeaMonster() &&
        generator->getQueryUsesSM())
      root_tdb->setQueryUsesSM();
  }

  generator->setGenObj(this, root_tdb);

  return 0;

} // RelRoot::codeGen()

short Sort::generateTdb(Generator * generator,
                        ComTdb * child_tdb,
                        ex_expr * sortKeyExpr,
                        ex_expr * sortRecExpr,
                        ULng32 sortKeyLen,
                        ULng32 sortRecLen,
                        ULng32 sortPrefixKeyLen,
                        ex_cri_desc * given_desc,
                        ex_cri_desc * returned_desc,
                        ex_cri_desc * work_cri_desc,
                        Lng32 saveNumEsps,
                        ExplainTuple *childExplainTuple,
                        NABoolean resizeCifRecord,
                        NABoolean considerBufferDefrag,
                        NABoolean operatorCIF)
{

  NADefaults &defs = ActiveSchemaDB()->getDefaults();

  ULng32 numBuffers = (ULng32)getDefault(GEN_SORT_NUM_BUFFERS);
  
  CostScalar bufferSize = getDefault(GEN_SORT_MAX_BUFFER_SIZE);

  UInt32 bufferSize_as_uint32 = 
    (UInt32)(MINOF(CostScalar(UINT_MAX), bufferSize)).getValue(); 

  // allocate buffer to hold atlease one row
  bufferSize_as_uint32 = MAXOF(bufferSize_as_uint32, sortRecLen);

  GenAssert(sortRecLen <= bufferSize_as_uint32, 
      "Record Len greater than GEN_SORT_MAX_BUFFER_SIZE");
  
  ComTdbSort * sort_tdb = 0;
  // always start with quick sort. Sort will switch to
  // replacement sort in case of overflow at runtime.
  SortOptions *sort_options = new(generator->getSpace()) SortOptions();

  Lng32 max_num_buffers = (Lng32)numBuffers;
  NAString tmp;
  CmpCommon::getDefault(SORT_ALGO, tmp, -1);
  if(tmp == "HEAP")
    sort_options->sortType() = SortOptions::ITER_HEAP;
  else if(tmp == "REPSEL")
    sort_options->sortType() = SortOptions::REPLACEMENT_SELECT;
  else if(tmp == "IQS")
    sort_options->sortType() = SortOptions::ITER_QUICK;
  else if(tmp == "QS")
    sort_options->sortType() = SortOptions::QUICKSORT;
  max_num_buffers = (Lng32)getDefault(GEN_SORT_MAX_NUM_BUFFERS);
  sort_options->internalSort() = TRUE;

  unsigned short threshold = (unsigned short) CmpCommon::getDefaultLong(SCRATCH_FREESPACE_THRESHOLD_PERCENT);
  sort_options->scratchFreeSpaceThresholdPct() = threshold;
  sort_options->sortMaxHeapSize() = (short)getDefault(SORT_MAX_HEAP_SIZE_MB);
  sort_options->mergeBufferUnit() = (short)getDefault(SORT_MERGE_BUFFER_UNIT_56KB);
 
  //512kb default size initiliazed in sort_options.
  if(sortRecLen >= sort_options->scratchIOBlockSize())
  {
    Int32 maxScratchIOBlockSize = (Int32)getDefault(SCRATCH_IO_BLOCKSIZE_SORT_MAX);
    // allocate space for atleast one row.
    maxScratchIOBlockSize = MAXOF(maxScratchIOBlockSize, sortRecLen);

    GenAssert(sortRecLen <= maxScratchIOBlockSize, 
         "sortRecLen is greater than SCRATCH_IO_BLOCKSIZE_SORT_MAX");
    sort_options->scratchIOBlockSize() = MINOF(sortRecLen * 128, maxScratchIOBlockSize);
  }
  
  sort_options->scratchIOVectorSize() = (Int16)getDefault(SCRATCH_IO_VECTOR_SIZE_SORT);

  if (CmpCommon::getDefault(EXE_BMO_SET_BUFFERED_WRITES) == DF_ON)
    sort_options->setBufferedWrites(TRUE);
  if (CmpCommon::getDefault(EXE_DIAGNOSTIC_EVENTS) == DF_ON)
    sort_options->setLogDiagnostics(TRUE);
  
  // Disable Compiler Hints checks if: CQD is ON or if SYSTEM - only for HDD
  if (
      (CmpCommon::getDefault(EXE_BMO_DISABLE_CMP_HINTS_OVERFLOW_SORT) == DF_ON)
      ||
      (
       ((generator->getOverflowMode()== ComTdb::OFM_DISK) ||
       (generator->getOverflowMode()== ComTdb::OFM_MMAP)) 
       && 
       (CmpCommon::getDefault(EXE_BMO_DISABLE_CMP_HINTS_OVERFLOW_SORT) 
        == DF_SYSTEM )
      )
     )
	 sort_options->setDisableCmpHintsOverflow(TRUE);
	 
  if (CmpCommon::getDefault(EXE_BMO_DISABLE_OVERFLOW) == DF_ON)
    sort_options->dontOverflow() = TRUE;
  if (CmpCommon::getDefault(SORT_INTERMEDIATE_SCRATCH_CLEANUP) == DF_ON)
    sort_options->setIntermediateScratchCleanup(TRUE);

  sort_options->setResizeCifRecord(resizeCifRecord);
  sort_options->setConsiderBufferDefrag(considerBufferDefrag);

  short memoryQuotaMB = 0;
  double memoryQuotaRatio;
  Lng32 numStreams;
  double bmoMemoryUsagePerNode = generator->getEstMemPerNode(getKey(), numStreams);

  if (CmpCommon::getDefault(SORT_MEMORY_QUOTA_SYSTEM) != DF_OFF)
  {
    // The CQD EXE_MEM_LIMIT_PER_BMO_IN_MB has precedence over the mem quota sys
    memoryQuotaMB = (UInt16)defs.getAsDouble(EXE_MEM_LIMIT_PER_BMO_IN_MB);

    if (memoryQuotaMB > 0) {
     sort_options->memoryQuotaMB() = memoryQuotaMB;
    } else {
  
      UInt16 numBMOsInFrag = (UInt16)generator->getFragmentDir()->getNumBMOs();
  
      // Apply quota system if either one the following two is true:
      //   1. the memory limit feature is turned off and more than one BMOs
      //   2. the memory limit feature is turned on
      
      NABoolean mlimitPerNode = defs.getAsDouble(BMO_MEMORY_LIMIT_PER_NODE_IN_MB) > 0;
  
      if ( mlimitPerNode || numBMOsInFrag > 1 ||
         (numBMOsInFrag == 1 && CmpCommon::getDefault(EXE_SINGLE_BMO_QUOTA) == DF_ON)) {
  
          memoryQuotaMB = (short)
             computeMemoryQuota(generator->getEspLevel() == 0,
                                mlimitPerNode,
                                generator->getBMOsMemoryLimitPerNode().value(),
                                generator->getTotalNumBMOs(),
                                generator->getTotalBMOsMemoryPerNode().value(),
                                numBMOsInFrag, 
                                bmoMemoryUsagePerNode,
                                numStreams,
                                memoryQuotaRatio
                               );
  
      }            
      Lng32 sortMemoryLowbound = defs.getAsLong(BMO_MEMORY_LIMIT_LOWER_BOUND_SORT);
      Lng32 memoryUpperbound = defs.getAsLong(BMO_MEMORY_LIMIT_UPPER_BOUND);
  
      if ( memoryQuotaMB < sortMemoryLowbound ) {
         memoryQuotaMB = (short)sortMemoryLowbound;
         memoryQuotaRatio = BMOQuotaRatio::MIN_QUOTA;
      }
      else if (memoryQuotaMB >  memoryUpperbound)
         memoryQuotaMB = memoryUpperbound;
    }
  }

   //BMO settings. By Default set this value to max available 
   //irrespective of quota is enabled or disabled. Sort at run time
   //will manage to check for quota and available physical memory
   //before consuming memory. Note that if memoryQuota is set zero,
   //sort may not do physical memory or memory pressure checks.
  if ( memoryQuotaMB <= 0  && 
       ! sort_options->disableCmpHintsOverflow() ) // compiler hints enabled
   {
     memoryQuotaMB = (UInt16)defs.getAsLong(EXE_MEMORY_AVAILABLE_IN_MB);
   }
   sort_options->memoryQuotaMB() = memoryQuotaMB;

  if(generator->getOverflowMode() == ComTdb::OFM_SSD )
    sort_options->bmoMaxMemThresholdMB() = (UInt16)defs.getAsLong(SSD_BMO_MAX_MEM_THRESHOLD_IN_MB);
  else
    sort_options->bmoMaxMemThresholdMB() = (UInt16)defs.getAsLong(EXE_MEMORY_AVAILABLE_IN_MB);

   sort_options->pressureThreshold() = 
                  (short)getDefault(GEN_MEM_PRESSURE_THRESHOLD);
   
  short sortGrowthPercent = 
    RelExpr::bmoGrowthPercent(getEstRowsUsed(), getMaxCardEst());

  sort_tdb = new(generator->getSpace())
    ComTdbSort(sortKeyExpr,
	       sortRecExpr,
	       sortKeyLen,
	       sortRecLen,
	       sortPrefixKeyLen,
	       returned_desc->noTuples() - 1,
	       child_tdb,
	       given_desc,
	       returned_desc,
	       work_cri_desc,

	       // if sort input is from top, switch the UP and DOWN queue
	       // sizes
	       (sortFromTop()
		? (queue_index)getDefault(GEN_SORT_SIZE_UP)
		: (queue_index)getDefault(GEN_SORT_SIZE_DOWN)),
	       (queue_index)getDefault(GEN_SORT_SIZE_UP),
	       (Cardinality) (getInputCardinality() * getEstRowsUsed()).getValue(),
	       numBuffers,
	       bufferSize_as_uint32,
	       max_num_buffers,
	       sort_options,
           sortGrowthPercent);
  sort_tdb->setCollectNFErrors(this->collectNFErrors());

  sort_tdb->setSortFromTop(sortFromTop());
  sort_tdb->setOverflowMode(generator->getOverflowMode());
  sort_tdb->setTopNSortEnabled(CmpCommon::getDefault(GEN_SORT_TOPN) == DF_ON);
  sort_tdb->setBmoQuotaRatio(memoryQuotaRatio);
  
  if (generator->getUserSidetreeInsert())
    sort_tdb->setUserSidetreeInsert(TRUE);

  if (getTolerateNonFatalError() == RelExpr::NOT_ATOMIC_) 
    sort_tdb->setTolerateNonFatalError(TRUE);

  sort_tdb->setCIFON(operatorCIF);

  generator->initTdbFields(sort_tdb);

  double sortMemEst = generator->getEstMemPerInst(getKey());
  sort_tdb->setEstimatedMemoryUsage(sortMemEst / 1024);
  generator->addToTotalEstimatedMemory(sortMemEst);

  if (sortPrefixKeyLen > 0)
    ((ComTdbSort *)sort_tdb)->setPartialSort(TRUE);  // do partial sort

  if(CmpCommon::getDefaultLong(SORT_REC_THRESHOLD) > 0)
      ((ComTdbSort *)sort_tdb)->setMinimalSortRecs(CmpCommon::getDefaultLong(SORT_REC_THRESHOLD));

  sort_tdb->setMemoryContingencyMB(getDefault(PHY_MEM_CONTINGENCY_MB));
  float bmoCtzFactor;
  defs.getFloat(BMO_CITIZENSHIP_FACTOR, bmoCtzFactor);
  sort_tdb->setBmoCitizenshipFactor((Float32)bmoCtzFactor);
  sort_tdb->setSortMemEstInKBPerNode(bmoMemoryUsagePerNode /1024);
  if (sortNRows())
     sort_tdb->setTopNThreshold(defs.getAsLong(GEN_SORT_TOPN_THRESHOLD));
  if (!generator->explainDisabled()) {
    generator->setExplainTuple(
       addExplainInfo(sort_tdb, childExplainTuple, 0, generator));
  }

  // set the new up cri desc.
  generator->setCriDesc(returned_desc, Generator::UP);

  generator->setGenObj(this, sort_tdb);

  // reset the expression generation flag to generate float validation pcode
  generator->setGenNoFloatValidatePCode(FALSE);

  return 0;
}

//////////////////////////////////////////////////////////////
//
// Sort::codeGen()
//
/////////////////////////////////////////////////////////
short Sort::codeGen(Generator * generator)
{
  ExpGenerator * exp_gen = generator->getExpGenerator();
  Space * space = generator->getSpace();

   ////////////////////////////////////////////////////////////////////////
  //
  // Layout at this node:
  //
  // |-------------------------------------------------|
  // | input data  |  Sorted data  | child's data      |
  // | ( I tupps ) |  ( 1 tupp )   | ( C tupps )       |
  // |-------------------------------------------------|
  // <-- returned row to parent --->
  // <------------ returned row from child ------------>
  //
  // input data:        the atp input to this node by its parent.
  // sorted data:       tupp where the sorted row is.
  //                    this data is accessed by the key and by the data
  //                    separately.
  //                    The key data is in SQLMX_KEY_FORMAT and the data
  //                    will be in either internal or exploded format.
  // child data:        tupps appended by the child
  //
  // Input to child:    I + 1 tupps
  //
  // Tupps returned from child are only used to create the
  // sorted data. They are not returned to parent.
  //
  /////////////////////////////////////////////////////////////////////////
  // Tupps returned from child are only used to create the
  // sorted data. They are not returned to parent.
  //
  /////////////////////////////////////////////////////////////////////////

  MapTable * last_map_table = generator->getLastMapTable();

  ex_cri_desc * given_desc
    = generator->getCriDesc(Generator::DOWN);

  ex_cri_desc * returned_desc
    = new(space) ex_cri_desc(given_desc->noTuples() + 1, space);

  Int32 work_atp = 1; // temps
  Int32 work_atp_index = 2;  // where the result row will be
  ex_cri_desc * work_cri_desc = new(space) ex_cri_desc(3, space);

  //All the records in the table will not be processed by a single sort 
  //instance if multiple sort instances are involved within ESPs.
  Lng32 saveNumEsps = generator->getNumESPs();
  
  if (sortFromTop())
    generator->setCriDesc(returned_desc, Generator::DOWN);

  // generate code for child tree
  child(0)->codeGen(generator);
  
  //This value is set inside generator by my parent exchange node,
  //as a global variable. Reset the saveNumEsps value back into
  //generator since codegen of my children exchange nodes may have
  //changed it. Resetting is performed here so the codegen of right
  //child nodes of my parent gets the proper value.  
  generator->setNumESPs(saveNumEsps);
  
  ComTdb * child_tdb = (ComTdb *)(generator->getGenObj());
  ExplainTuple *childExplainTuple = generator->getExplainTuple();

  // Before generating any expression for this node, set the
  // the expression generation flag not to generate float
  // validation PCode. This is to speed up PCode evaluation
  generator->setGenNoFloatValidatePCode(TRUE);

  // generate an expression to create the input row
  // to be sent to sort.
  // The input row consists of:
  //   n + m values
  // where, n is the number of encoded key columns.
  //        m is the total number of column values.
  // At runtime, a contiguous row of n + m columns is created
  // and then given to sort.
  // sort prefix key columns are indexed from 0 to k where k < n.


  // The data within the Sort buffer will be contiguous in the format
  // | encoded keys | returned column values |
  // ----------------------------------------
  // The keys will be in key format.
  // The returned column values will be in Exploded or Compressed internal
  // format.

  // generate the key encode value id list used for sorting
  UInt32  sortKeyLen = 0;
  UInt32  sortPrefixKeyLen = 0;
  Int32   prefixKeyCnt = getPrefixSortKey().entries();
  ValueIdList sortKeyValIdList;
  CollIndex   sortKeyListIndex;
  CollIndex   sortRecListIndex;
  for (sortKeyListIndex = 0;
       sortKeyListIndex < getSortKey().entries();
       sortKeyListIndex++)
    {
      ItemExpr * skey_node =
        ((getSortKey()[sortKeyListIndex]).getValueDesc())->getItemExpr();

      short desc_flag = FALSE;

      if (skey_node->getOperatorType() == ITM_INVERSE)
	{
	  desc_flag = TRUE;
	}

      if (skey_node->getValueId().getType().getVarLenHdrSize() > 0)
	{
	  // Explode varchars by moving them to a fixed field
	  // whose length is equal to the max length of varchar.
	  // 5/8/98: add support for VARNCHAR

          const CharType& char_type =
		(CharType&)(skey_node->getValueId().getType());

          //no cast to fixed char in the case of collation (Czech) 
          if (!CollationInfo::isSystemCollation(char_type.getCollation()))
	  {
	    skey_node =
	      new(generator->wHeap())
		Cast (skey_node,
		      (new(generator->wHeap())
			 SQLChar(generator->wHeap(),
                          CharLenInfo(char_type.getStrCharLimit(), char_type.getDataStorageSize()),
			  char_type.supportsSQLnull(),
			  FALSE, FALSE, FALSE,
			  char_type.getCharSet(),
			  char_type.getCollation(),
			  char_type.getCoercibility()
				)
		     )
		    );
	  }
	}

      CompEncode * enode
	= new(generator->wHeap()) CompEncode(skey_node, desc_flag);

      enode->bindNode(generator->getBindWA());

      sortKeyLen += enode->getValueId().getType().getTotalSize();

      sortKeyValIdList.insert(enode->getValueId());

      if (sortKeyListIndex < (CollIndex) prefixKeyCnt)
        // sort key length is the prefix sort key length
        // Note we need do this assignment only once. Need a better way
        sortPrefixKeyLen = sortKeyLen;
    }
/*
  // Generate the key encode expression ...
  ex_expr * sortKeyExpr = 0;
  exp_gen->generateContiguousMoveExpr(sortKeyValIdList,
                                      0,     // no conv nodes
                                      work_atp, work_atp_index,
                                      ExpTupleDesc::SQLMX_KEY_FORMAT,
                                      sortKeyLen, &sortKeyExpr,
                                      0,  // no tupp descr
                                      ExpTupleDesc::SHORT_FORMAT);
*/
  // Now generate the returned column value value id list that moves the input
  // data into the sort input buffer using convert nodes.
  ValueIdList sortRecValIdList;
  ValueId     valId;
  for (valId = getGroupAttr()->getCharacteristicOutputs().init();
       getGroupAttr()->getCharacteristicOutputs().next(valId);
       getGroupAttr()->getCharacteristicOutputs().advance(valId))
    {
      // add the convert node
      Convert * convNode = new(generator->wHeap())Convert(valId.getItemExpr());
      convNode->bindNode(generator->getBindWA());
      sortRecValIdList.insert(convNode->getValueId());
    }

  UInt32 sortRecLen = 0;
  ex_expr * sortRecExpr = 0;
  ex_expr * sortKeyExpr = 0;
  ExpTupleDesc * tuple_desc = 0;


  // contains the value ids that are being returned (the sorted values)
  MapTable * returnedMapTable = 0;
  ExpTupleDesc::TupleDataFormat tupleFormat = generator->getInternalFormat();

  // resizeCifRecord indicator that tells us whether we need to resize the CIF row or not
  // if CIF is not used then no resizing is done
  // if CIF is used the based on some logic that will be defined we determine whether we need
  // to resize the row or not
  NABoolean resizeCifRecord = FALSE;
  // Sometimes only the key value id list has entries and there are no
  // additional characteristic outputs.
  // This happens when Sort is used as a blocking operator for NAR (Non Atomic
  // Rowsets).
  NABoolean bmo_affinity = (CmpCommon::getDefault(COMPRESSED_INTERNAL_FORMAT_BMO_AFFINITY) == DF_ON);
  NABoolean considerBufferDefrag = FALSE;

  if (sortRecValIdList.entries() > 0)
  {
    if (! bmo_affinity &&
        getCachedTupleFormat() != ExpTupleDesc::UNINITIALIZED_FORMAT &&
        CmpCommon::getDefault(COMPRESSED_INTERNAL_FORMAT) == DF_SYSTEM &&
        CmpCommon::getDefault(COMPRESSED_INTERNAL_FORMAT_BMO) == DF_SYSTEM)
    {
      resizeCifRecord = getCachedResizeCIFRecord();
      tupleFormat = getCachedTupleFormat();
      considerBufferDefrag = getCachedDefrag() && resizeCifRecord;
    }
    else
    {
      //apply heuristic to determine the tuple format and whether we need to resize the row or not
     tupleFormat = determineInternalFormat( sortRecValIdList,
                                            this,
                                            resizeCifRecord,
                                            generator,
                                            bmo_affinity,
                                            considerBufferDefrag);
     considerBufferDefrag = considerBufferDefrag && resizeCifRecord;
    }

  }


  if (tupleFormat == ExpTupleDesc::SQLMX_ALIGNED_FORMAT)
  {
    exp_gen->generateContiguousMoveExpr(sortKeyValIdList,
                                         0,     // no conv nodes
                                         work_atp, work_atp_index,
                                         ExpTupleDesc::SQLMX_KEY_FORMAT,
                                         sortKeyLen, &sortKeyExpr,
                                         0,  // no tupp descr
                                         ExpTupleDesc::SHORT_FORMAT);

    exp_gen->generateContiguousMoveExpr(sortRecValIdList,
                                        0,   // no convert nodes
                                        work_atp, work_atp_index,
                                        tupleFormat,
                                        sortRecLen, &sortRecExpr,
                                        &tuple_desc, ExpTupleDesc::SHORT_FORMAT);
    sortRecLen += sortKeyLen;
    if (resizeCifRecord)
    {
      // with CIF if we need to resize the rows then we need to keep track of the length
      // of the row with the row itself
      // in this case the allocated space for the row will be as folows
      // |row size --(4 bytes)|sort key (sortkeyLen)| data (data length --may be variable)  |
      // ------------------------------------
      sortRecLen += sizeof(UInt32);
    }
  }
  else
  {
    CMPASSERT(resizeCifRecord == FALSE);
    sortKeyValIdList.insertSet(sortRecValIdList);
    exp_gen->generateContiguousMoveExpr(sortKeyValIdList,
                                          0,     // no conv nodes
                                          work_atp, work_atp_index,
                                          ExpTupleDesc::SQLARK_EXPLODED_FORMAT,
                                          sortRecLen, &sortRecExpr,
                                          &tuple_desc,
                                          ExpTupleDesc::SHORT_FORMAT);

  }


  // add in the total area for the keys since we generated this separately
  // and ensure the size is a factor of 8 so the data aligns correctly


  


  // describe the returned row
  returned_desc->setTupleDescriptor((UInt16)returned_desc->noTuples() - 1,
                                    tuple_desc);

  returnedMapTable = generator->appendAtEnd(); // allocates a new map table
  generator->unlinkLast();

  // Add the returned values to the map table. We get the returned value
  // value id from the char outputs and the item expr from the sort record
  // value id list, starting with the first item expr added to the sort
  // record value id list by the for loop immediately preceding this one.
  sortRecListIndex = 0;
  for (valId = getGroupAttr()->getCharacteristicOutputs().init();
       getGroupAttr()->getCharacteristicOutputs().next(valId);
       getGroupAttr()->getCharacteristicOutputs().advance(valId))
    {
      // ????????????The first time through this loop, sortRecListIndex will point
      // to the first return value convert node. This is because we
      // stopped incrementing the sortRecListIndex after the last sort
      // key was added and we did not increment it when we added the
      // return value convert nodes.
      Attributes *attr =
        generator->getMapInfo(sortRecValIdList[sortRecListIndex++])->getAttr();

      // ...add it to the new map table as if it belonged to
      // the original value id...
      MapInfo * mi =
	generator->addMapInfoToThis(returnedMapTable, valId, attr);

      // All reference to the returned values from this point on
      // will be at atp = 0, atp_index = last entry in returned desc.
      // Offset will be the same as in the workAtp.
      mi->getAttr()->setAtp(0);
      mi->getAttr()->setAtpIndex(returned_desc->noTuples() - 1);

      // ... and make sure no more code gets generated for it.
      mi->codeGenerated();

    }

  // remove all appended map tables and return the returnedMapTable
  generator->removeAll(last_map_table);
  generator->appendAtEnd(returnedMapTable);

  short rc =
    generateTdb(generator,
		child_tdb,
		sortKeyExpr,
                sortRecExpr,
		sortKeyLen,
		sortRecLen,
		sortPrefixKeyLen,
		given_desc,
		returned_desc,
		work_cri_desc,
		saveNumEsps,
		childExplainTuple,
		resizeCifRecord,
		considerBufferDefrag,
		(tupleFormat == ExpTupleDesc::SQLMX_ALIGNED_FORMAT));

  return rc;
}


ExpTupleDesc::TupleDataFormat Sort::determineInternalFormat( const ValueIdList & valIdList,
                                                                   RelExpr * relExpr,
                                                                   NABoolean & resizeCifRecord,
                                                                   Generator * generator,
                                                                   NABoolean bmo_affinity,
                                                                   NABoolean & considerBufferDefrag)
{

  RelExpr::CifUseOptions bmo_cif = RelExpr::CIF_SYSTEM;


  if (CmpCommon::getDefault(COMPRESSED_INTERNAL_FORMAT_BMO) == DF_OFF)
  {
    bmo_cif = RelExpr::CIF_OFF;
  }
  else
  if (CmpCommon::getDefault(COMPRESSED_INTERNAL_FORMAT_BMO) == DF_ON)
  {
    bmo_cif = RelExpr::CIF_ON;
  }

  //CIF_SYSTEM

  UInt32 sortKeyLength = getSortKey().getRowLength();
  return generator->determineInternalFormat(valIdList, 
                                            relExpr, 
                                            resizeCifRecord, 
                                            bmo_cif,
                                            bmo_affinity,
                                            considerBufferDefrag,
                                            sortKeyLength);

}
//////////////////////////////////////////////////////////////
//
// SortFromTop::codeGen()
//
/////////////////////////////////////////////////////////
short SortFromTop::codeGen(Generator * generator)
{
  ExpGenerator * exp_gen = generator->getExpGenerator();
  Space * space = generator->getSpace();

  MapTable * last_map_table = generator->getLastMapTable();

  ex_cri_desc * given_desc
    = generator->getCriDesc(Generator::DOWN);

  // no tuples returned from this operator
  ex_cri_desc * returned_desc = given_desc;

  // child gets one sorted row created in this operator.
  ex_cri_desc * child_desc
    = new(space) ex_cri_desc(given_desc->noTuples() + 1, space);

  Int32 work_atp = 1; // temps
  Int32 work_atp_index = 2;  // where the result row will be
  ex_cri_desc * work_cri_desc = new(space) ex_cri_desc(3, space);

  //All the records in the table will not be processed by a single sort 
  //instance if multiple sort instances are involved within ESPs.
  Lng32 saveNumEsps = generator->getNumESPs();

  generator->setCriDesc(child_desc, Generator::DOWN);

  // Before generating any expression for this node, set the
  // the expression generation flag not to generate float
  // validation PCode. This is to speed up PCode evaluation
  generator->setGenNoFloatValidatePCode(TRUE);

  MapTable *myMapTable = generator->appendAtEnd();
  
  ULng32 sort_rec_len = 0;
  ULng32 sort_key_len = 0;
  ex_expr * sort_rec_expr = 0;
  ex_expr * sort_key_expr = 0;
  ExpTupleDesc * tuple_desc = 0;

  ValueIdList sortRecVIDlist;
  ValueIdList sortKeyVIDlist;
  CollIndex ii = 0;
  for (ii = 0; ii < getSortKey().entries(); ii++)
    {
      ItemExpr * skey_node =
        ((getSortKey()[ii]).getValueDesc())->getItemExpr();

      if (skey_node->getOperatorType() != ITM_INDEXCOLUMN)
	GenAssert(0, "Must be IndexColumn");

      IndexColumn * ic = (IndexColumn*)skey_node;
      NABoolean found = FALSE;
      CollIndex jj = 0;
      while ((NOT found) && (jj < getSortRecExpr().entries()))
	{
	  const ItemExpr *assignExpr = 
	    getSortRecExpr()[jj].getItemExpr();

	  ItemExpr * tgtCol = assignExpr->child(0)->castToItemExpr();
	  if (tgtCol->getOperatorType() != ITM_BASECOLUMN)
	    GenAssert(0, "Must be BaseColumn");

	  ValueId tgtValueId = tgtCol->getValueId();

	  ValueId srcValueId = 
	    assignExpr->child(1)->castToItemExpr()->getValueId();

	  ItemExpr * srcVal = assignExpr->child(1)->castToItemExpr();

	  if (ic->getNAColumn()->getColName() == 
	      ((BaseColumn*)tgtCol)->getNAColumn()->getColName())
	    {
	      found = TRUE;

	      //***TBD*** need to handle descnding. Get that from index desc.
	      short desc_flag = FALSE;
	      if (ic->getNAColumn()->getClusteringKeyOrdering() == DESCENDING)
		{
		  desc_flag = TRUE;
		}

	      if (skey_node->getValueId().getType().getVarLenHdrSize() > 0)
		{
		  // Explode varchars by moving them to a fixed field
		  // whose length is equal to the max length of varchar.
		  
		  const CharType& char_type =
		    (CharType&)(skey_node->getValueId().getType());
		  
		  //no cast to fixed char in the case of collation (Czech) 
		  if (!CollationInfo::isSystemCollation(char_type.getCollation()))
		    {
		      skey_node =
			new(generator->wHeap())
			Cast (srcVal,
			      (new(generator->wHeap())
			       SQLChar(generator->wHeap(),
                                    CharLenInfo(char_type.getStrCharLimit(), char_type.getDataStorageSize()),
				    char_type.supportsSQLnull(),
				    FALSE, FALSE, FALSE,
				    char_type.getCharSet(),
				    char_type.getCollation(),
				    char_type.getCoercibility()
				    )
			       )
			      );
		    }
		}
	      else
		{
		  skey_node = new(generator->wHeap()) 
		    Cast(srcVal, &tgtValueId.getType());
		}

	      CompEncode * enode
		= new(generator->wHeap()) CompEncode(skey_node, desc_flag);
	      
	      enode->bindNode(generator->getBindWA());
	      
	      sort_key_len += enode->getValueId().getType().getTotalSize();
	      
	      sortKeyVIDlist.insert(enode->getValueId()); 
	    } // if
	  
	  jj++;
	} // while
      
      if (NOT found)
	{
	  GenAssert(0, "Key not found in newRecExprArray");
	}
    } // for
  // genearate sort key expr
  //ex_expr * sort_key_expr = 0;
  if (sortKeyVIDlist.entries() > 0)
  {
    exp_gen->generateContiguousMoveExpr(sortKeyVIDlist,
                                      0,     // no conv nodes
                                      work_atp, work_atp_index,
                                      ExpTupleDesc::SQLMX_KEY_FORMAT,
                                      sort_key_len, &sort_key_expr,
                                      0,  // no tupp descr
                                      ExpTupleDesc::SHORT_FORMAT);
  
  }
  //sortRecVIDlist = sortKeyVIDlist;

  for (ii = 0; ii < getSortRecExpr().entries(); ii++)
    {
      const ItemExpr *assignExpr = 
	getSortRecExpr()[ii].getItemExpr();
      
      ValueId tgtValueId = 
	assignExpr->child(0)->castToItemExpr()->getValueId();
      ValueId srcValueId = 
	assignExpr->child(1)->castToItemExpr()->getValueId();
      
      ItemExpr * ie = NULL;
      ie = new(generator->wHeap())
	Cast(assignExpr->child(1), 
	     &tgtValueId.getType());
      
      ie->bindNode(generator->getBindWA());
      sortRecVIDlist.insert(ie->getValueId());
    } // for

  ExpTupleDesc::TupleDataFormat tupleFormat = generator->getInternalFormat();
  NABoolean resizeCifRecord = FALSE;
  NABoolean considerBufferDefrag = FALSE;

  if (sortRecVIDlist.entries()>0)
  {
    tupleFormat = determineInternalFormat( sortRecVIDlist,
                                           this,
                                           resizeCifRecord,
                                           generator,
                                           FALSE,
                                           considerBufferDefrag);

    exp_gen->generateContiguousMoveExpr(sortRecVIDlist, 
				      0 /*don't add conv nodes*/,
				      work_atp, work_atp_index,
				      tupleFormat,
				      sort_rec_len, &sort_rec_expr,
				      &tuple_desc, ExpTupleDesc::SHORT_FORMAT);
  }
  //sort_key_len = ROUND8(sort_key_len); ?????????

  sort_rec_len += sort_key_len;

  if (resizeCifRecord)
  {
    // with CIF if we need to resize the rows then we need to keep track of the length
    // of the row with the row itself
    // in this case the allocated space for the row will be as folows
    // |row size --(4 bytes)|sort key (sortkeyLen)| data (data length --may be variable)  |
    // ------------------------------------
    sort_rec_len += sizeof(UInt32);
  }


  for (CollIndex i = 0; i < (CollIndex) sortRecVIDlist.entries(); i++)
    {
      ItemExpr * cn = (sortRecVIDlist[i]).getItemExpr();
      
      Attributes *attrib =
	generator->getMapInfo(cn->getValueId())->getAttr();
      
      MapInfo * mi =
	generator->
	addMapInfoToThis(myMapTable, 
			 cn->child(0)->castToItemExpr()->getValueId(), 
			 attrib);
      
      // All reference to the sorted values from this point on
      // will be at atp = 0, atp_index = last entry in child desc.
      // Offset will be the same as in the workAtp.
      mi->getAttr()->setAtp(0);
      mi->getAttr()->setAtpIndex(child_desc->noTuples() - 1);

      // ... and make sure no more code gets generated for it.
      mi->codeGenerated();
    }

  // generate code for child tree
  child(0)->codeGen(generator);
  
  //This value is set inside generator by my parent exchange node,
  //as a global variable. Reset the saveNumEsps value back into
  //generator since codegen of my children exchange nodes may have
  //changed it. Resetting is performed here so the codegen of right
  //child nodes of my parent gets the proper value.  
  generator->setNumESPs(saveNumEsps);
  
  ComTdb * child_tdb = (ComTdb *)(generator->getGenObj());
  ExplainTuple *childExplainTuple = generator->getExplainTuple();

  // remove all appended map tables. No values are returned by
  // this node.
  generator->removeAll(last_map_table);

  short rc =
    generateTdb(generator,
		child_tdb,
                sort_key_expr,
		sort_rec_expr,
		sort_key_len,
		sort_rec_len,
		0, //sort_prefix_key_len,
		given_desc,
		child_desc,
		work_cri_desc,
		saveNumEsps,
		childExplainTuple,
		resizeCifRecord,
		considerBufferDefrag);

  return rc;
}

CostScalar Sort::getEstimatedRunTimeMemoryUsage(Generator *generator, NABoolean perNode, Lng32 *numStreams)
{
  GroupAttributes * childGroupAttr = child(0).getGroupAttr();
  Lng32 childRecordSize = 
      childGroupAttr->getCharacteristicOutputs().getRowLength();
  CostScalar rowsUsed;
  if (sortNRows() && (topNRows_ > 0)
            && (topNRows_ <= getDefault(GEN_SORT_TOPN_THRESHOLD)))
     rowsUsed = topNRows_; 
  else
     rowsUsed = getEstRowsUsed();
  CostScalar totalMemory = rowsUsed * childRecordSize;
  CostScalar estMemPerNode;
  CostScalar estMemPerInst;
 
  //TODO: Line below dumps core at times 
  //const CostScalar maxCard = childGroupAttr->getResultMaxCardinalityForEmptyInput();
  const CostScalar maxCard = 0;

  Lng32 numOfStreams = 1;
  const PhysicalProperty* const phyProp = getPhysicalProperty();
  if (phyProp != NULL)
  {
     PartitioningFunction * partFunc = phyProp -> getPartitioningFunction() ;
     numOfStreams = partFunc->getCountOfPartitions();
     if (numOfStreams <= 0)
        numOfStreams = 1;
  }
  if (numStreams != NULL)
     *numStreams = numOfStreams;
  estMemPerNode = totalMemory / MINOF(MAXOF(gpClusterInfo->getTotalNumberOfCPUs(), 1), numOfStreams);
  estMemPerInst = totalMemory / numOfStreams;
  OperBMOQuota *operBMOQuota = new (generator->wHeap()) OperBMOQuota(getKey(), numOfStreams,
                                                  estMemPerNode, estMemPerInst, rowsUsed, maxCard);
  generator->getBMOQuotaMap()->insert(operBMOQuota);
  if (perNode)
     return estMemPerNode;
  else
     return estMemPerInst; 
}

/////////////////////////////////////////////////////////
//
// Tuple::codeGen()
//
/////////////////////////////////////////////////////////
short Tuple::codeGen(Generator * generator)
{
  // code generation for this node doesn't do anything.
  // A Tuple node returns one tuple of expression of constants. This
  // expression is evaluated where it is used. Since this node doesn't
  // produce anything, the returned cri desc is same as the input cri desc.
  // We could do away with generating something here but the
  // parent node expects a child node to return 'something' before it
  // can continue.
  Queue * qList = new(generator->getSpace()) Queue(generator->getSpace());
  ExpGenerator *expGen = generator->getExpGenerator();

  // expression to conditionally return 0 or more rows.
  ex_expr *predExpr = NULL;

  // generate tuple selection expression, if present
  if(NOT selectionPred().isEmpty())
  {
    ItemExpr* pred = selectionPred().rebuildExprTree(ITM_AND,TRUE,TRUE);
    expGen->generateExpr(pred->getValueId(),ex_expr::exp_SCAN_PRED,&predExpr);
  }

  ComTdbTupleLeaf *tuple_tdb = new(generator->getSpace())
    ComTdbTupleLeaf(qList,
		    0, // no tuple returned. Length = 0.
		    0, // no tupp index
		    predExpr,
                    generator->getCriDesc(Generator::DOWN),
		    generator->getCriDesc(Generator::DOWN),
		    (queue_index)getDefault(GEN_TUPL_SIZE_DOWN),
		    (queue_index)getDefault(GEN_TUPL_SIZE_UP),
		    (Cardinality) (getInputCardinality() * getEstRowsUsed()).getValue(),
		    getDefault(GEN_TUPL_NUM_BUFFERS),
		    getDefault(GEN_TUPL_BUFFER_SIZE));
  generator->initTdbFields(tuple_tdb);

  if(!generator->explainDisabled()) {
    generator->setExplainTuple(
	 addExplainInfo(tuple_tdb, 0, 0, generator));
  }

  generator->setGenObj(this, tuple_tdb);
  generator->setCriDesc(generator->getCriDesc(Generator::DOWN),
			Generator::UP);

  return 0;
}

/////////////////////////////////////////////////////////
//
// TupleList::codeGen()
//
/////////////////////////////////////////////////////////
short TupleList::codeGen(Generator * generator)
{
  Space * space          = generator->getSpace();
  ExpGenerator * expGen  = generator->getExpGenerator();
  ex_cri_desc * givenDesc
    = generator->getCriDesc(Generator::DOWN);
  ex_cri_desc * returnedDesc
    = new(space) ex_cri_desc(givenDesc->noTuples() + 1, space);
  Int32 tuppIndex = returnedDesc->noTuples() - 1;

  // disable common subexpression elimination for now.
  // There is a problem which shows up due to common subexpression
  // elimination. See case 10-040402-2209.
  // After the problem is diagnosed and fixed in tuple list,
  // we won't need to disable subexp elimination.
  generator->getExpGenerator()->setEnableCommonSubexpressionElimination(FALSE);

  Queue * qList = new(generator->getSpace()) Queue(generator->getSpace());
  ULng32 tupleLen = 0;
  ExpTupleDesc * tupleDesc = 0;
  ExprValueId eVid(tupleExprTree());
  ItemExprTreeAsList tupleList(&eVid, ITM_ITEM_LIST);
  CollIndex nTupEntries = (CollIndex) tupleList.entries();
  for (CollIndex i = 0; i < nTupEntries; i++)
    {
      ex_expr * moveExpr = NULL;

      ItemExpr * tuple =
	((ItemExpr *) tupleList[i])->child(0)->castToItemExpr();

      ExprValueId tVid(tuple);
      ItemExprTreeAsList tupleTree(&tVid, ITM_ITEM_LIST);

      ValueIdList convVIDlist;
      BindWA *bindWA = generator->getBindWA();

      NABoolean castTo = castToList().entries() > 0;
      for (CollIndex j = 0; j < tupleExpr().entries(); j++)
	{
	  ItemExpr * castNode = tupleExpr()[j].getItemExpr();
	  ItemExpr * childNode = (ItemExpr *) tupleTree[j];
          if (castTo)
          {
	    // When we have ins/upd target cols which are
	    // MP NCHAR in MX-NSK-Rel1 (i.e., SINGLE-byte),
	    // and the source was from a Tuple/TupleList,
	    // then we must do some magic Assign binding
	    // to ensure that the single-byte even-num-of-bytes
	    // "constraint" is not violated.
	    //
	    // Build + copy this "constraint" --
	    // NOTE:  tmpAssign MUST BE ON HEAP -- see TupleList::bindNode() !

	    Assign *tmpAssign = new(bindWA->wHeap())
	      Assign(castToList()[j].getItemExpr(), childNode);

            //***************************************************************
            // 10-0414-2428: Note that this assign is for inserts or updates
            // (1) castTo is set only when insert DMLs
            // (2) Assign constructor argument UserSpecified is set to TRUE
            //***************************************************************
            setInUpdateOrInsert(bindWA, NULL, REL_INSERT);
	    tmpAssign = (Assign *)tmpAssign->bindNode(bindWA);
            setInUpdateOrInsert(bindWA, NULL);
	    childNode = tmpAssign->getSource().getItemExpr();
            //don't allow LOB insert in a tuple list
            if (childNode->getOperatorType() == ITM_LOBINSERT)
              {                                                          
                // cannot have this function in a values list with
                // multiple tuples. Use a single tuple.
                *CmpCommon::diags() << DgSqlCode(-4483);
                GenExit();
                return -1;
                        
              }
            castNode->child(0) = childNode;
          }
          else
          {
            childNode = childNode->bindNode(bindWA);

            if ( (castNode->child(0)) &&
                (castNode->child(0)->getOperatorType() == ITM_INSTANTIATE_NULL) )
            {
              // if this tuplelist is part of a subquery an additional node
              // of type ITM_INSTANTIATE_NULL is placed in the binder; check if
              // that is the case
              castNode->child(0)->child(0) = childNode; // need to fix this
            }
            else
            {
              castNode->child(0) = childNode;
            }
          }

          castNode->bindNode(bindWA);

	  // if any unknown type in the tuple,
	  // coerce it to the target type.
	  childNode->bindNode(bindWA);
	  childNode->getValueId().coerceType(castNode->getValueId().getType());

	  MapInfo * mInfo = generator->getMapInfoAsIs(castNode->getValueId());
	  if (mInfo)
	    mInfo->resetCodeGenerated();
	  castNode->unmarkAsPreCodeGenned();
	  convVIDlist.insert(castNode->getValueId());
	}

      GenAssert(!bindWA->errStatus(), "bindWA");
      expGen->generateContiguousMoveExpr(convVIDlist,
					 0 /*don't add conv nodes*/,
					 0 /*atp*/,
					 tuppIndex,
					 generator->getInternalFormat(),
					 tupleLen,
					 &moveExpr,
					 &tupleDesc,
					 ExpTupleDesc::SHORT_FORMAT);
      qList->insert(moveExpr);
    }

  returnedDesc->setTupleDescriptor(tuppIndex, tupleDesc);

  // generate expression for selection predicate, if it exists
  ex_expr *predExpr = NULL;
  if(NOT selectionPred().isEmpty())
  {
    ItemExpr* pred = selectionPred().rebuildExprTree(ITM_AND,TRUE,TRUE);
    expGen->generateExpr(pred->getValueId(),ex_expr::exp_SCAN_PRED,
             &predExpr);
  }

  // Compute the buffer size based on upqueue size and row size.
  // Try to get enough buffer space to hold twice as many records
  // as the up queue.
  ULng32 buffersize = getDefault(GEN_TUPL_BUFFER_SIZE);
  Int32 numBuffers = getDefault(GEN_TUPL_NUM_BUFFERS);
  queue_index upqueuelength = (queue_index)getDefault(GEN_TUPL_SIZE_UP);
  ULng32 cbuffersize =
    ((tupleLen + sizeof(tupp_descriptor))
     * (upqueuelength * 2/numBuffers)) +
    SqlBufferNeededSize(0,0);
  buffersize = buffersize > cbuffersize ? buffersize : cbuffersize;

  ComTdbTupleLeaf *tupleTdb = new(generator->getSpace())
    ComTdbTupleLeaf(qList,
		    tupleLen,
		    tuppIndex,
		    predExpr,
                    givenDesc,
		    returnedDesc,
		    (queue_index)getDefault(GEN_TUPL_SIZE_DOWN),
		    (queue_index)upqueuelength,
		    (Cardinality) (getInputCardinality() * getEstRowsUsed()).getValue(),
		    getDefault(GEN_TUPL_NUM_BUFFERS),
		    buffersize);
  generator->initTdbFields(tupleTdb);

  if(!generator->explainDisabled())
    {
      generator->setExplainTuple(
	   addExplainInfo(tupleTdb, 0, 0, generator));
    }

  generator->setGenObj(this, tupleTdb);
  generator->setCriDesc(givenDesc, Generator::DOWN);
  generator->setCriDesc(returnedDesc, Generator::UP);

  return 0;
}

/////////////////////////////////////////////////////////
//
// ExplainFunc::codeGen()
//
/////////////////////////////////////////////////////////
short ExplainFunc::codeGen(Generator * generator)
{
  ExpGenerator * expGen = generator->getExpGenerator();
  Space * space = generator->getSpace();

  // allocate a map table for the retrieved columns
  generator->appendAtEnd();

  ex_expr *explainExpr = 0;

  ex_cri_desc * givenDesc
    = generator->getCriDesc(Generator::DOWN);

  ex_cri_desc * returnedDesc
    = new(space) ex_cri_desc(givenDesc->noTuples() + 1, space);

  ex_cri_desc * paramsDesc
    = new(space) ex_cri_desc(givenDesc->noTuples() + 1, space);


  // Assumption (for now): retrievedCols contains ALL columns from
  // the table/index. This is because this operator does
  // not support projection of columns. Add all columns from this table
  // to the map table.
  //
  // The row retrieved from filesystem is returned as the last entry in
  // the returned atp.

  const ValueIdList & columnList = getTableDesc()->getColumnList();
  const CollIndex numColumns = columnList.entries();

  Attributes ** attrs = new(generator->wHeap()) Attributes * [numColumns];

  for (CollIndex i = 0; i < numColumns; i++)
    {
     ItemExpr * col_node = ((columnList[i]).getValueDesc())->getItemExpr();

      attrs[i] = (generator->addMapInfo(col_node->getValueId(), 0))->
	getAttr();
    }

  ExpTupleDesc *explTupleDesc = 0;
  ULng32 explTupleLength = 0;
  expGen->processAttributes(numColumns,
			    attrs, ExpTupleDesc::SQLARK_EXPLODED_FORMAT,
			    explTupleLength,
			    0, returnedDesc->noTuples() - 1,
			    &explTupleDesc, ExpTupleDesc::SHORT_FORMAT);

  // delete [] attrs;
  // NADELETEBASIC is used because compiler does not support delete[]
  // operator yet. Should be changed back later when compiler supports
  // it.
  NADELETEBASIC(attrs, generator->wHeap());

  // add this descriptor to the work cri descriptor.
  returnedDesc->setTupleDescriptor(returnedDesc->noTuples()-1, explTupleDesc);

  // generate explain selection expression, if present
  if (! selectionPred().isEmpty())
   {
     ItemExpr * newPredTree = selectionPred().rebuildExprTree(ITM_AND,TRUE,TRUE);
     expGen->generateExpr(newPredTree->getValueId(), ex_expr::exp_SCAN_PRED,
			   &explainExpr);
   }

  // generate move expression for the parameter list
  ex_expr *moveExpr = 0;

  ExpTupleDesc *tupleDesc = 0;
  ULng32 tupleLength = 0;
  if (! getProcInputParamsVids().isEmpty())
    {

      expGen->generateContiguousMoveExpr(getProcInputParamsVids(),
					 -1,
					 0,
					 paramsDesc->noTuples()-1,
					 ExpTupleDesc::SQLARK_EXPLODED_FORMAT,
					 tupleLength,
					 &moveExpr,
					 &tupleDesc,
					 ExpTupleDesc::LONG_FORMAT);

      // add this descriptor to the work cri descriptor.
      paramsDesc->setTupleDescriptor(paramsDesc->noTuples()-1, tupleDesc);
    }

  // allocate buffer space to contain atleast 2 rows.
  ULng32 bufferSize = (explTupleLength+100/*padding*/) * 2/*rows*/;
  bufferSize = MAXOF(bufferSize, 30000); // min buf size 30000
  Int32 numBuffers = 3; // allocate 3 buffers

  ComTdbExplain *explainTdb
    = new(space)
      ComTdbExplain(givenDesc,	                 // given_cri_desc
		    returnedDesc,		 // returned cri desc
		    8,				 // Down queue size
		    16,				 // Up queue size0
		    returnedDesc->noTuples() - 1, // Index in atp of return
		    // tuple.
		    explainExpr,			 // predicate
		    paramsDesc,			 // Descriptor of params Atp
		    tupleLength,			 // Length of params Tuple
		    moveExpr,			 // expression to calculate
						 // the explain parameters
		    numBuffers,			 // Number of buffers to allocate
                    bufferSize);			 // Size of each buffer
  generator->initTdbFields(explainTdb);

  // Add the explain Information for this node to the EXPLAIN
  // Fragment.  Set the explainTuple pointer in the generator so
  // the parent of this node can get a handle on this explainTuple.
  if(!generator->explainDisabled()) {
    generator->setExplainTuple(
       addExplainInfo(explainTdb, 0, 0, generator));
  }
  generator->setCriDesc(givenDesc, Generator::DOWN);
  generator->setCriDesc(returnedDesc, Generator::UP);
  generator->setGenObj(this, explainTdb);

  return 0;
}

// PhysTranspose::codeGen() ------------------------------------------
// Generate code (a TDB node with corresponding Expr expressions) for
// the PhysTranspose node.  This node implements the TRANSPOSE operator.
//
// Parameters:
//
// Generator *generator
//    IN/OUT : A pointer to the generator object which contains the state,
//             and tools (e.g. expression generator) to generate code for
//             this node.
//
// Side Effects: Generates an ComTdbTranspose along with all the required
//               expressions for the transpose node.
//
//               Generates explain info.
//
//               Alters the state of the generator, including modifing
//               the map table, setting references to the generated Tdb
//               and explain info. etc.
//
short
PhysTranspose::codeGen(Generator *generator)
{
  // Get handles on expression generator, map table, and heap allocator
  //
  ExpGenerator *expGen = generator->getExpGenerator();
  Space *space = generator->getSpace();

  // Allocate a new map table for this operation
  //
  MapTable *localMapTable = generator->appendAtEnd();

  // Generate the child and capture the task definition block and a description
  // of the reply composite row layout and the explain information.
  //
  child(0)->codeGen(generator);

  ComTdb *childTdb = (ComTdb*)(generator->getGenObj());

  ex_cri_desc *childCriDesc = generator->getCriDesc(Generator::UP);

  ExplainTuple *childExplainTuple = generator->getExplainTuple();


  // Generate the given and returned composite row descriptors
  // Transpose adds a tupp to the row returned by the *child*
  // or the Given row, if no columns of the child are outputs of
  // this node.
  //
  ex_cri_desc *givenCriDesc = generator->getCriDesc(Generator::DOWN);


  // Determine if any of the childs outputs are also outputs of the node.
  // (if not, then don't pass them up the queue, later we will remove them
  // from the map table.)
  //

  // Get the outputs of this node.
  //
  ValueIdSet transOutputs = getGroupAttr()->getCharacteristicOutputs();

  // Get all the ValueIds that this node generates.
  //
  ValueIdSet transVals;

  for(CollIndex v = 0; v < transUnionVectorSize(); v++) {
    transVals.insertList(transUnionVector()[v]);
  }

  // Remove from the outputs, those values that are generated by this
  // node. (if none are left, then the child's outputs are not needed
  // above, otherwise they are.)
  //
  transOutputs -= transVals;

  ex_cri_desc *returnedCriDesc = 0;

  if (transOutputs.isEmpty()) {

    // The child's outputs are not needed above, so do not pass them
    // along.
    //
    returnedCriDesc =
      new(space) ex_cri_desc(givenCriDesc->noTuples() + 1, space);

    // Make all of my child's outputs map to ATP 1. Since they are
    // not needed above, they will not be in the work ATP (0).
    // (Later, they will be reomved from the map table)
    //
    localMapTable->setAllAtp(1);

  } else {

    // The child's outputs are needed above, so must pass them along.
    //
    returnedCriDesc =
      new(space) ex_cri_desc(childCriDesc->noTuples() + 1, space);
  }

  // transposeCols is the last Tp in Atp 0.
  //
  const Int32 transColsAtpIndex = returnedCriDesc->noTuples() - 1;
  const Int32 transColsAtp = 0;

  // The length of the new tuple which will contain the columns
  // generated by transpose.
  //
  ULng32 transColsTupleLen;

  // The Transpose node contains 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. Each ValueIdUnion within a list must contain the same
  // number of elements.
  //

  // The cardinality of an entry in the vector is the number of entries
  // in each of its ValueIdUnion nodes.  The cardinality of the first
  // entry (the key values) is equal to the sum of the cardinalities of
  // the subsequent entries (the transpose values).

  // In order to generate the expressions for the transpose node the
  // ValueIdUnion nodes for the values expressions (entries 1 - 3 below)
  // have to be  indexed from 0 - N (0 - 6 in the example below).
  // In order to translate from an index from 0 - N to an index of the
  // vector and an index within the ValueIdUnion, numExprs contains the
  // number of ValExprs for each ValueIdUnion. Eg. if the transUnionVector
  // contains these entries:
  //
  // Vector Num
  // Entry  Entries Card.
  //   0     1       7      ValueIdUnion(1,2,3,4,5,6,7)
  //   1     1       2      ValueIdUnion(A,B)
  //   2     1       3      ValueIdUnion(X,Y,Z)
  //   3     2       2      ValueIdUnion(1,2) , ValueIdUnion('hello', 'world')
  //
  // Then numUnionLists would be 4
  //
  // The numKeyExprs would be 7 (the cardinality of the Key Values, see below)
  //
  // The total cardinality of the rest of the ValueIdUnions also equals 7.
  //
  // numExprs will have 4 (numUnionLists) entries with values 7, 2, 3 and 2.
  //
  // The number of entries in the transUnionVector.
  //
  CollIndex numUnionLists = transUnionVectorSize();

  // Allocate a vector of size numUnionLists to hold the cardinality of each
  // entry in the vector.
  //
  CollIndex *numExprs = new(space) CollIndex[numUnionLists];

  // The Tuple Desc describing the tuple containing the new transpose columns
  // It is generated when the expressions are generated.
  //
  ExpTupleDesc *transColsTupleDesc = 0;

  // Loop index used throughout
  //
  CollIndex unionListNum;

  // Used below for a sanity check (assert).
  //
  CollIndex totNumExprs = 0;

  // Populate the numExprs array.
  //
  for(unionListNum = 0; unionListNum < numUnionLists; unionListNum++) {

    // If the entry of the vector has at least one ValueIdUnion ...
    // (All ValueIdUnions in an entry of the vector should have the
    // same number of enties, so use the first entry)
    //
    if(transUnionVector()[unionListNum].entries() > 0)
      numExprs[unionListNum] =
	((ValueIdUnion *)(transUnionVector()[unionListNum])[0].
	 getValueDesc()->getItemExpr())->entries();
    else
      // If the keyCol was not specified, then the first entry of the
      // vector may contain no ValueIdUnion nodes.
      //
      numExprs[unionListNum] = 0;

    // Used in an assert below.
    //
    totNumExprs += numExprs[unionListNum];
  }

  // The number of Key Exprs. The item expressions should be the Constants
  // 1 -> numKeyExprs or non-existant. The Key Exprs are the first entry.
  //
  const CollIndex numKeyExprs = numExprs[0];

  // If there are no key expressions, the the number of expressions
  // to generate is the totNumExprs.
  //
  const CollIndex numMovExprs = (numKeyExprs == 0 ? totNumExprs : numKeyExprs);

  // The total number of item expressions in the value unions should equal
  // the number of key values in the first ValueIdUnion.
  //
  GenAssert(totNumExprs == numKeyExprs * 2 || numKeyExprs == 0,
	    "Transpose: Internal Error");

  // Allocate space to hold numMovExprs expressions. Each expression will
  // compute one value for each of the ValueIdUnions.
  // A constant Key Value will be computed in each expression,
  // but only value expressions from one vector entry will be computed.
  // All other value expressions will be NULL.
  //
  ex_expr ** transExprs = new(space)ex_expr*[numMovExprs];

  // A list of the ValueIds will be constructed and used to generate
  // the expressions
  //
  ValueIdList ValueIds;

  // A new item expression which casts the result to the proper type
  // will be constructed.
  //
  Cast *castExpr = 0;

  // Loop index
  //
  CollIndex exprNum;

  // For each transpose value expression (also equal to the number of key
  // values if they exist)
  //
  for(exprNum = 0; exprNum < numMovExprs; exprNum++) {

    // Clear the list of value Ids (used in the previous iteration
    // through this loop).
    //
    ValueIds.clear();

    // Contruct Key Expression with Cast node if they exist.
    // The key ValueIdUnion is in position 0.
    //
    if(numKeyExprs != 0) {

      // Get the key ValueIdUnion.
      //
      ValueIdUnion *keyValIdUnion =
	(ValueIdUnion *)((transUnionVector()[0])[0].
			 getValueDesc()->getItemExpr());

      // Extract one (exprNum) entry from the ValueIdUnion and add a
      // Cast to cast it to the proper type.
      //
      castExpr = new(generator->wHeap())
	Cast(keyValIdUnion->getSource(exprNum).getValueDesc()->getItemExpr(),
	     &(keyValIdUnion->getResult().getType()));

      // Bind this new item expression.
      //
      castExpr->bindNode(generator->getBindWA());

      // This should never fail at this point !!!
      //
      GenAssert(! generator->getBindWA()->errStatus(),
		"Transpose: Internal Error");

      // Insert the Value Id for this item expression into the list of
      // Value Ids that will be used to generate the final expression.
      //
      ValueIds.insert(castExpr->getValueId());
    }

    // ValueIds may now contains one ValueId representing the key value.
    //

    // Translate the expression number (exprNum) from 0 -> numKeyExprs - 1
    // to vector entry number (vectorEntryNum) and expression number
    // (valExprNum)
    //

    // Binary expression indexes.
    //
    CollIndex vectorEntryNum, valExprNum;

    // Keep track of how many expressions are covered by the current
    // ValueIdUnion and those previous.
    //
    CollIndex numCoveredExprs;

    // Translate the Unary expression index (exprNum) into a binary
    // index (vectorEntryNum, valExprNum)
    // (A for-loop with no body)
    //
    for((vectorEntryNum = 1,
	 numCoveredExprs = numExprs[1],
	 valExprNum = exprNum);

	// Does this ValueIdUnion cover this expression number
	//
	numCoveredExprs <= exprNum;

	// If not, adjust the indexes and try the next one.
	(numCoveredExprs += numExprs[vectorEntryNum + 1],
	 valExprNum -= numExprs[vectorEntryNum],
	 vectorEntryNum++));

    // At this point:
    // vectorEntryNum is index of the transUnionVector for this exprNum.
    // valExprNum is index into the ValueIdUnion.

    GenAssert(vectorEntryNum > 0 && vectorEntryNum < numUnionLists,
	      "Transpose: Internal Error");

    GenAssert(valExprNum < numExprs[vectorEntryNum],
	      "Transpose: Internal Error");

    // Generate all Value Expressions.
    // One will be all of the value expressions indexed by vectorEntryNum
    // and valExprNum and the others will be NULL.
    //
    for(unionListNum = 1; unionListNum < numUnionLists; unionListNum++) {

      // For Each ValueIdUnion in an entry of the vector.
      //
      for(CollIndex numValUnions = 0;
	  numValUnions < transUnionVector()[unionListNum].entries();
	  numValUnions++) {

	ValueIdUnion *valValIdUnion =
	  (ValueIdUnion *)((transUnionVector()[unionListNum])[numValUnions].
			   getValueDesc()->getItemExpr());

	if(unionListNum == vectorEntryNum){

	  // Construct the value expression cast to the proper type.
	  //
	  castExpr = new(generator->wHeap())
	    Cast(valValIdUnion->
		 getSource(valExprNum).getValueDesc()->getItemExpr(),
		 &(valValIdUnion->getResult().getType()));
	} else {

	  // Construct NULL expression cast to the proper type.
	  //
	  castExpr = new(generator->wHeap())
	    Cast(new (space) ConstValue(),
		 &(valValIdUnion->getResult().getType()));
	}

	// Bind the CASTed itemed expression.
	//
	castExpr->bindNode(generator->getBindWA());

	// This should never fail at this point !!!
	//
	GenAssert(! generator->getBindWA()->errStatus(),
		  "Transpose: Internal Error");

	// Add the ValueId to the list of value ids which will be used
	// to generate the final expression.
	//
	ValueIds.insert(castExpr->getValueId());
      }
    }

    // Generate the expression.

    // Initialize the pointer to the expression to be generated
    // to be NULL.
    //
    transExprs[exprNum] = 0;

    // Generate the expressions.
    //
    // ValueIds - refers to the expressions for 1 key value, and N
    // transpose values, all but one will be NULL.
    //
    // 0 - Do not add conv. nodes.
    //
    // transColsAtp - this expression will be evaluated on the
    // transColsAtp (0) ATP.
    //
    // transColsAtpIndex - within the transColsAtp (0) ATP, the destination
    // for this move expression will be the transColsAtpIndex TP. This should
    // be the last TP of the ATP.
    //
    // SQLARK_EXPLODED_FORMAT - generate the move expression to construct
    // the destination tuple in EXPLODED FORMAT.
    //
    // transColsTupleLen - This is an output which will contain the length
    // of the destination Tuple.  This better return the same value for each
    // interation of this loop.
    //
    // &transExprs[exprNum] - The address of the pointer to the expression
    // which will be generated.
    //
    // &transColsTupleDesc - The address of the tuple descriptor which is
    // generated.  This describes the destination tuple of the move expression.
    // This will be generated only the first time through the loop. The tuple
    // better have the same format each time. A NULL value inticates that
    // the descriptor should not be generated.
    //
    // SHORT_FORMAT - generate the transColsTupleDesc in the SHORT FORMAT.
    //
    expGen->generateContiguousMoveExpr(ValueIds,
				       0,
				       transColsAtp,
				       transColsAtpIndex,
				       generator->getInternalFormat(),
				       transColsTupleLen,
				       &transExprs[exprNum],
				       (exprNum == 0
					? &transColsTupleDesc
					: 0),
				       ExpTupleDesc::SHORT_FORMAT);
    // Set the tuple descriptor in the returned CRI descriptor.
    // This will be set only the first time through the loop.
    //
    if(exprNum == 0) {
      returnedCriDesc->setTupleDescriptor(transColsAtpIndex,
					  transColsTupleDesc);

      // Take the result (ie. the Cast nodes) of generateContiguousMove
      // and set the mapInfo for the ValueIdUnion nodes to be the same so
      // that our parent can access the computed expressions
      // This code is executed only the first time through the loop.
      // The info generated from the expression generator should be the
      // same each time through the loop.
      //

      // An index into the ValueIds that we just generated.
      // (It is assumed that the above code inserts the value Ids into
      // ValueIds in the same order as the loops below).
      //
      CollIndex valIdNum = 0;

      // For each entry in the transUnionVector...
      //
      for(unionListNum = 0; unionListNum < numUnionLists; unionListNum++) {

	// For each ValueIdUnion in the entry...
	//
	for(CollIndex numValUnions = 0;
	    numValUnions < transUnionVector()[unionListNum].entries();
	    numValUnions++) {

	  // Get the ValueId of the ValueIdUnion node.
	  //
	  ValueId valId =
	    (transUnionVector()[unionListNum])[numValUnions];

	  // Add a map entry to the map table for this ValueIdUnion node.
	  // The mapInfo is the same as the mapInfo of the result of
	  // generating an expression for the corresponding Cast expression.
	  //
	  MapInfo * mapInfo =
	    generator->addMapInfoToThis(localMapTable,
                valId,
                generator->getMapInfo(ValueIds[valIdNum])->getAttr());

	  // Indicate that code was generated for this map table entry.
	  //
	  mapInfo->codeGenerated();

	  // Advance the index to the ValueIds.
	  //
	  valIdNum++;
	}
      }
    }

    //localMapTable->removeLast();
    generator->removeLast();
  }

  // Generate expression to evaluate predicate on the transposed row
  //
  ex_expr *afterTransPred = 0;

  if (! selectionPred().isEmpty()) {
    ItemExpr * newPredTree =
      selectionPred().rebuildExprTree(ITM_AND,TRUE,TRUE);

    expGen->generateExpr(newPredTree->getValueId(), ex_expr::exp_SCAN_PRED,
			 &afterTransPred);
  }

  // Allocate the Transpose TDB
  //
  queue_index upQ = (queue_index)getDefault(GEN_TRSP_SIZE_UP);

  ComTdbTranspose *transTdb =
    new (space) ComTdbTranspose(childTdb,
				transExprs,
				numMovExprs,
				afterTransPred,
				transColsTupleLen,
				transColsAtpIndex,
				givenCriDesc,
				returnedCriDesc,
				(queue_index)getDefault(GEN_TRSP_SIZE_DOWN),
				//(queue_index)getDefault(GEN_TRSP_SIZE_UP),
				upQ,
				(Cardinality) (getInputCardinality() * getEstRowsUsed()).getValue(),
				getDefault(GEN_TRSP_NUM_BUFFERS),
				getDefault(GEN_TRSP_BUFFER_SIZE),
                                space);
  generator->initTdbFields(transTdb);
  // If the child's outputs are not needed above this node,
  // remove the entries from the map table.
  //
  if (transOutputs.isEmpty()) {

    // Remove child's outputs from mapTable, They are not needed
    // above.
    //
    generator->removeAll(localMapTable);
    NADELETEARRAY(numExprs,numUnionLists,CollIndex,space);
    numExprs = NULL;

  }


  // Add the explain Information for this node to the EXPLAIN
  // Fragment.  Set the explainTuple pointer in the generator so
  // the parent of this node can get a handle on this explainTuple.
  //
  if(!generator->explainDisabled()) {
    generator->setExplainTuple(addExplainInfo(transTdb,
					      childExplainTuple,
					      0,
					      generator));
  }

  // Restore the Cri Desc's and set the return object.
  //
  generator->setCriDesc(givenCriDesc, Generator::DOWN);
  generator->setCriDesc(returnedCriDesc, Generator::UP);
  generator->setGenObj(this, transTdb);

  return 0;
}

// -----------------------------------------------------------------------
// PhyPack::codeGen()
// -----------------------------------------------------------------------
short PhyPack::codeGen(Generator* generator)
{
  // Get handles on expression generator, map table, and heap allocator.
  ExpGenerator* expGen = generator->getExpGenerator();
  Space* space = generator->getSpace();

  // Allocate a new map table for this operation.
  MapTable* localMapTable =
    generator->appendAtEnd();

  // Get a description of what kind of tuple my parent gives me.
  ex_cri_desc* givenCriDesc = generator->getCriDesc(Generator::DOWN);

  // PhyPack adds one tupp to what its parent gives in its return tuple.
  unsigned short returnedNoOfTuples = givenCriDesc->noTuples() + 1;
  ex_cri_desc* returnedCriDesc =
                        new (space) ex_cri_desc(returnedNoOfTuples,space);

  // Get a handle of the last map table before allowing child to code gen.
  MapTable* lastMapTable = generator->getLastMapTable();

  // Create new attributes for the packed columns.
  CollIndex noOfPackedCols = packingExpr().entries();
  Attributes** attrs =
                   new (generator->wHeap()) Attributes * [noOfPackedCols];

  // Add the packed columns to the map table. (using ATP0)
  for(CollIndex i = 0; i < noOfPackedCols; i++)
      attrs[i] = (generator->addMapInfo(packingExpr().at(i),0))->getAttr();

  // PhyPack adds one tupp to the tail of its parent's ATP (stored as ATP0)
  const Int32 atpIndex = returnedNoOfTuples - 1;
  const Int32 atp = 0;

  // To store length of the last tupp introduced by PhyPack.
  ULng32 tupleLen = 0;

  // Will be generated to describe the last tupp introduced by PhyPack.
  ExpTupleDesc* tupleDesc = 0;

  // From here up we go back into Exploded Internal format (if not there
  // already) since it doesn't make sense for column wise rowsets to
  // be in Compressed Internal format yet.
  generator->setExplodedInternalFormat();

  // Fill in offsets and other info in the attributes list and computes the
  // length and descriptor of the resulting tuple generated.
  // The format of packed rows in rowsets is always Exploded Internal format.
  expGen->processAttributes(noOfPackedCols,
                            attrs,
                            ExpTupleDesc::SQLARK_EXPLODED_FORMAT,
                            tupleLen,
                            atp,
                            atpIndex,
                            &tupleDesc,
                            ExpTupleDesc::SHORT_FORMAT);

  // Copies of Attributes have been made to store in the tuple descriptor.
  NADELETEBASIC(attrs,generator->wHeap());

  // Store the computed tuple desc for the new tuple added by PhyPack.
  returnedCriDesc->setTupleDescriptor(returnedNoOfTuples - 1,tupleDesc);

  // Set the DOWN descriptor in the generator to what my child gets from me.
  generator->setCriDesc(returnedCriDesc,Generator::DOWN);

  // Get the child code generated and retrieve useful stuffs from it.
  child(0)->codeGen(generator);
  ComTdb* childTdb = (ComTdb*)(generator->getGenObj());

  // Generate an expression to pack the rows.
  ex_expr* packExpr = 0;
  expGen->generateListExpr(packingExpr(),ex_expr::exp_ARITH_EXPR,&packExpr);

  // Generate selection predicate on the packed cols if there are any.
  ex_expr* predExpr = 0;
  if(NOT selectionPred().isEmpty())
  {
    ItemExpr* pred = selectionPred().rebuildExprTree(ITM_AND,TRUE,TRUE);
    expGen->generateExpr(pred->getValueId(),ex_expr::exp_SCAN_PRED,
                         &predExpr);
  }

  //????????? Generate an expression to copy result row to result buffer.
  // ex_expr* copyExpr = 0;
  // expGen->generateContiguousMoveExpr(packingExpr(),
  //                                 -1,                       // add conv
  //                                 1,                        // copy to ATP1
  //                                 returnedNoOfTuples - 1,   // ATP index
  //                                 ExpTupleDesc::SQLARK_EXPLODED_FORMAT,
  //                                 tupleLen,
  //                                 &copyExpr);
  //
  // Note that my parent is gonna find the non-copied version of attributes
  // information in my map table, since it is refering to the vid's of the
  // originals but not the copies. Coincidentally this is good for us since:
  // 1. My parent is expected to see things at ATP0 rather than ATP1.
  // 2. The format (or order) of the tuple doesn't get changed after copying
  //    so that the old attributes are refering to the right offsets.
  //
  // $$$ Seems copyExpr_ is no longer needed after ComTdbPackRows code were written.

  // Values at the child's context as well as the intermediates during expr
  // generation are no longer visible any more from this point.
  generator->removeAll(lastMapTable);

  // Create the Pack node's TDB.
  ComTdbPackRows* packTdb = new (space) ComTdbPackRows (childTdb,
                                              packExpr,
                                              predExpr,
                                              returnedNoOfTuples - 1,
                                              tupleLen,
                                              givenCriDesc,
                                              returnedCriDesc,
                                              (queue_index) 8,
                                              (queue_index) 8);
  generator->initTdbFields(packTdb);

  // Add explain info of this node to the EXPLAIN fragment. Set explainTuple
  // pointer in the generator so the parent of this node can get a handle on
  // this explainTuple.
  //
  if(NOT generator->explainDisabled())
  {
    // Child's explain tuple.
    ExplainTuple* childExplainTuple = generator->getExplainTuple();

    generator->setExplainTuple(addExplainInfo(packTdb,
                                              childExplainTuple,
                                              0,
                                              generator));
  }

  // Set up the new up CRI desc.
  generator->setCriDesc(returnedCriDesc,Generator::UP);

  // Restore original down CRI desc since this node changed it.
  generator->setCriDesc(givenCriDesc,Generator::DOWN);

  // Return generated object (the TDB) to the generator.
  generator->setGenObj(this, packTdb);

  return 0;

}

// -----------------------------------------------------------------------
// TableValuedFunction methods
// -----------------------------------------------------------------------
const char * TableValuedFunction::getVirtualTableName()
{ return "??TableValuedFunction??"; }

TrafDesc *TableValuedFunction::createVirtualTableDesc()
{ return NULL; }

void TableValuedFunction::deleteVirtualTableDesc(TrafDesc *vtd)
{
}

// -----------------------------------------------------------------------
// StatisticsFunc methods
// -----------------------------------------------------------------------
const char * StatisticsFunc::getVirtualTableName()
//{ return "STATISTICS__"; }
{return getVirtualTableNameStr();}

TrafDesc *StatisticsFunc::createVirtualTableDesc()
{
  TrafDesc * table_desc =
    Generator::createVirtualTableDesc(getVirtualTableName(),
				      NULL, // let it decide what heap to use    
				      ComTdbStats::getVirtTableNumCols(),
				      ComTdbStats::getVirtTableColumnInfo(),
				      ComTdbStats::getVirtTableNumKeys(),
				      ComTdbStats::getVirtTableKeyInfo());
  return table_desc;
}


short StatisticsFunc::codeGen(Generator* generator)
{
  ExpGenerator * expGen = generator->getExpGenerator();
  Space * space = generator->getSpace();

  // allocate a map table for the retrieved columns
  generator->appendAtEnd();

  ex_expr *scanExpr = 0;
  ex_expr *projExpr = 0;

  ex_cri_desc * givenDesc
    = generator->getCriDesc(Generator::DOWN);

  ex_cri_desc * returnedDesc
    = new(space) ex_cri_desc(givenDesc->noTuples() + 1, space);

  // cri descriptor for work atp has 4 entries:
  // first two entries for consts and temps.
  // Entry 1(index #2) is
  // where the stats row will be moved to evaluate
  // the 'where' predicate.
  // Entry 2(index #3) is where the input row will be built.

  ex_cri_desc * workCriDesc = new(space) ex_cri_desc(4, space);
  const Int32 work_atp = 1;
  const Int32 stats_row_atp_index = 2;
  const Int32 input_row_atp_index = 3;

  // Assumption (for now): retrievedCols contains ALL columns from
  // the table/index. This is because this operator does
  // not support projection of columns. Add all columns from this table
  // to the map table.
  //
  // The row retrieved from filesystem is returned as the last entry in
  // the returned atp.

  Attributes ** attrs =
    new(generator->wHeap())
    Attributes * [getTableDesc()->getColumnList().entries()];

  for (CollIndex i = 0; i < getTableDesc()->getColumnList().entries(); i++)
    {
      ItemExpr * col_node
	= (((getTableDesc()->getColumnList())[i]).getValueDesc())->
	  getItemExpr();

      attrs[i] = (generator->addMapInfo(col_node->getValueId(), 0))->
	getAttr();
    }

  ExpTupleDesc *tupleDesc = 0;
  ULng32 tupleLength = 0;

  // StatisticsFunc must use Exploded Format for now.
  ExpTupleDesc::TupleDataFormat tupleFormat = ExpTupleDesc::SQLARK_EXPLODED_FORMAT;

  expGen->processAttributes(getTableDesc()->getColumnList().entries(),
			    attrs, tupleFormat,
			    tupleLength,
			    work_atp, stats_row_atp_index,
			    &tupleDesc, ExpTupleDesc::LONG_FORMAT);

  // delete [] attrs;
  // NADELETEBASIC is used because compiler does not support delete[]
  // operator yet. Should be changed back later when compiler supports
  // it.
  NADELETEBASIC(attrs, generator->wHeap());

  // add this descriptor to the work cri descriptor.
  workCriDesc->setTupleDescriptor(stats_row_atp_index, tupleDesc);

  // generate stats selection expression, if present
  if (! selectionPred().isEmpty())
   {
     ItemExpr * newPredTree = selectionPred().rebuildExprTree(ITM_AND,TRUE,TRUE);
     expGen->generateExpr(newPredTree->getValueId(), ex_expr::exp_SCAN_PRED,
			  &scanExpr);
   }

  // generate move expression for the parameter list
  ex_expr *inputExpr = 0;
  ExpTupleDesc *inputTupleDesc = 0;
  ULng32 inputTupleLength = 0;

  if (! getProcInputParamsVids().isEmpty())
    {

      expGen->generateContiguousMoveExpr(getProcInputParamsVids(),
					 -1,
					 work_atp,
					 input_row_atp_index,
					 tupleFormat,
					 inputTupleLength,
					 &inputExpr,
					 &inputTupleDesc,
					 ExpTupleDesc::LONG_FORMAT);

      // add this descriptor to the work cri descriptor.
      workCriDesc->setTupleDescriptor(input_row_atp_index, inputTupleDesc);
    }

  // The stats row will be returned as the last entry of the returned atp.
  // Change the atp and atpindex of the returned values to indicate that.
  expGen->assignAtpAndAtpIndex(getTableDesc()->getColumnList(),
			       0, returnedDesc->noTuples()-1);

  Lng32 numBuffers = 3;
  Lng32 bufferSize = 10 * tupleLength;
  ComTdbStats *statsTdb = new(space) ComTdbStats
    (
	 tupleLength,			 // Length of stats Tuple
	 tupleLength,                    // Length of returned tuple
	 inputTupleLength,               // length of input tuple
	 givenDesc,	                 // given_cri_desc
	 returnedDesc,		         // returned cri desc
	 8,				 // Down queue size
	 16,				 // Up queue size
	 numBuffers,			 // Number of buffers to
					 // allocate
	 bufferSize,			 // Size of each buffer
	 scanExpr,			 // predicate
	 inputExpr,
	 projExpr,
	 workCriDesc,			 // Descriptor of work Atp
	 stats_row_atp_index,
	 input_row_atp_index);

  generator->initTdbFields(statsTdb);

  // Add the explain Information for this node to the EXPLAIN
  // Fragment.  Set the explainTuple pointer in the generator so
  // the parent of this node can get a handle on this explainTuple.
  if(!generator->explainDisabled()) {
    generator->setExplainTuple(
       addExplainInfo(statsTdb, 0, 0, generator));
  }
  generator->setCriDesc(givenDesc, Generator::DOWN);
  generator->setCriDesc(returnedDesc, Generator::UP);
  generator->setGenObj(this, statsTdb);

  return 0;
}

// -----------------------------------------------------------------------
// ProxyFunc methods
// -----------------------------------------------------------------------

static void initProxyKeyDescStruct(TrafKeysDesc *tgt, ComUInt32& src)
{
  tgt->keyseqnumber = 1;
  tgt->tablecolnumber = 0;
  tgt->setDescending(FALSE);
}

static Lng32 createDescStructsForProxy(const ProxyFunc &proxy,
                                        char *tableName,
                                        TrafDesc *&colDescs,
                                        TrafDesc *&keyDescs)
{
  colDescs = NULL;
  keyDescs = NULL;
  Lng32 reclen = 0;
  TrafDesc *prev_desc = NULL;
  ComUInt32 numCols = proxy.getNumColumns();

  // Creates and populates column descs
  proxy.populateColumnDesc(tableName, colDescs, reclen);

  // Create key descs
  prev_desc = NULL;
  numCols = 1; 
  for (ComUInt32 keyNum = 0; keyNum < numCols; keyNum++)
  {
    TrafDesc *key_desc = TrafAllocateDDLdesc(DESC_KEYS_TYPE, NULL);
    if (prev_desc)
      prev_desc->next = key_desc;
    else
      keyDescs = key_desc;      
    
    prev_desc = key_desc;
    
    initProxyKeyDescStruct(key_desc->keysDesc(), keyNum);
  }
  
  return reclen;
}

TrafDesc *ProxyFunc::createVirtualTableDesc()
{
  // TrafAllocateDDLdesc() requires that HEAP (STMTHEAP) 
  // be used for operator new herein

  TrafDesc *table_desc = TrafAllocateDDLdesc(DESC_TABLE_TYPE, NULL);
  const char *tableName = getVirtualTableName();
  table_desc->tableDesc()->tablename = new HEAP char[strlen(tableName)+1];
  strcpy(table_desc->tableDesc()->tablename, tableName);

  table_desc->tableDesc()->setSystemTableCode(TRUE);

  TrafDesc *files_desc = TrafAllocateDDLdesc(DESC_FILES_TYPE, NULL);
  files_desc->filesDesc()->setAudited(TRUE); // audited table
  table_desc->tableDesc()->files_desc = files_desc;
  
  TrafDesc *cols_descs = NULL;
  TrafDesc *keys_descs = NULL;

  table_desc->tableDesc()->colcount = (Int32) getNumColumns();

  table_desc->tableDesc()->record_length =
    createDescStructsForProxy(*this,
                                table_desc->tableDesc()->tablename,
                                cols_descs,
                                keys_descs);
  
  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; // doesn't matter.

  TrafDesc *i_files_desc = TrafAllocateDDLdesc(DESC_FILES_TYPE, NULL);
  i_files_desc->filesDesc()->setAudited(TRUE); // audited table
  index_desc->indexesDesc()->files_desc = i_files_desc;

  index_desc->indexesDesc()->keys_desc  = keys_descs;
  table_desc->tableDesc()->columns_desc = cols_descs;
  table_desc->tableDesc()->indexes_desc = index_desc;
 
  return table_desc;
}

short PhysicalExtractSource::codeGen(Generator *)
{
  GenAssert(0, "PhysicalExtractSource::codeGen() should never be called");
  return 0;
}

/////////////////////////////////////////////////////////
//
// ControlRunningQuery::codeGen()
//
/////////////////////////////////////////////////////////
short ControlRunningQuery::codeGen(Generator * generator)
{
  Space * space = generator->getSpace();

  GenAssert((child(0) == NULL) && (child(1) == NULL),
    "ControlRunningQuery does not expect any child.");

  char *qid =
    space->allocateAndCopyToAlignedSpace(queryId_, str_len(queryId_), 0);

  char *pname =
     space->allocateAndCopyToAlignedSpace(pname_, str_len(pname_), 0);

  char *comment =
    space->allocateAndCopyToAlignedSpace(comment_, str_len(comment_), 0);

  ComTdbCancel::Action a = ComTdbCancel::InvalidAction;
  switch (action_)
  {
    case Cancel:
    {
      switch (qs_)
      {
        case ControlQid:    
          a = ComTdbCancel::CancelByQid;    
          break;
        case ControlPname:  
        case ControlNidPid:
          break;
        default: 
          GenAssert(0, "Invalid ControlRunningQuery::qs_"); break;
      }
      break;
    }
   case Suspend: 
   case Activate:
     break;
   default: GenAssert(0, "Invalid ControlRunningQuery::action_");
  }

  if (a == ComTdbCancel::InvalidAction)
  {
    *CmpCommon::diags() << DgSqlCode(-1010);
    GenExit();
    return -1;
  }

  ComTdbCancel * exe_cancel_tdb = new(space)
    ComTdbCancel(qid, pname, nid_, pid_,
                 getDefault(CANCEL_MINIMUM_BLOCKING_INTERVAL),
                 a,  forced_, comment,
                 generator->getCriDesc(Generator::DOWN),
                 generator->getCriDesc(Generator::DOWN),
                 (queue_index)getDefault(GEN_DDL_SIZE_DOWN),
                 (queue_index)getDefault(GEN_DDL_SIZE_UP)
                );

  generator->initTdbFields(exe_cancel_tdb);

  // no tupps are returned
  generator->setCriDesc((ex_cri_desc *)
    (generator->getCriDesc(Generator::DOWN)),
                           Generator::UP);
  generator->setGenObj(this, exe_cancel_tdb);

  if(!generator->explainDisabled()) {
    generator->setExplainTuple(
       addExplainInfo(exe_cancel_tdb, 0, 0, generator));
  }

  return 0;
}

