/**********************************************************************
// @@@ 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:         Statement.C
* Description:  Methods for class Statement.
*
* Created:      7/10/95
* Language:     C++
*
*
*
*
*****************************************************************************
*/

#define _XOPEN_SOURCE_EXTENDED 1
#include "cli_stdh.h"
#undef _XOPEN_SOURCE_EXTENDED       

#include "ComCextdecs.h"
#include "ex_stdh.h"
#include "ex_exe_stmt_globals.h"
#include "ComTdb.h"
#include "ex_tcb.h"
#include "ex_root.h"
#include "ExStats.h"
#include "ExSqlComp.h"
#include "ex_transaction.h"
#include "ex_frag_rt.h"
#include "ComDiags.h"
#include "NAMemory.h"
#include "LateBindInfo.h"
#include "sql_buffer.h"
#include "ex_control.h"
#include "Descriptor.h"  // For call to Descriptor::getCharDataFromCharHostVar(). 
#include "exp_clause_derived.h"
#include "sql_id.h"
#include "ex_error.h"
#include "ComRtUtils.h"
#include "ComDistribution.h"
#include "Cli.h"
#include "Int64.h"
#include "ComSqlId.h"
#include "CmpErrors.h"

#include "TriggerEnable.h" // triggers
#include "ComSmallDefs.h" // MV
#include "ComMvAttributeBitmap.h" // MV

#include "logmxevent.h"

#include "ExpLOBinterface.h"

#include "ExUdrServer.h"
#include "wstr.h"
#include "QueryText.h"
#include <wchar.h>

#include "ComAnsiNamePart.h"
#include "ExRsInfo.h"

#include "arkcmp_proc.h"
#include "CmpContext.h"

#include "HiveClient_JNI.h"

// Printf-style tracing macros for the debug build. The macros are
// no-ops in the release build.
#ifdef _DEBUG
#include <stdarg.h>
#define StmtDebug0(s) StmtPrintf((s))
#define StmtDebug1(s,a1) StmtPrintf((s),(a1))
#define StmtDebug2(s,a1,a2) StmtPrintf((s),(a1),(a2))
#define StmtDebug3(s,a1,a2,a3) StmtPrintf((s),(a1),(a2),(a3))
#define StmtDebug4(s,a1,a2,a3,a4) StmtPrintf((s),(a1),(a2),(a3),(a4))
#define StmtDebug5(s,a1,a2,a3,a4,a5) StmtPrintf((s),(a1),(a2),(a3),(a4),(a5))
const char *TransIdToText(Int64 transId)
{
  static char text[256];
  short actualLen;
  short error = TRANSIDTOTEXT(transId, text, 255, &actualLen);
  if (error)
    str_sprintf(text, "(error %d)", (Int32) error);
  else
    text[actualLen] = 0;
  return &text[0];
}
#else
#define StmtDebug0(s)
#define StmtDebug1(s,a1)
#define StmtDebug2(s,a1,a2)
#define StmtDebug3(s,a1,a2,a3)
#define StmtDebug4(s,a1,a2,a3,a4)
#define StmtDebug5(s,a1,a2,a3,a4,a5)
#endif

const char *RetcodeToString(RETCODE r)
{
  switch (r)
  {
    case SUCCESS: return "SUCCESS";
    case SQL_EOF: return "SQL_EOF";
    case ERROR: return "ERROR";
    case WARNING: return "WARNING";
    case NOT_FINISHED: return "NOT_FINISHED";
    default: return ComRtGetUnknownString((Int32) r);
  }
}

class Dealloc
{
  NAHeap *heap_;
  void * addr_;
public:
  Dealloc() : heap_(NULL), addr_(NULL) {}
  ~Dealloc() { if (addr_ != NULL) heap_->deallocateMemory(addr_); }
  NAHeap * setHeap(NAHeap *heap) { return heap_ = heap; }
  void * getAddr(void *addr) { return addr_ = addr; }
};

////////////////////////////////////////////////////////////////////
// class StatementInfo
////////////////////////////////////////////////////////////////////
StatementInfo::StatementInfo()
{
  statement_  = NULL;
  inputDesc_  = NULL;
  outputDesc_ = NULL;
  hashValue_  = 0;
  flags_      = 0;
};

StatementInfo::~StatementInfo()
{
  statement_  = NULL;
  inputDesc_  = NULL;
  outputDesc_ = NULL;
  hashValue_  = 0;
  flags_      = 0;
};

// This function is an internal test mechanism for SPJ result sets
static const char *getProxySyntaxFromEnvironment(CliGlobals *cliGlobals,
                                                 Lng32 rsIndex)
{
  char *stmtText = NULL;


  return stmtText;
}

////////////////////////////////////////////////////////////////////
// class Statement
////////////////////////////////////////////////////////////////////
Statement::Statement(SQLSTMT_ID * statement_id_,
		     CliGlobals * cliGlobals,
                     StatementType stmt_type_,
                     char * cn, Module *module)
  : stmt_state(INITIAL_),
    cliGlobals_(cliGlobals),
    context_(cliGlobals->currContext()),
    clonedFrom_(NULL),
    parentCall_(NULL),
    heap_("Statement Heap",
          context_->exHeap(), 
	  8096  /* 20480 */ /* block size */, 
	  0     /* upperLimit */),
    prevCloseStatement_(NULL),
    nextCloseStatement_(NULL),
    closeSequence_((stmt_type_ == STATIC_STMT) ? 0 : -1)
  , holdable_(SQLCLIDEV_NONHOLDABLE)
  , statementIndex_(0)
  , module_(module)
  , inputArrayMaxsize_(0)   // compile time info for dynamic rowsets
  , rowsetAtomicity_(UNSPECIFIED_)
  , notAtomicFailureLimit_(0)
  , anyTransWasStartedByMe_(FALSE)
  , autoCommitCleared_(FALSE)
  , savedRoVal_(TransMode::READ_WRITE_ )
  , savedRbVal_ (TransMode::ROLLBACK_MODE_NOT_SPECIFIED_ )
  , savedAiVal_( -1 )	       
  , udrSecurity_ (NULL)
  , versionOnEntry_ (COM_VERS_UNKNOWN)
  , versionToUse_ (COM_VERS_UNKNOWN)
  , fetchErrorCode_ (VERSION_NO_ERROR)
  , mxcmpErrorCode_ (VERSION_NO_ERROR)
  , stmtStats_(NULL)
  , extractConsumerQueryTemplate_(NULL)
  , stmtInfo_(NULL)
  , aqrStmtInfo_(NULL)
  , state_(INITIAL_STATE_)  
  , compileStatsArea_(NULL) 
  , spaceObject_(new(context_->exHeap())
    Space(Space::EXECUTOR_SPACE, TRUE, (char *)"Stmt Space"))
  , space_(*spaceObject_)
  , aqrInitialExeStartTime_(-1)
  , compileEndTime_(-1)
{
  cliLevel_ = context_->getNumOfCliCalls();

#ifdef _DEBUG
  stmtDebug_ = FALSE;
  stmtListDebug_ = FALSE;
  Lng32 numCliCalls = context_->getNumOfCliCalls();

  // We have two printf-style trace mechanisms in the debug build
  //
  // 1. A detailed account of all significant events in the life
  //    of this statement. Enabled by the STMT_DEBUG environment
  //    variable.
  //
  // 2. An account of when this is statement is added to or removed
  //    from any of the context's statement lists. Enabled by the
  //    STMTLIST_DEBUG or STMT_DEBUG environment variable. The code
  //    for this trace is in the ContextCli class. All we do here in
  //    the Statement class is carry a flag indicating whether events
  //    for this instance should be reported.

  // Each trace is enabled on a per-instance basis. We check the
  // environment variables every time through the Statement
  // constructor. Also note that we do NOT enable either trace for
  // statements created internally by SQL/MX code. For those
  // statements, the numCliCalls variable will be greater than one.

  // The commands to create trace output are the StmtDebugX macros
  // above in this source file. In the release build the macros
  // evaluate to a noop.

  if (numCliCalls == 1)
  {
    char *envVar;
    envVar = getenv("STMT_DEBUG");
    if (envVar && envVar[0])
    {
      stmtDebug_ = TRUE;
      stmtListDebug_ = TRUE;
    }
    else
    {
      envVar = getenv("STMTLIST_DEBUG");
      if (envVar && envVar[0])
      {
        stmtListDebug_ = TRUE;
      }
    }
  }
#endif

  StmtDebug1("[BEGIN constructor] %p", this);
  StmtDebug2("  Context address %p, context handle %d",
             context_, (Lng32) context_->getContextHandle());

  clonedStatements = new(&heap_) Queue(&heap_);
  // for now a statement space is allocated from the statement heap 
  space_.setParent(&heap_);

  // Set up a space object which might be used during unpacking to allocate
  // additional space for potential upgrading of objects in the plan. This
  // space is derived from heap_, and therefore goes away with it when the
  // statement is destroyed.
  // 
  unpackSpace_ = new(&heap_) Space();
  unpackSpace_->setType(Space::EXECUTOR_SPACE);
  unpackSpace_->setParent(&heap_);

  stmt_type = stmt_type_;

  // Allocate statement-id
  statement_id = (SQLSTMT_ID *)(heap_.allocateMemory(sizeof(SQLSTMT_ID)));
  init_SQLCLI_OBJ_ID(statement_id);

  SQLMODULE_ID* new_module =
       (SQLMODULE_ID *)(heap_.allocateMemory(sizeof(SQLMODULE_ID)));
  init_SQLMODULE_ID(new_module);

  statement_id->module = new_module;
  statement_id->identifier = 0;
  statement_id->handle = 0;
  statement_id->name_mode = statement_id_->name_mode;

  const SQLMODULE_ID* old_module = statement_id_-> module; 

  if(statement_id_->module->module_name)
    {
      Lng32 old_module_nm_len = (Lng32) getModNameLen(old_module);

      char * mn = (char *)(heap_.allocateMemory(old_module_nm_len + 1));
      str_cpy_all(mn,
             statement_id_->module->module_name, old_module_nm_len);

      new_module->module_name_len = old_module_nm_len;
      mn[old_module_nm_len] = 0;
      new_module->module_name = mn;
      StmtDebug1("  Module name: \"%s\"", mn);
    }

  if(statement_id_->identifier)
    {
      Lng32 stmt_name_len = (Lng32) getIdLen(statement_id_);
      char * id =
        (char *)(heap_.allocateMemory(stmt_name_len + 1));

      str_cpy_all(id, statement_id_->identifier, 
		  stmt_name_len);
      statement_id->identifier_len = stmt_name_len;
      id[stmt_name_len] = 0;
      statement_id->identifier = id;
    }
  
  if (context_->aqrInfo() && 
      context_->aqrInfo()->aqrStmtInfo() && 
      (context_->aqrInfo()->aqrStmtInfo()->getSavedStmtHandle() != 0))      
    statement_id->handle=context_->aqrInfo()->aqrStmtInfo()->getSavedStmtHandle();
  else  
    statement_id->handle=(void*)getContext()->getNextStatementHandle();
  StmtDebug1("  New statement handle: %p", statement_id->handle);
    
  default_input_desc = 0;
  default_output_desc = 0;
  
  cursor_name_ = NULL;

  switch (statement_id->name_mode)
  {
  case stmt_handle:
    // nothing to handle for now...
    break;

  case stmt_name:
    // nothing to handle for now...
    break;

  case cursor_name:
    if (cn)
      setCursorName(cn);
    else
      setCursorName(statement_id->identifier);
    break;

  case stmt_via_desc:
  case curs_via_desc:
    {
    SQLDESC_ID tmpDescId;
    if (statement_id->name_mode == stmt_via_desc)
    {
   	init_SQLDESC_ID(&tmpDescId, 
		SQLCLI_CURRENT_VERSION,
		stmt_via_desc,
		statement_id->module,
		statement_id->identifier,
		0,
		SQLCHARSETSTRING_ISO88591,
		(Lng32) getIdLen(statement_id)
    		);
     }
    else
       {
	init_SQLDESC_ID(&tmpDescId,
        SQLCLI_CURRENT_VERSION,
        curs_via_desc,
        statement_id->module,
        statement_id->identifier,
        0,
        SQLCHARSETSTRING_ISO88591,
        (Lng32) getIdLen(statement_id)
        );
	}

    // get the value of the name from the descriptor
    SQLCLI_OBJ_ID* tmpObjId = Descriptor::GetNameViaDesc(&tmpDescId,
           context_,heap_);

    // now that we have used the statement_id->identifier to get the
    // descriptor, we can get rid of it as it won't be used again...
    // NOTE: init_SQLDESC_ID() doesn't make a copy of the identifier so
    //  it isn't safe to free statement_id->identifier until after
    //  the call to GetNameViaDesc().
    if (statement_id->identifier)
    {
      heap_.deallocateMemory((char*)statement_id->identifier);
      statement_id->identifier = 0;
    }

    if (tmpObjId) 
    {
      statement_id->identifier_len = (Lng32) getIdLen(tmpObjId);
      char * id =
        (char *)(heap_.allocateMemory(statement_id->identifier_len + 1));
      if (tmpObjId->identifier) {
        str_cpy_all(id, tmpObjId->identifier,
                    statement_id->identifier_len);
        id[statement_id->identifier_len] = 0;
        // fix memory leak (genesis case 10-981230-3244) 
        // caused by not freeing a non-null tmpString.
        heap_.deallocateMemory((char*)tmpObjId->identifier);
	statement_id->identifier = id;
      }
    
    else
     {
       statement_id->identifier =0;
       statement_id->identifier_len = 0;
     } 
      heap_.deallocateMemory(tmpObjId);
    }

    if(statement_id->identifier == 0)
    {
        // probably an error
    }

    if (statement_id_->name_mode == curs_via_desc)
    {
    // now that the cursor name is set... we don't look in the descriptor
    // again.  The name_mode is now cursor_name *NOT* curs_via_desc.

        setCursorName(statement_id->identifier);
        statement_id->name_mode = cursor_name;
    }
    else
    {
    // now that the statement name is set... we don't look in the descriptor
    // again.  The name_mode is now stmt_name *NOT* stmt_via_desc.

        cursor_name_ = 0;
        statement_id->name_mode = stmt_name;
    }
    }
    break;

  default:
    // error
    break;
  }

#ifdef _DEBUG
  switch (statement_id->name_mode)
  {
    case stmt_handle:
      StmtDebug0("  Name mode: stmt_handle");
      break;

    case stmt_name:
      StmtDebug0("  Name mode: stmt_name");
      StmtDebug1("  Statement name: \"%s\"", statement_id->identifier);
      break;

    case cursor_name:
      StmtDebug0("  Name mode: cursor_name");
      StmtDebug1("  Cursor name: \"%s\"", statement_id->identifier);
      break;

    default:
      StmtDebug1("  *** UNKNOWN NAME MODE %d",
                 (Lng32) statement_id->name_mode);
      break;
  }
#endif

  if (statement_id_->version > SQLCLI_STATEMENT_VERSION_1)
    statement_id->tag = statement_id_->tag; 
  else
    statement_id->tag = 0;
  
  currentOfCursorStatement_ = NULL;

  source_str = 0;
  source_length = 0;
  charset_ = SQLCHARSETCODE_ISO88591;

  schemaName_ = NULL;
  schemaNameLength_ = 0;

  recompControlInfo_ = NULL;
  recompControlInfoLen_ = 0;

  root_tdb = 0;
  root_tcb = 0;
  root_tdb_size = 0;

  lnil_ = NULL;
  inputData_ = NULL;
  inputDatalen_ = 0;


  uniqueStmtId_ = NULL;
  uniqueStmtIdLen_ = 0;
  parentQid_ = NULL;
  parentQidSystem_[0] = '\0';

  if (stmt_type_ == STATIC_STMT)
    // STATIC statement. These are already 'prepared'.
    // They are in Close Cursor state.
    setState(CLOSE_);
  
  flags_ = 0;

  setComputeBulkMoveInfo(TRUE);

  statementGlobals_ = 
    new(&heap_) ExMasterStmtGlobals(0, /* fixup will add the real number */
                                    cliGlobals_,
                                    this,
                                    1 /* create gui scheduler */,
                                    &space_,
                                    &heap_);

  // stored the type in statementGlobals
  if(stmt_type_ == STATIC_STMT){
    statementGlobals_->setStmtType(ExExeStmtGlobals::STATIC);
  }

  if (stmt_type == DYNAMIC_STMT)
    aqrStmtInfo_ = new(&heap_) AQRStatementInfo(&heap_);
  else
    aqrStmtInfo_ = NULL;

  StmtDebug1("[END constructor] %p", this);
  childQueryId_ = NULL;
  childQueryIdLen_ = 0;
  childQueryCostInfo_ = NULL;
  childQueryCompStatsInfo_ = NULL;
} // Statement::Statement

Statement::~Statement()
{
  StmtDebug1("[BEGIN destructor] %p", this);

  dealloc();
  if (compileStatsArea_ != NULL)
  {
    NADELETE(compileStatsArea_, ExStatisticsArea, compileStatsArea_->getHeap());
    compileStatsArea_ = NULL;
  }
  if (statement_id)
    {
      if (statement_id->module)
	{
	  if (statement_id->module->module_name)
	    {
	      heap_.deallocateMemory((char*)statement_id->module->module_name);
	    }
	  heap_.deallocateMemory((char*)statement_id->module);
	  statement_id->module = 0;
	}
      if (statement_id->identifier)
	{
	  heap_.deallocateMemory((char*)statement_id->identifier);
	  statement_id->identifier = 0;
	}
      heap_.deallocateMemory(statement_id);
      statement_id = 0;
    }
  
  if (cursor_name_)
    {
      heap_.deallocateMemory(cursor_name_);
      cursor_name_ = 0;
    }
  
  if (source_str)
    {
      NADELETEBASIC(source_str, context_->exHeap());

      //      heap_.deallocateMemory(source_str);
      source_str = NULL;
    }
  
  // Release the TDB tree. assignRootTdb() does take into account
  // statement cloning and will not actually deallocate memory
  // occupied by the TDB tree if this statement is a clone.
  assignRootTdb(NULL);

  // Delete cloned statements
  // Note: Context should be used to deallocate cloned statements
  //       if the original statement being cloned from is deallocated...
  clonedStatements->position();
  Statement *clone = (Statement *) clonedStatements->getNext();
  for (; clone != NULL; clone = (Statement *) clonedStatements->getNext())
  {
    delete clone;
  }
  
  NADELETE(clonedStatements, Queue, &heap_); 
  
  // Delete child stored procedure result set statements. Note that
  // the context has already removed these child statements from its
  // statement lists before calling this Statement destructor.
  ExRsInfo *rsInfo = getResultSetInfo();
  if (rsInfo)
  {
    ULng32 numChildren = rsInfo->getNumEntries();
    for (ULng32 i = 1; i <= numChildren; i++)
    {
      Statement *rsChild = NULL;
      const char *proxySyntax = NULL;
      NABoolean open = FALSE;
      NABoolean closed = FALSE;
      NABoolean prepared = FALSE;
      NABoolean found = rsInfo->getRsInfo(i, rsChild, proxySyntax,
                                          open, closed, prepared); 
      if (found && rsChild)
        delete rsChild;
    }

    // All the child statements have gone away and this statement is
    // about to go away. We can destroy the ExRsInfo object that was
    // storing information about the children.
    statementGlobals_->deleteResultSetInfo();
  }

  // If this is a stored procedure result set, inform the parent that
  // this child is going away
  if (parentCall_)
  {
    ExRsInfo *rsInfo = parentCall_->getResultSetInfo();
    if (rsInfo)
    {
      StmtDebug1("  About to unbind proxy statement %p ", this);
      rsInfo->unbind(this);
    }
  }

  if (default_input_desc)
    {
      delete default_input_desc;    
      default_input_desc = 0;
    }
  
  if (default_output_desc)
    {
      delete default_output_desc;
      default_output_desc = 0;
    }

  if ( udrSecurity_ )
    {
      if ( udrSecurity_->entries ())
	{
	  for ( UInt32 i=0; i < udrSecurity_->entries (); i++)
	    {
	      delete (*udrSecurity_)[i];
	    }
	    udrSecurity_->clear ();
        } // if udrSecurity_->entries ()
  
      delete udrSecurity_;
      udrSecurity_ = 0;
    } // if udrSecurity_

  StmtDebug1("[END destructor] %p", this);

  if (cliGlobals_->getStatsGlobals() != NULL)
  {
    if (stmtStats_ != NULL)
    {
      int error = cliGlobals_->getStatsGlobals()->getStatsSemaphore(cliGlobals_->getSemId(),
                    cliGlobals_->myPin());
      if (stmtStats_->getMasterStats() != NULL)
	{
	  stmtStats_->getMasterStats()->setStmtState(Statement::DEALLOCATED_);
	  stmtStats_->getMasterStats()->setEndTimes(! stmtStats_->aqrInProgress());
	}
      cliGlobals_->getStatsGlobals()->removeQuery(cliGlobals_->myPin(), stmtStats_);
      cliGlobals_->getStatsGlobals()->releaseStatsSemaphore(cliGlobals_->getSemId(),cliGlobals_->myPin());
    }
  }
  else
  {
    if (stmtStats_ != NULL)
    {
      NADELETE(stmtStats_, StmtStats, stmtStats_->getHeap());
    }
  }
  stmtStats_ = NULL;
  if (childQueryId_ != NULL)
  {
    NADELETEBASIC(childQueryId_, &heap_);
    childQueryId_ = NULL;
  }
  if (childQueryCostInfo_ != NULL)
  {
    NADELETEBASIC(childQueryCostInfo_, &heap_);
    childQueryCostInfo_ = NULL;
  }
  if (childQueryCompStatsInfo_ != NULL)
  {   
    NADELETEBASIC(childQueryCompStatsInfo_, &heap_);
    childQueryCompStatsInfo_ = NULL;
  }
  if (spaceObject_ != NULL)
  {
    delete spaceObject_;
    spaceObject_ = NULL;
  }
} // Statement::~Statement

NABoolean Statement::updateInProgress ()
{
  // if there are incomplete insert, delete, update or prepare operations,
  // return TRUE, otherwise return FALSE.
  if (!isPubsubHoldable() 
      )
  {
   if (((getState() == Statement::OPEN_ || 
        getState() == Statement::FETCH_ ||
        getState() == Statement::RELEASE_TRANS_) &&
	(getRootTdb() &&
        (getRootTdb()->updDelInsertQuery() ||
	 getRootTdb()->isEmbeddedUpdateOrDelete()) )
        ) )
     return TRUE;
   }
  return FALSE;
}  

// releaseTransaction is called by Statement::close, Statement::dealloc,
// ContextCli::releaseAllTransactionalRequests and 
// ContextCli::removeFromOpenstatementList.

RETCODE Statement::releaseTransaction(NABoolean allWorkRequests,
				      NABoolean alwaysSendReleaseMsg,
                                      NABoolean statementRemainsOpen)
{
  
  StmtDebug2("[BEGIN releaseTransaction] %p, allWorkRequests = %s",
             this, (allWorkRequests ? "TRUE" : "FALSE"));
  
  // do not send new DML request. 
  statementGlobals_->setNoNewRequest(TRUE);

  if (!statementRemainsOpen               &&  // is holdable cursor?
      root_tcb                            &&
      root_tcb->needsDeregister())
    root_tcb->deregisterCB();

  Int64 cbWaitStartTime = NA_JulianTimestamp();

  statementGlobals_->setNoNewRequest(FALSE);
    
  ExRtFragTable *fragTable = statementGlobals_->getRtFragTable();
  if (fragTable)
    {
      if (root_tcb && root_tcb->fatalErrorOccurred())
        {
          // We can easily get deadlocks from the ESPs at this
          // point, due to producer ESPs' ex_split_bottom_tcb::
          // workState_ set to WAIT_FOR_MORE_REQUESTORS --
          // see solution 10-070108-1544.  This entire statement
          // will soon be deallocated, so place all IpcConnections
          // with pending I/O into the error state.
          fragTable->abandonPendingIOs();
        }
      else
        {
          // For the ESPs, send out the word that we want to get out
          // of the transaction (maybe just temporarily)
	  fragTable->releaseTransaction(allWorkRequests,
					alwaysSendReleaseMsg);
	  
          // Note that for the cancel broker, we have already sent the 
          // finish message -- see the call to deregisterCB in this 
          // method above.
	  
          // wait until the messages have come back
          // (that's all messages if allWorkRequests is set to TRUE,
          // and only the transactional msges if it is FALSE)

	  // how long should we wait for release work reply from esps?
	  // upon timeout we will abort all outstanding I/Os.
	  // some facts below:
	  //
	  //   - default timeout is 15 minutes
	  //   - minimum wait timeout is 5 minutes
	  //   - timeout = -1 means wait indefinitely. but every 2 minutes
	  //     write a timeout message to EMS log.
	  //   - timeout = -2 means that we time out after 2 minutes, then
	  //     abend up to 8 esps that are not responding so we can collect
	  //     saveabend files for debug purpose.
	  //
	  bool waitForever = false;
	  bool abendEsps = false;
	  IpcTimeout timeout = context_->getSessionDefaults()->
                                                getEspReleaseWorkTimeout();
	  if (timeout <= 0)
	    {
	      if (timeout == -1)
		waitForever = true;
	      else if (timeout == -2)
		abendEsps = true;

	      timeout = 2*6000; // 2 minutes
	    }
	  else if (timeout < 5*60)
	    {
	      // minimum timeout is 5 minutes
	      timeout = 5*6000;
	    }
	  else
	    {
	      timeout *= 100;
	    }

          NABoolean hasTimedout;
          while (fragTable->hasOutstandingTransactionalMsges() ||
		 (allWorkRequests && fragTable->hasOutstandingWorkRequests()))
            {
	      if (fragTable->getState() == ExRtFragTable::ERROR)
		{
		  // some error occured
		  context_->diags() << DgSqlCode(-EXE_INTERNAL_ERROR);
		  ComDiagsArea *diagsPtr = statementGlobals_->getDiagsArea();
		  if (diagsPtr)
		    context_->diags().mergeAfter(*diagsPtr);

		  // abort all outstanding I/Os
		  fragTable->abandonPendingIOs();
		  break;
		}

              // wait for an I/O to complete, we know there are some
              // transaction requests that should complete...
              statementGlobals_->getIpcEnvironment()->getAllConnections()->
	        waitOnAll(timeout, FALSE, &hasTimedout);

              if (hasTimedout)
                {
                  // timed out waiting for esp reply. something is wrong.
                  char errMsg[200];
                  str_sprintf(errMsg, "Statement still has %d connections with I/O outstanding - %d trans msgs and %d work reqs.",
			      statementGlobals_->getIpcEnvironment()
                              ->getAllConnections()->getNumPendingIOs(),
			      fragTable->numOutstandingTransactionalMsges(),
			      fragTable->numOutstandingWorkRequests());

		  if (!waitForever)
		    {
		      context_->diags() << DgSqlCode(-EXE_RELEASE_WORK_TIMEOUT)
					<< DgString0(errMsg);

		      if (abendEsps)
			{
			  // abend up to 8 esps so we can collect saveabend
			  // files for debug purpose.
			  CollIndex numEsps = 8;
			  GuaProcessHandle phandles[8];
			  statementGlobals_->getIpcEnvironment()->getAllConnections()->
			    fillInListOfPendingPhandles(phandles, numEsps);

			  char logMsg[300];
			  char *initMsg= (char *)" Executor abended non-responding ESPs ";
			  memset(logMsg, '\0', sizeof logMsg);
			  str_cat(logMsg, initMsg, logMsg);
			  for (CollIndex i = 0; i < numEsps; i++)
			    {
                              // abend esp with saveabend file
                              phandles[i].dumpAndStop(true, true);
			      if (i > 0)
				str_cat(logMsg, ", ", logMsg);
			      phandles[i].toAscii(logMsg + str_len(logMsg), 300 - str_len(logMsg));
			    }
			  str_cat(logMsg, ".", logMsg);

			  context_->diags() << DgString1(logMsg);
			} // if (abendEsps)

		      // abort all outstanding I/Os
		      fragTable->abandonPendingIOs();
		      break;
		    } // if (!waitForever)
		  else
		    {
		      // wait forever. log a warning msg and go back to wait.
		      char logMsg[500];
		      const char *initMsg="Query looping while waiting for release work reply from ESPs ";
		      logMsg[0] = '\0';
		      str_cat(logMsg, initMsg, logMsg);
		      // pins of waited processes are concatenated to logMsg
		      // each pin should be 28 bytes or less
		      statementGlobals_->getIpcEnvironment()->getAllConnections()->
			fillInListOfPendingPins(logMsg + str_len(initMsg),
						300 - str_len(initMsg), 8);
		      str_cat(logMsg, ". ", logMsg);
		      str_cat(logMsg, errMsg, logMsg);
		      SQLMXLoggingArea::logExecRtInfo("Statement.cpp", 0, logMsg, 0);
		    }
                } // if (hasTimedout)
	      else
		{
		  // we did not timeout because some I/O completed first.
		  // now do some work on the fragment dir.
		  if (fragTable->getState() != ExRtFragTable::ERROR)
		    {
		      fragTable->workOnRequests();
		    }
		  else
		    {
		      // some error occured
		      context_->diags() << DgSqlCode(-EXE_INTERNAL_ERROR);
		      ComDiagsArea *diagsPtr = statementGlobals_->getDiagsArea();
		      if (diagsPtr)
			context_->diags().mergeAfter(*diagsPtr);

		      // abort all outstanding I/Os
		      fragTable->abandonPendingIOs();
		      break;
		    }
		}
            } // while (..)
        } // if (root_tcb && ..)
    } // if (fragTable)

  // In most case, the wait loop above will ensure that cancel broker messages
  // are now complete.  However, if there is no fragTable, or there was
  // fatalErrorOccurred or if in the wait loop some problem happened that
  // caused the loop to exit early, then here we must wait for cancel broker
  // to reply to start  and finish message.
  if (root_tcb && !statementRemainsOpen)
    root_tcb->cbMessageWait(cbWaitStartTime);

  // If there is an error either in Context diagsArea or
  // in StatementGlobals_ diagsArea, do not update the end time
  ComDiagsArea *diagsArea = context_->getDiagsArea();
  if (diagsArea->mainSQLCODE() >= 0 && stmtStats_ != NULL &&
    stmtStats_->getMasterStats() != NULL && (! stmtStats_->aqrInProgress())
      && stmtStats_->getMasterStats()->getExeEndTime() == -1)
  {
    Int64 exeEndTime = NA_JulianTimestamp();
    stmtStats_->getMasterStats()->setExeEndTime(exeEndTime);
    stmtStats_->getMasterStats()->setElapsedEndTime(exeEndTime);
  }

  // If this is a CALL statement that can produce result sets (as
  // indicated by a non-NULL return value from getResultSetInfo())
  // then we may need to tell the UDR server to release this
  // transaction.
  ExRsInfo *rsInfo = getResultSetInfo();
  if (rsInfo)
  {
    StmtDebug0("  About to call ExRsInfo::suspendUdrTx()...");
    rsInfo->suspendUdrTx(*statementGlobals_);
    StmtDebug0("  Done");
  }

  // Make sure there are no outstanding transactional UDR requests
  completeUdrRequests(allWorkRequests);

  
  // Ideally, we would want to set this state for all cursors.
  // But we found that setting it for all results in an unnecessary call to
  // removeFromOpenStatementList() when the state is changed from RELEASE_TRANS_ 
  // to CLOSE_ even when the cursor was already closed earlier.
  if (isAnsiHoldable())
    setState(RELEASE_TRANS_);
  else
  if (isPubsubHoldable())
  {
    if (! getRootTdb()->getPsholdUpdateBeforeFetch())
      setState(RELEASE_TRANS_);
  }

  StmtDebug1("[END releaseTransaction] %p", this);
  return SUCCESS;
}

void Statement::releaseEsps(NABoolean closeAllOpens)
{
  if (!statementGlobals_)
    return;

  ExRtFragTable *fragTable = statementGlobals_->getRtFragTable();
  if (!fragTable)
    return;

  fragTable->releaseEsps(closeAllOpens);
	  
  // wait until all release esp replies have come back
  NABoolean hasTimedout;
  IpcTimeout espReleaseTimeout;
  espReleaseTimeout = context_->getEspReleaseTimeout();
  if (espReleaseTimeout != -1)
    espReleaseTimeout *= 6000;
  while (fragTable->hasOutstandingReleaseEspMsges())
    {
      statementGlobals_->getIpcEnvironment()->getAllConnections()->
        waitOnAll(5*6000, FALSE, &hasTimedout);// Wait up to 5 minutes
      if (hasTimedout)
        {
          // not all replied after 5 minutes, something is wrong
          char msg[300];
          str_sprintf(msg, "Timedout! Still have %d release esp messages and %d I/O outstanding.",
                      fragTable->numOutstandingReleaseEspMsges(),
                      statementGlobals_->getIpcEnvironment()
                      ->getAllConnections()->getNumPendingIOs());
          SQLMXLoggingArea::logExecRtInfo("Statement.cpp", 0, msg, 0);
          // abort remaining release esp msgs
          fragTable->abandonPendingIOs();
        } // if (hasTimedout)
    } // while
}

RETCODE Statement::bindTo(Statement * stmt)
{
  StmtDebug2("[BEGIN bindTo] Binding clone %p to master %p",
             this, stmt);

  root_tdb = stmt->root_tdb;
  clonedFrom_ = stmt;
  setState(CLOSE_); // does this work here????
  setCloned();
  stmt->clonedStatements->insert((void *) this);

  StmtDebug0("[END bindTo]");
  return SUCCESS;
}

bool Statement::isOpen()
{
  switch (stmt_state)
  {
    case OPEN_:
    case FETCH_:
    case EOF_:
    case PREPARE_:
    case RELEASE_TRANS_:
    case INITIAL_:
      return true;
    default:
      return false;
  }
}

RETCODE Statement::close(ComDiagsArea &diagsArea, NABoolean inRollback)
{  
  StmtDebug2("[BEGIN close] %p, stmt state %s", this, stmtState(getState()));
  RETCODE rc = SUCCESS;
  NABoolean readyToReturn = FALSE;

  if (!isOpen())
  {
      // trying to close a statement which is already in closed state
      diagsArea << DgSqlCode(- CLI_STMT_NOT_OPEN);
    rc = ERROR;
    readyToReturn = TRUE;
  }

  NABoolean closingEmbeddedIUDCursorPrematurely = FALSE; 

  if (!readyToReturn)
  {
    if ((stmt_state == OPEN_) && 
        (root_tdb && root_tdb->isEmbeddedIUDWithLast1()))
    {
      closingEmbeddedIUDCursorPrematurely = TRUE;
    }

    // Update stmtGlobals transid with current transid.
    // The stmtGlobals transid is used in sending release msg to remote esps.
    // The context transid can be obsolete if the transaction has been 
    // committed/aborted by the user.
    Int64 transid;
    if (!context_->getTransaction()->getCurrentXnId(&transid))
      getGlobals()->castToExExeStmtGlobals()->getTransid() = transid;
    else 
      getGlobals()->castToExExeStmtGlobals()->getTransid() = (Int64)-1;

  // cancel the down request to my child
    if (root_tcb)
    {
      ComDiagsArea *diagsPtr = NULL;

      // pass flag to cancel to collect diags from queue entries 
      // if stmt_state is OPEN_.  This is needed to pick up diags
      // info from failed DDL operations.
      NABoolean pickUpDiags =
        (   // False if DML, true otherwise
           (root_tdb->getQueryType() < ComTdbRoot::SQL_SELECT_UNIQUE)     ||
           (root_tdb->getQueryType() > ComTdbRoot::SQL_DELETE_NON_UNIQUE)
        );

      Int32 rc1 =
      root_tcb->cancel(statementGlobals_, diagsPtr, pickUpDiags);

      StmtDebug1("  root_tcb->cancel() returned %s",
                 RetcodeToString((RETCODE) rc1));
      if (diagsPtr)
	{
	  diagsArea.mergeAfter(*diagsPtr);
	  diagsPtr->decrRefCount();    
          diagsPtr = NULL;
	}
      if (root_tcb->fatalErrorOccurred())
        {
          dealloc();
          space_.freeBlocks();
          statementGlobals_->reAllocate(1);
          setFixupState(0);
        }
    }
  }

  if (!readyToReturn)
  {
    // If this statement has stored procedure result set children,
    // then close each child. Ignore errors encountered while closing
    // the children.
    ExRsInfo *rsInfo = getResultSetInfo();
    if (rsInfo)
    {
      ULng32 numChildren = rsInfo->getNumEntries();
      StmtDebug0("  About to close all result set proxy statements");
      StmtDebug1("  Num RS children: %d", (Lng32) numChildren);

      ComDiagsArea *diagsFromProxy = NULL;

      for (ULng32 i = 1; i <= numChildren && !readyToReturn; i++)
      {
        Statement *proxyStmt = NULL;
        const char *proxySyntax = NULL;
        NABoolean open = FALSE;
        NABoolean closed = FALSE;
        NABoolean prepared = FALSE;
        NABoolean found = rsInfo->getRsInfo(i, proxyStmt, proxySyntax,
                                            open, closed, prepared);

        if (found && proxyStmt && proxyStmt->stmt_state != CLOSE_)
        {
          if (diagsFromProxy == NULL)
            diagsFromProxy = ComDiagsArea::allocate(&heap_);

          RETCODE rcFromProxy = proxyStmt->close(*diagsFromProxy);
          diagsFromProxy->clear();
        }

      } // for each proxy

      if (diagsFromProxy)
        diagsFromProxy->deAllocate();

      StmtDebug0("  About to call ExRsInfo::exitUdrTx()...");
      rsInfo->exitUdrTx(*statementGlobals_);
      StmtDebug0("  Done");
      rsInfo->reset();
    } // if (rsInfo)
  
      releaseTransaction(TRUE, FALSE);

    setState(CLOSE_);

    if (closingEmbeddedIUDCursorPrematurely)
    {
      diagsArea << DgSqlCode(- CLI_IUD_IN_PROGRESS) << DgString0(getCursorName()->identifier);
      if (rollbackTransaction(diagsArea))
          return ERROR;
    }

    // stop the transaction, if one was started and if we are not
    // currently rolling back this transaction
    if (!inRollback)
    {
      if ((root_tdb && root_tdb->transactionReqd()) ||
          ((context_->getTransaction()->xnInProgress()) &&
          (context_->getTransaction()->exeStartedXn()) &&
          (context_->getTransaction()->autoCommit()) &&
          (autocommitXn())))
        {
          if (commitTransaction(diagsArea))
          {
            rc = ERROR;
            readyToReturn = TRUE;
          }
        }
    } // !inRollback
  } // !readyToReturn
  updateStatsAreaInContext();
  // Get rid of child query info if there is any
  if (childQueryId_ != NULL)
  {
    NADELETEBASIC(childQueryId_, &heap_);
    childQueryId_ = NULL;
    childQueryIdLen_ = 0;
  }
  if (childQueryCostInfo_ != NULL)
  {
    NADELETEBASIC(childQueryCostInfo_, &heap_);
    childQueryCostInfo_ = NULL;
  }
  if (childQueryCompStatsInfo_ != NULL)
  {
    NADELETEBASIC(childQueryCompStatsInfo_, &heap_);
    childQueryCompStatsInfo_ = NULL;
  }

  // clear transId from statement globals as it is no longer needed
  // this is to avoid reuse the transId when deleting the statement
  statementGlobals_->getTransid() = (Int64)-1;

  StmtDebug2("[END close] %p, result is %s", this,
             RetcodeToString(rc));
  return rc;
}

static inline void diagsTakeOver(ComDiagsArea &diagsArea,
				 CliGlobals *cliGlobals,
                                  short indexIntoCompilerArray)
{
  ComDiagsArea &exec_diags =
    *cliGlobals->getArkcmp(indexIntoCompilerArray)->getDiags();
  if (&diagsArea != &exec_diags)
    {
      if (diagsArea.getFunction() == ComDiagsArea::NULL_FUNCTION)
	diagsArea.setFunction(exec_diags.getFunction());
      diagsArea.mergeAfter(exec_diags);
      exec_diags.clear();
    }
}

NABoolean Statement::isDISPLAY()
{
  QueryText qt(source_str, charset_);
  return qt.isDISPLAY();
}

NABoolean Statement::isExeDebug(char *src, Lng32 charset)
{
  if (!src) {
    return FALSE;
  }
  else {
    if (charset == SQLCHARSETCODE_UCS2) {
          NAWchar* p = (NAWchar*)(src) + 7;
         
          return  p[0] == NAWchar('$') &&
                  p[1] == NAWchar('Z') &&
                  p[2] == NAWchar('Z') &&
                  p[3] == NAWchar('E') &&
                  p[4] == NAWchar('X') &&
                  p[5] == NAWchar('E') &&
                  p[6] == NAWchar('D') &&
                  p[7] == NAWchar('E') &&
                  p[8] == NAWchar('B') &&
                  p[9] == NAWchar('U') &&
                  p[10] == NAWchar('G') ;
    }
    else {
	  return str_cmp(src+7, "$ZZEXEDEBUG", str_len("$ZZEXEDEBUG")) == 0;
    }
  }
}

Int32 Statement::octetLen(char *s, Lng32 charset)
{
  return charset==SQLCHARSETCODE_UCS2 ?  
    na_wcslen((const NAWchar*)s) * 
    CharInfo::maxBytesPerChar((CharInfo::CharSet)charset) : str_len(s);
}

Int32 Statement::octetLenplus1(char *s, Lng32 charset)
{
  return charset==SQLCHARSETCODE_UCS2 ? 
    (na_wcslen((const NAWchar*)s)+1)*
    CharInfo::maxBytesPerChar((CharInfo::CharSet)charset) : str_len(s)+1;
}

Int32 Statement::sourceLenplus1()
{
  return (source_length+1)*CharInfo::maxBytesPerChar((CharInfo::CharSet)charset_);
}

RETCODE Statement::prepareReturn ( const RETCODE retcode)
{
  if (versionToUse_ != versionOnEntry_)
  {
    // We changed the current compiler, reset it
    short index;
    getContext()->setOrStartCompiler(versionOnEntry_, NULL, index);
  }

  // Unconditionally reset version on entry.
  versionOnEntry_ = COM_VERS_UNKNOWN;
  if (retcode != NOT_FINISHED)
  {
    // We're done with the prepare, reset the version we used
    versionToUse_ = COM_VERS_UNKNOWN;
  }

  return retcode;
}

/*
NABoolean Statement::isStandaloneQ()
{
  NABoolean standaloneQ = FALSE;

  // if query from mxcs and the statement name starts with "SQL_CUR_",
  // then it is a standalone query. This is standard and guaranteed
  // mxcs behavior.
  // or if query is from mxci and the statement name starts 
  // with "__SQLCI_", then it is a standalone query.
  if ((getContext()->getSessionDefaults()->getOdbcProcess()) &&
      (statement_id->identifier_len > 0) &&
      (strncmp(statement_id->identifier, "SQL_CUR_", strlen("SQL_CUR_")) == 0))
    {
    standaloneQ = TRUE;
    }
  else if ((getContext()->getSessionDefaults()->getMxciProcess()) &&
	   (statement_id->identifier_len > 0) &&
	   (strncmp(statement_id->identifier, "__SQLCI_DML_", strlen("__SQLCI_DML_")) == 0))
    {
      standaloneQ = TRUE;
    }
  
  return standaloneQ;
}
*/
RETCODE Statement::prepare(char *source, ComDiagsArea &diagsArea,
			   char *passed_gen_code, 
			   ULng32 passed_gen_code_len,
			   Lng32 charset,
			   NABoolean unpackTdbs,
			   ULng32 cliFlags)
{
  StmtDebug1("[BEGIN prepare] %p", this);
  StmtDebug1("  Source: %s",
             source ? source : (source_str ? source_str : "(NULL)"));

  state_ = INITIAL_STATE_;

  if (aqrReprepareNeeded())
    setAqrReprepareNeeded(FALSE);

  if (NOT ((! (cliFlags & PREPARE_AUTO_QUERY_RETRY)) &&
	   (cliFlags & PREPARE_STANDALONE_QUERY) &&
	   source &&
	   (stmt_type == DYNAMIC_STMT) &&
	   unpackTdbs &&
	   (context_->getNumOfCliCalls() == 1)))
    {
      // do not use query text cache for explicitely prepared queries.
      cliFlags |= PREPARE_NO_TEXT_CACHE;
    }
  
  if (context_->aqrInfo())
    context_->aqrInfo()->setXnStartedAtPrepare(FALSE);
  
  RETCODE rc = prepare2(source, diagsArea, 
			passed_gen_code, passed_gen_code_len,
			charset, unpackTdbs, cliFlags);

  StmtDebug2("[END prepare] %p, result is %s", this, RetcodeToString(rc));
  return rc;
}

RETCODE Statement::prepare2(char *source, ComDiagsArea &diagsArea,
                            char *passed_gen_code, 
			    ULng32 passed_gen_code_len,
			    Lng32 charset,
			    NABoolean unpackTdbs,
			    ULng32 cliFlags)
{
  ULng32 fetched_gen_code_len = 0L;
  char *fetched_gen_code = NULL;
  short retcode = SUCCESS;   
  short indexIntoCompilerArray = 0;
     
  // if there is any error using embedded cmpiler and we will switch to regular compiler
  NABoolean canUseEmbeddedArkcmp = ((cliFlags & PREPARE_USE_EMBEDDED_ARKCMP) != 0) ; // This flag 
  // will be set only by the master. If a Prepare call is made from the 
  // compiler(including the embedded compiler), it will use the regular compiler.

  ExSqlComp::OperationStatus status;
  Dealloc dealloc; // DTOR calls NAHeap::deallocateMemory for an object

  //  NABoolean newOperation = TRUE;
  NABoolean newOperation = (NOT ((cliFlags & PREPARE_NOT_A_NEW_OPERATION) != 0));
  NABoolean reComp       = (cliFlags & PREPARE_RECOMP) != 0;
  NABoolean aqRetry      = (cliFlags & PREPARE_AUTO_QUERY_RETRY) != 0;
  NABoolean deCache      = (cliFlags & PREPARE_WITH_DECACHE) != 0;
  NABoolean noTextCache  = (cliFlags & PREPARE_NO_TEXT_CACHE) != 0;
  NABoolean standaloneQuery = (cliFlags & PREPARE_STANDALONE_QUERY) != 0;
  NABoolean doNotCache   = (cliFlags & PREPARE_DONT_CACHE) != 0;
  this->setStandaloneQ(standaloneQuery);

  NABoolean wmsMonitoringNeeded = (cliFlags & PREPARE_MONITOR_THIS_QUERY) !=0;

  this->setWMSMonitorQuery(wmsMonitoringNeeded);
  // Remove compileStatsArea, if it exists
  if (compileStatsArea_  != NULL)
  {
    NADELETE(compileStatsArea_, ExStatisticsArea, compileStatsArea_->getHeap());
    compileStatsArea_ = NULL;
  }
  // We should not do prepares on a cloned statement. Clones share a
  // TDB tree with some other statement and compiles/recompiles should
  // always be done by that other statement.
  ex_assert(!isCloned(),
            "Statement::prepare() should not be called on a clone");

  // We may be doing a prepare for two reasons: 1) as part of a
  // dynamic SQL PREPARE operation or 2) as part of automatic
  // recompilation. The first case includes such things as 
  // EXECUTE IMMEDIATE and internal calls to prepare statements.
  // 
  // The value returned by the noWaitOpPending() member in the Statement 
  // object must be interpreted very carefully here, because its 
  // meaning depends on which of these two cases
  // we are in. In the first case, where we are doing an explicit
  // prepare, noWaitOpPending() TRUE implies that we are trying
  // to start a new explicit operation on a statement that already
  // has a no-wait operation in progress. This is a user error,
  // and is raised as such in this method.
  //
  // In the second case, however, this method has been called
  // from another Statement method to do an automatic recompilation.
  // If noWaitOpPending() == TRUE in this case, it is because the
  // calling method is processing an outstanding no-wait operation.
  // So, for example, we might be attempting an automatic
  // recompilation while redriving a no-wait fetch. This is not
  // a user error; in fact we want the automatic recompilation
  // to succeed.
  //
  // The way to distinguish these two cases is to consider the
  // reComp parameter. If it is FALSE, we know it is the first
  // case. If it is TRUE, we know it is the second.
  //
  // For the moment, we make all automatic recompilations waited,
  // even if we are redriving a no-wait operation. The reason we
  // do this is the Statement object lacks the state, and the
  // calling methods lack the logic, to detect on a redrive that
  // a no-wait automatic recompilation is in effect. This is a 
  // refactoring opportunity for a clever developer in a future 
  // release ;-).
  //
  // Note that since we make automatic recompilations waited,
  // we treat the noWaitOpEnabled_ flag differently in this case
  // as well.
  //
  // In this method, then, instead of testing noWaitOpPending_
  // directly, we use the following flag which takes reComp
  // into account.


  Lng32 rsa = getRowsetAtomicity();
  if (context_->getSessionDefaults()->getRowsetAtomicity() != -1)
    rsa = context_->getSessionDefaults()->getRowsetAtomicity(); //NOT_ATOMIC_;

  if (canUseEmbeddedArkcmp && !context_->isEmbeddedArkcmpInitialized())
    {
      Int32 embeddedArkcmpSetup;
      // embeddedArkcmpSetup = arkcmp_main_entry();
      embeddedArkcmpSetup = context_->switchToCmpContext((Int32)0);
      if (embeddedArkcmpSetup == 0)           
        {
          context_->setEmbeddedArkcmpIsInitialized(TRUE);
        }
      else if (embeddedArkcmpSetup == -2)
        {
          diagsArea << DgSqlCode(-2079);
          return ERROR;
        }
      else
        {
          context_->setEmbeddedArkcmpIsInitialized(FALSE);
          context_->setEmbeddedArkcmpContext(NULL);
        }
    }
  // Set the Global CmpContext from the one saved in the CLI context
  // for proper operation
  if (context_->isEmbeddedArkcmpInitialized() &&
      context_->getEmbeddedArkcmpContext())
    {
      cmpCurrentContext = context_->getEmbeddedArkcmpContext();
    }
    
  if (newOperation)
    assert ((aqRetry && source) ||
	    ((!reComp) || (reComp && (!source))));

  if ((reComp) && (stmt_type == STATIC_STMT))
    {
    }
#ifdef _DEBUG
  if (getenv("TEST_INFO_EVENT"))
    {

      SQLMXLoggingArea::logSQLMXEventForError(0000, "Dummy Error with Dummy SQCode and QID", "DummyQID", FALSE);

      SQLMXLoggingArea::logExecRtInfo("Statement.cpp",999,"Testing info event", 999);
      
      SQLMXLoggingArea::logSQLMXAbortEvent("Statement.cpp",888, "testing abort event");
      SQLMXLoggingArea::logSQLMXAssertionFailureEvent("Statement.cpp",777,"testing assertion failure");
      SQLMXLoggingArea::logSQLMXDebugEvent("debug event" ,69,__LINE__);
      
      SQLMXLoggingArea::logMVRefreshInfoEvent("mv refresh info");
      SQLMXLoggingArea::logMVRefreshErrorEvent("mv refresh error");

      SQLMXLoggingArea::logCliReclaimSpaceEvent(100,200,300,400);

      SQLMXLoggingArea::logCompNQCretryEvent("select * from t1 where a > 10");
      SQLMXLoggingArea::logSortDiskInfo("disk101", 25, 2080);

      const char msgT[] = "SQL compiler: Optimization failed at pass two or higher. " 
                          "Execution will use the plan generated at pass one instead.";

      SQLMXLoggingArea::logSQLMXPredefinedEvent(msgT, LL_WARN);
    }
 #endif
  
  if (passed_gen_code)
    {
      // it is legal for passed_gen_code to be passed in as NULL here!
      copyGenCode(passed_gen_code, passed_gen_code_len, FALSE);

      
    }
  else if ((source) ||               // source is passed in. Preparing a stmt.
	   ((!source) && (reComp)) || // recompiling a statement at runtime.
	    !newOperation)
    {
      if (isExeDebug(source, charset))
	{
	  NADebug();
	  diagsArea << DgSqlCode(- CLI_STMT_NOT_PREPARED);
          // OK to return directly, we haven't done anything to
          // the current compiler settings yet
	  return ERROR;
	}
      
      if (context_->checkAndSetCurrentDefineContext())
	{

	     // define context changed, kill arkcmps, if they are runing.
             for (short i = 0; 
		  i < getContext()->getNumArkcmps();
		  i++)
	       cliGlobals_->getArkcmp(i)->endConnection();

	}

      // Get the version of compiler to use initially. There are several possibilities.
      // a) No particular version compiler is required, we use whatever is the current version.
      // b) The compiler version was explicitly set from outside, using setOrStartCompiler.
      //    This may happen for automatic retry of plan version errors, and for certain DDL
      //    operations.
      // c) The compiler version was requested, using the versionToUse_ data member.
      //    This may happen if a non-retryable statement encountered a plan version error.
      // In all cases, save whatever version was the default for our caller since prepare
      // may automatically set the compiler version further down the road.
      // 
      versionOnEntry_ = context_->getVersionOfCompiler();
      if (newOperation && (versionToUse_ == COM_VERS_UNKNOWN))
      {
        // This is a new prepare, and a particular version was not requested.
        // Use the version from the context.
        indexIntoCompilerArray = context_->getIndexToCompilerArray();  
        versionToUse_ = versionOnEntry_;
      }
      else
      {
        // This is a redrive of a nowait prepare, or a particular version was requested.
        // Use whatever we used originally/whatever is requested.
        getContext()->setOrStartCompiler(versionToUse_, NULL, indexIntoCompilerArray);
      }

      // From this point on, do not return directly as that will mess up the current compiler version.
      // Instead, do 
      //    return prepareReturn (<retcode>);
      short retry = TRUE;
      char * data = NULL;
      ULng32 dataLen = 0;
      ExSqlComp::Operator op;
      while (retry)
	{
	  if (newOperation)
	    {

	      // Build request and send to arkcmp. 
	      if ((reComp) || (aqRetry && deCache))
		{
		  CmpCompileInfo c((reComp ? source_str : source), 
				   (reComp ? sourceLenplus1() : octetLenplus1(source, charset)),
				   (Lng32) (reComp ? charset_ : charset),
				   schemaName_, schemaNameLength_+1, 
				   getInputArrayMaxsize(), (short)rsa);

		  if (aqRetry)
		    c.setAqrPrepare(aqRetry);
		  else if (noTextCache)
		  c.setNoTextCache(noTextCache);
		  c.setDoNotCachePlan(doNotCache);
		  
		  if (standaloneQuery)
		    c.setStandaloneQuery(standaloneQuery);

		  // if this statement was statically compiled with odbc process
		  // on, then set it here. This will be used at auto recomp time.
		  c.setOdbcProcess(odbcProcess());
		  c.setSystemModuleStmt(systemModuleStmt());   
                  c.setAnsiHoldable(isAnsiHoldable());
                  c.setPubsubHoldable(isPubsubHoldable());
              	  dataLen = c.getLength();
		  // Dealloc dtor will deallocate the memory allocated by next statement
		  data = (char *)dealloc.getAddr
		    (new(dealloc.setHeap(&heap_)) char[dataLen]);
		  c.pack(data);
		  
		  // Release the existing TDB tree if one exists
		  assignRootTdb(NULL);
		  
		  op = (getStatementType() == DYNAMIC_STMT) ?
		    EXSQLCOMP::SQLTEXT_RECOMPILE :
		    EXSQLCOMP::SQLTEXT_STATIC_RECOMPILE;
		  
		  
		  // The R1.8 compiler does not understand the above type
		  // EXSQLCOMP::SQLTEXT_STATIC_RECOMPILE. So if we are talking
		  // to an R1.8 compiler then we have to change the type to
		  // EXSQLCOMP::SQLTEXT_STATIC_COMPILE
		  
		  if (cliGlobals_->getArkcmp(indexIntoCompilerArray)->
		      getVersion() == COM_VERS_R1_8 )
		    {
		      op = (getStatementType() == DYNAMIC_STMT) ?
			EXSQLCOMP::SQLTEXT_RECOMPILE :
			EXSQLCOMP::SQLTEXT_STATIC_COMPILE;
		    }
		} // recompiling statement
	      else
		{
		  CmpCompileInfo c(source, octetLenplus1(source, charset), (Lng32) charset,
				   NULL, 0,
				   getInputArrayMaxsize(), (short)rsa);

		  if (aqRetry)
		    c.setAqrPrepare(aqRetry);
		  else if (noTextCache)
		  c.setNoTextCache(noTextCache);
		  c.setDoNotCachePlan(doNotCache);

		  if (standaloneQuery)
		    c.setStandaloneQuery(standaloneQuery);
        	  c.setAnsiHoldable(isAnsiHoldable());
                  c.setPubsubHoldable(isPubsubHoldable());
                  dataLen = c.getLength();
		  // Dealloc dtor will deallocate the memory allocated by next statement
		  data = (char *)dealloc.getAddr
		    (new(dealloc.setHeap(&heap_)) char[dataLen]);
		  c.pack(data);
		  
		  op = EXSQLCOMP::SQLTEXT_COMPILE;
		}
	      
                
	      // send request
	      // request is nowaited if noWaitOpEnabled and not recompile
	      NABoolean waited = TRUE;

              // Use the embedded compiler first
              if (context_->getSessionDefaults()->callEmbeddedArkcmp() && 
		  canUseEmbeddedArkcmp && 
		  context_->isEmbeddedArkcmpInitialized() &&
		  CmpCommon::context() && (CmpCommon::context()->getRecursionLevel() == 0))
		  //!aqRetry  && cliGlobals_->isEmbeddedArkcmpInitialized())
                {
                  Int32 compStatus;
                  ComDiagsArea *da = NULL;

                  // clean up diags area of regular arkcmp, it could contain
                  // old errors from last use
                  if (cliGlobals_->getArkcmp() &&
                      cliGlobals_->getArkcmp()->getDiags())
                     cliGlobals_->getArkcmp()->getDiags()->clear();

                  compStatus = CmpCommon::context()->compileDirect(
                                   (char *)data, dataLen,
                                   // use arkcmp heap to store the plan
                                   // check why indexIntoCompilerArray is used here?
                                   cliGlobals_->getArkcmp(indexIntoCompilerArray)->getHeap(),
                                   charset, op,
                                   fetched_gen_code, fetched_gen_code_len,
                                   context_->getSqlParserFlags(), 
                                   NULL, 0, da);
                  if (da != NULL) 
                  {
                     diagsArea.mergeAfter(*da);
                     da->decrRefCount();
                  }

                  if (compStatus == ExSqlComp::SUCCESS)
                    {
                      // break from the while (retry) loop
                      break;
                    }
                  else
		    {
		      diagsArea << DgSqlCode(- CLI_STMT_NOT_PREPARED);
		      if (diagsArea.getRollbackTransaction())
		     	rollbackTransaction(diagsArea);
		      return prepareReturn (ERROR);
		    }
                }

	      ExSqlComp::ReturnStatus sendStatus = 
		cliGlobals_->getArkcmp(indexIntoCompilerArray)->sendRequest(
		     op, data, dataLen,
		     waited, 
		     0, charset, TRUE);
	      
	      if ( sendStatus == ExSqlComp::ERROR || 
		   sendStatus == ExSqlComp::WARNING )
		{
		  diagsTakeOver(diagsArea, cliGlobals_,indexIntoCompilerArray);
		  if (sendStatus == ExSqlComp::ERROR)
		    {
		      setState(INITIAL_);
#ifndef _DEBUG
                      // For release, if the mxcmp could not reply
                      // to the request, use error -2005, to let the 
                      // user know that a dialout has been generated.
		      diagsArea << DgSqlCode(arkcmpErrorNoDiags);
		      diagsArea << DgString0(source);
#endif
                      diagsArea << DgSqlCode(- CLI_STMT_NOT_PREPARED);
                      if (diagsArea.getRollbackTransaction())
			rollbackTransaction(diagsArea);
		      return prepareReturn (ERROR);
		    }
		  else	//if (sendStatus == ExSqlComp::WARNING)
		    retcode = WARNING;
		}
	    } // if new operation
	  
	  // check for completion of request.
	  status = cliGlobals_->getArkcmp(indexIntoCompilerArray)->status();
	  
	  if ( status != ExSqlComp::FINISHED )
	      {
	      // waited request should complete. Return error.
	      diagsTakeOver(diagsArea, cliGlobals_,indexIntoCompilerArray);
	      diagsArea << DgSqlCode(- CLI_IO_REQUESTS_PENDING) 
			<< DgString0("SQLTEXT_COMPILE");
	      return prepareReturn (ERROR); 
	    }
	  
	  // initialize pointer to returned data(from reply) in private state.
	  ExSqlComp::ReturnStatus replyStatus = 
	    cliGlobals_->getArkcmp(indexIntoCompilerArray)->getReply(
		 fetched_gen_code, 
		 fetched_gen_code_len);
	  
          retry = FALSE;

          if (replyStatus != ExSqlComp::SUCCESS)
            {
              diagsTakeOver (diagsArea, cliGlobals_, indexIntoCompilerArray);
 
              if (replyStatus == ExSqlComp::ERROR)
                {
                  
                  if (retry == FALSE)
                  {
                    // An error other than 25304, or failure to start downrev compiler
                    setState(INITIAL_);
		    
		    if (ABS(diagsArea.mainSQLCODE()) != 4074
			||
			diagsArea.getNumber() != 1)
		      diagsArea << DgSqlCode(- CLI_STMT_NOT_PREPARED);
		    return prepareReturn (ERROR);
		  }
		}
	      else
                {
                  retcode = WARNING;
		}
	    }

	} // while retry
      context_->killIdleMxcmp();
      assignRootTdb((ex_root_tdb *)fetched_gen_code);
      root_tdb_size = (Lng32) fetched_gen_code_len;
    }
  
  if (root_tdb)
    {
      diagsArea.setCost(root_tdb->getCost());
    }
  if (unpackTdbs)
    retcode = (short)unpackAndInit(diagsArea, indexIntoCompilerArray);
  
  return (RETCODE)retcode;
} // Statement::prepare

Lng32 Statement::unpackAndInit(ComDiagsArea &diagsArea,
			      short indexIntoCompilerArray)
{
  Lng32 retcode = 0;

  // Do not unpack the root tdb if the statement is from showplan.
  // CmpDescribePlan will unpack it.
  ComTdbRoot *thisTdb = root_tdb;

  if (root_tdb && !thisTdb->isFromShowplan())
    {
      // Here, we have just freshly (re)prepared the plan using the latest
      // version of the compiler. Unpacking should be uneventful (i.e. no
      // object version migration should happen). Therefore, it should not
      // be necessary to reallocate space.
      //
      ComTdb dummyTdb;
      ex_root_tdb *newRoot = (ex_root_tdb *)
	root_tdb->driveUnpack((void *) root_tdb, &dummyTdb, unpackSpace_);
      
      if (newRoot == NULL)  
	{
	  // ERROR during unpacking. 
	  if ((indexIntoCompilerArray >= 0) &&
	      (cliGlobals_->getArkcmp(indexIntoCompilerArray)->getDiags()))
	    diagsArea.mergeAfter(*cliGlobals_->getArkcmp()->getDiags());
	  diagsArea << DgSqlCode(- CLI_STMT_NOT_PREPARED);
          return prepareReturn (ERROR); 
	}

      assignRootTdb(newRoot);
    }


      if ( (versionToUse_ != COM_VERS_COMPILER_VERSION)                    && // Used a downrev compiler
           (returnRecompWarn())                                            && // Will return recomp warnings
           (root_tdb->getQueryType() >= ComTdbRoot::SQL_SELECT_UNIQUE)     && // Query is DML
           (root_tdb->getQueryType() <= ComTdbRoot::SQL_DELETE_NON_UNIQUE)
         )
      {
        // We compiled a DML query with a downrev compiler - save information so that we can 
        // issue warning 25304 if required. We do this rather than issue the warning directly,
        // because we want warning 8576: Query was recompiled, to precede warning 25304 if applicable.
	mxcmpErrorCode_ = VERSION_COMPILER_USED_TO_COMPILE_QUERY;
        mxcmpStartedVersion_ = (COM_VERSION) versionToUse_; 
      }

  // Reset state in this statement, then loop through all clones and
  // make corresponding state changes in each.
  if (root_tdb)
    {
      setComputeBulkMoveInfo(TRUE);
    }
  setFixupState(0);
  setState(CLOSE_);
  setFirstResolveDone(FALSE);
  lnil_ = NULL;
  
  clonedStatements->position();
  Statement * clone = (Statement*)clonedStatements->getNext();
  for (; clone != NULL; clone = (Statement*)clonedStatements->getNext())
    {
      if (clone->root_tdb)
	{
	  clone->setComputeBulkMoveInfo(TRUE);
	}
      clone->setFixupState(0);
      clone->setState(CLOSE_);
      clone->setFirstResolveDone(FALSE);
      clone->lnil_ = NULL;
    }
  
  if (indexIntoCompilerArray >= 0)
    diagsTakeOver(diagsArea, cliGlobals_,indexIntoCompilerArray);
  
  if (root_tdb)
    diagsArea.setCost(root_tdb->getCost());
  StatsGlobals *statsGlobals = cliGlobals_->getStatsGlobals();
  Lng32 fragOffset;
  Lng32 fragLen;
  Lng32 topNodeOffset;
  SessionDefaults *sessionDefaults =
       context_->getSessionDefaults();
  if (statsGlobals != NULL && stmtStats_ != NULL && root_tdb != NULL 
        && getUniqueStmtId() != NULL) 
  {
    ex_root_tdb *rootTdb = getRootTdb();
    //root_tdb is not unpacked for SHOWPLAN and 
    // explain fragment can't be obtained for such prepared queries
    if (!rootTdb->isPacked() && rootTdb->explainInRms() &&
        rootTdb->getFragDir()->getExplainFragDirEntry
                 (fragOffset, fragLen, topNodeOffset) == 0)
    {
      int error = statsGlobals->getStatsSemaphore(cliGlobals_->getSemId(),
            cliGlobals_->myPin());
      stmtStats_->setExplainFrag((void *)(((char *)root_tdb)+fragOffset), fragLen, topNodeOffset);
      statsGlobals->releaseStatsSemaphore(cliGlobals_->getSemId(),cliGlobals_->myPin());
    }
  }
  return prepareReturn ((RETCODE)retcode);
}

RETCODE Statement::closeTables(ComDiagsArea &diagsArea)
{
  // cancel the down request to my child
  ComDiagsArea *diagsPtr = NULL;
  Int32 retcode = root_tcb->cancel(statementGlobals_,diagsPtr);
  StmtDebug1("  root_tcb->cancel() returned %s",
             RetcodeToString((RETCODE) retcode));
  if (diagsPtr)
    {
      diagsArea.mergeAfter(*diagsPtr);
      diagsPtr->decrRefCount();    
      diagsPtr = NULL;
    }

  if (retcode)
    return ERROR;
  
  retcode = root_tcb->closeTables(statementGlobals_,
                                  statementGlobals_->getRtFragTable());
  if (retcode)
    return ERROR;
  
  return SUCCESS;
}

RETCODE Statement::reOpenTables(ComDiagsArea &diagsArea)
{
  closeTables(diagsArea);

  Int32 retcode =
    root_tcb->reOpenTables(
	 statementGlobals_,
	 statementGlobals_->getRtFragTable());
  if (retcode)
    return ERROR;
  
  return SUCCESS;
}

/////////////////////////////////////////////////////////////////////
// Searches for the given cursorName in the statement list. If found,
// and the cursor is an updatable cursor, returns pointer to that
// statement. Else, returns NULL.
/////////////////////////////////////////////////////////////////////
Statement * Statement::getCurrentOfCursorStatement(char * cursorName)
{
  ComDiagsArea &diags = context_->diags();

  if (!cursorName)
     return NULL;

  char nameBuf[ComMAX_1_PART_EXTERNAL_UTF8_NAME_LEN_IN_BYTES + 1 + 16]; // a null terminator + a few extra bytes
  char *pName = nameBuf;
  Lng32 len = str_len(cursorName);

  if (len > sizeof(nameBuf) - 1)
    pName = (char *)heap_.allocateMemory(len + 1);

  str_cpy_all(pName, cursorName, len);
  pName[len] = '\0';
  str_strip_blanks(pName,len);
  // Convert to ansi id format
  if (str_to_ansi_id(cursorName,pName,len))
	{
          diags << DgSqlCode(-CLI_INVALID_SQL_ID)
       << DgString0(pName);
        return NULL;
	}
  HashQueue * cursorList =
    context_->getCursorList();

  Statement *pStmt = NULL;
  Statement * stmt;
  
  cursorList->position(pName, len);
  while (stmt = (Statement *)cursorList->getNext())
    { 
      //char * stmtCursorName = stmt->getCursorName();
      SQLSTMT_ID* stmtCursorName = stmt->getCursorName();

// Need to use length in comparison when the
// new length argument is added for "cursorName".
      if (stmtCursorName &&
          (strcmp(pName, stmtCursorName->identifier) == 0))
        {
          if (stmt->getRootTdb() && (stmt->getRootTdb()->updatableSelect() ))
	    {
	      pStmt = stmt;
	      break;
	    }
          else
            break;
	  
        }
    }

  if (pName != nameBuf)
    heap_.deallocateMemory(pName);
  return pStmt;

}

RETCODE Statement::doHiveTableSimCheck(TrafSimilarityTableInfo *si,
                                       NABoolean &simCheckFailed,
                                       ComDiagsArea &diagsArea)
{
  simCheckFailed = FALSE;

  if ((si->hdfsRootDir() == NULL) || (si->modTS() == -1))
    return SUCCESS;
 
  char *tmpBuf = new (&heap_) char[ComMAX_3_PART_EXTERNAL_UTF8_NAME_LEN_IN_BYTES+6];
  Lng32 numParts = 0;
  char *parts[4];
  Int64 redefTime;

  LateNameInfo::extractParts(si->tableName(), tmpBuf, numParts, parts, FALSE);
  switch (numParts) {
     case 1:
        parts[2] = parts[0];
        parts[1] = (char *)"default";
        parts[0] = (char *)"HIVE";
        break;
     case 2:
        parts[2] = parts[1];
        parts[1] = parts[0];
        parts[0] = (char *)"HIVE";
        break;
     case 3:
        break;
     default:
        diagsArea << DgSqlCode(-24114);
        return ERROR;
  }
  if (stricmp(parts[1], "HIVE") == 0)
     parts[1] = (char *)"default";
  HVC_RetCode hvcRetcode = HiveClient_JNI::getRedefTime(parts[1], parts[2], redefTime);
  if (hvcRetcode == HVC_OK) {
     if (redefTime > si->modTS()) {
        simCheckFailed = TRUE;
        char errStr[strlen(si->tableName()) + 100 + strlen(si->hdfsRootDir())];
        snprintf(errStr,sizeof(errStr), 
               "compiledModTS = %ld, failedModTS = %ld, failedLoc = %s", 
               si->modTS(), redefTime, 
               si->hdfsRootDir());
        diagsArea << DgSqlCode(-EXE_HIVE_DATA_MOD_CHECK_ERROR)
                  << DgString0(errStr);
        NADELETEBASIC(tmpBuf, &heap_);
        return ERROR;
     }
  } else if (hvcRetcode == HVC_DONE) {
      char errBuf[strlen(si->tableName()) + 100 + strlen(si->hdfsRootDir())];
      snprintf(errBuf,sizeof(errBuf), "%s (fileLoc: %s)", si->tableName(), si->hdfsRootDir());
      diagsArea << DgSqlCode(-EXE_TABLE_NOT_FOUND)
                << DgString0(errBuf); 
      NADELETEBASIC(tmpBuf, &heap_);
      return ERROR;             
  } else {
     diagsArea << DgSqlCode(-1192)
          << DgString0("HiveClient_JNI::getRedefTime")
          << DgString1("")
          << DgInt0(hvcRetcode)
          << DgString2(getSqlJniErrorStr());
     NADELETEBASIC(tmpBuf, &heap_);
     return ERROR; 
  } 
  NADELETEBASIC(tmpBuf, &heap_);
  return SUCCESS;
}

RETCODE Statement::doQuerySimilarityCheck(TrafQuerySimilarityInfo * qsi,
					  NABoolean &simCheckFailed,
					  ComDiagsArea &diagsArea
					  )
{
  RETCODE retcode;

  simCheckFailed = FALSE;
  if ((! qsi) ||
      (qsi->disableSimCheck()) ||
      (! qsi->siList()) ||
      (qsi->siList()->numEntries() == 0))
    return SUCCESS;

  qsi->siList()->position();
  for (Lng32 i = 0; i < qsi->siList()->numEntries(); i++)
    {
      TrafSimilarityTableInfo *si = 
        (TrafSimilarityTableInfo *)qsi->siList()->getCurr();

      simCheckFailed = FALSE;
      if (si->isHive())
        {
          retcode = doHiveTableSimCheck(si,simCheckFailed, diagsArea);
          if (retcode == ERROR)
            {
              goto error_return; // diagsArea is set
            }
        }
    } // for

  return SUCCESS;
  
 error_return:
  return ERROR;
}

RETCODE Statement::fixup(CliGlobals * cliGlobals, Descriptor * input_desc,
			 ComDiagsArea &diagsArea, NABoolean &doSimCheck,
                         NABoolean &partitionUnavailable, const NABoolean donePrepare)
{
  Int32 retcode;
  ExMasterStats *masterStats;
 
  if ((stmtStats_) && ((masterStats = stmtStats_->getMasterStats()) != NULL))
     masterStats->setStmtState(STMT_FIXUP_);

  // Initialize this method's output parameters  
  doSimCheck = FALSE;
  partitionUnavailable = FALSE;

  if (fixupState() != 0)
    return ERROR;

  /* fixup the generated code */
  statementGlobals_->setStartAddr((void *)root_tdb);
  statementGlobals_->setCliGlobals(cliGlobals_);

  // Keep timeout data locally for this statement
  //  (The "root build" builds the messages to the ESPs by copying the 
  //   relevant timeout data from the master globals.)
  statementGlobals_->setLocalTimeoutData(root_tdb);

  // if this is part of an auto query retry and esp need to be cleaned up,
  // set that indication in root tcb.
  if ((context_->aqrInfo()) &&
      (context_->aqrInfo()->espCleanup()))
    {
      // set flag for verify ESPs - make sure esp in cache is alive before
      // reuse it.
      statementGlobals_->setVerifyESP();
    }

  root_tcb = (ex_root_tcb *)(root_tdb->build(cliGlobals, statementGlobals_));

  if ((context_->aqrInfo()) &&
      (context_->aqrInfo()->espCleanup()))
    {
      // reset flag for verify ESPs
      statementGlobals_->resetVerifyESP();
    }

  statementGlobals_->takeGlobalDiagsArea(diagsArea);

  if ((diagsArea.mainSQLCODE() < 0) || (!root_tcb))
    {
      if ((diagsArea.contains(-EXE_TIMESTAMP_MISMATCH) &&
           (NOT tsMismatched()))
          // if table not found, primary partition may have moved.
          // so, try a similarity check to verify it.
          || diagsArea.contains(-EXE_TABLE_NOT_FOUND))
	{
	  setTsMismatched(TRUE);
	  doSimCheck = TRUE;
	  return SUCCESS;
	}

      if (diagsArea.contains(-EXE_PARTITION_UNAVAILABLE))
          // if partition availability error, use the catalog manager
          // to attempt to find another partition.
	{
          partitionUnavailable = TRUE;
	  return SUCCESS;
	}

      setTsMismatched(FALSE);
      rollbackTransaction(diagsArea);
      return ERROR;
    }

  if (inputData_)
    {
      root_tcb->setInputData(inputData_);
    }
  
  // QStuff ^^
  if (isPubsubHoldable() || isAnsiHoldable())
    {
      root_tcb->propagateHoldable(TRUE);
    }
  // QStuff __

  retcode = root_tcb->fixup();

  if (retcode)
    {
      statementGlobals_->takeGlobalDiagsArea(diagsArea);

      // do similarity check if timestamp mismatch is returned at
      // fixup time.
      if (((diagsArea.contains(-EXE_TIMESTAMP_MISMATCH)) &&
	   (NOT tsMismatched()))
          || (diagsArea.contains(-EXE_TABLE_NOT_FOUND)))
	{
	  setTsMismatched(TRUE);
	  doSimCheck = TRUE;
	  return SUCCESS;
	}
      
      if (diagsArea.contains(-EXE_PARTITION_UNAVAILABLE))
          // if partition availability error, use the catalog manager
          // to attempt to find another partition.
	{
          partitionUnavailable = TRUE;
	  return SUCCESS;
	}

      setTsMismatched(FALSE);
      rollbackTransaction(diagsArea);
      return ERROR;
    }
  
  setTsMismatched(FALSE);

  // if this is an 'update where current of' query, and
  // the cursor statement was specified as a literal,
  // then find the cursor statement and hook it up here.
  if (root_tdb->updateCurrentOfQuery() &&
      root_tdb->fetchedCursorName())
    {
      currentOfCursorStatement_ =
	getCurrentOfCursorStatement(root_tdb->fetchedCursorName());
      
      if (currentOfCursorStatement_ == NULL)
	{
	  diagsArea << DgSqlCode(- CLI_NON_UPDATABLE_SELECT_CURSOR)
		    << DgString0(root_tdb->fetchedCursorName());
	  return ERROR;
	}
    }

  setFixupState(-1);

  return SUCCESS;
}

static
NABoolean compareTransModes(ex_root_tdb *root_tdb,
			    ExTransaction *currTransaction,
			    ComDiagsArea *diags = NULL,
                            NABoolean isSysModuleStmt = FALSE)
{
  TransMode
    &tmCompile = *root_tdb->getTransMode(),
    &tmRuntime = *currTransaction->getTransMode();

#ifdef _DEBUG
    static NABoolean dbg = !!getenv("TRANSMODE_DEBUG");
    if (dbg)
      cerr << "##tm: exe= " << tmRuntime.display()
           <<      " cmp= " << tmCompile.display()
           <<           " " << tmCompile.stmtLevelAccessOptions()
	   <<           " " << root_tdb->readonlyTransactionOK()
	   << endl;
#endif

  NABoolean recompileDueToRollbackMode = 
	( 
	  ((tmCompile.getRollbackMode() == TransMode::NO_ROLLBACK_IN_IUD_STATEMENT_) &&
	    (!currTransaction->autoCommit()))
	  ||
	  (((tmCompile.getRollbackMode() != TransMode::NO_ROLLBACK_IN_IUD_STATEMENT_) &&
	      (tmCompile.getRollbackMode() != TransMode::NO_ROLLBACK_)) &&
	    (tmRuntime.getRollbackMode() == TransMode::NO_ROLLBACK_))
	 ) ;

  NABoolean recompileDueToMultiCommitMode = !(tmCompile.multiCommitCompatible(tmRuntime));

  if (tmCompile.accessModeCompatible(tmRuntime) ||
      root_tdb->readonlyTransactionOK())
  {
    if (tmCompile.isolationLevelCompatible(tmRuntime) ||
        tmCompile.stmtLevelAccessOptions())
    {
      if( !recompileDueToRollbackMode && !recompileDueToMultiCommitMode)
	 return FALSE;
    }
  }

  // The run-time transaction mode ($0~int0) differs the compile-time ($1~int1).
  if (diags && !isSysModuleStmt)
    *diags << DgSqlCode(- CLI_TRANS_MODE_MISMATCH)
      << DgInt0(tmRuntime.display())
      << DgInt1(tmCompile.display())
      ;
  return TRUE;
}

inline static
void recompileReasonIsTransMode(ex_root_tdb *root_tdb,
				ExTransaction *currTransaction,
			 Lng32 recompileReason[])
{
  recompileReason[0] = CLI_TRANS_MODE_MISMATCH;
  recompileReason[1] = currTransaction->getTransMode()->display();
  recompileReason[2] = root_tdb->getTransMode()->display();
}

RETCODE Statement::error(ComDiagsArea &diagsArea)
{
  // Reset the autocommit flag to the user's view.
  resetAutoCommit();

  // abort the transaction, if auto commit is on or
  // rollbackTransaction flag is set in the diags area or
  // this is a query that would have dirtied the disk(like,
  // insert/update/delete). 
  rollbackTransaction(diagsArea);
  
  // if no other diags, as a last resort emit this rather 
  // cryptic message
  if (diagsArea.getNumber(DgSqlCode::ERROR_) == 0)
    diagsArea << DgSqlCode(- CLI_TCB_EXECUTE_ERROR);
  
  dealloc();
  space_.freeBlocks();
  statementGlobals_->reAllocate(1);
  
  setState(CLOSE_);
  
  setFixupState(0);
  
  return ERROR;
}

RETCODE Statement::execute(CliGlobals * cliGlobals, Descriptor * input_desc,
			   ComDiagsArea &diagsArea, ExecState  execute_state,
			   NABoolean fixupOnly, ULng32 cliflags)
{
  StmtDebug2("[BEGIN execute] %p, stmt_state %s", this, stmtState(getState()));

  RETCODE retcode = SUCCESS;
  NABoolean schemaFileLabelTSChecked = 0;

  NABoolean recompWarn;
  NABoolean partitionUnavailable = FALSE;
  NABoolean partitionAvailabilityChecked = FALSE;

  // This boolean indicates whether ANSI to Guardian name mappings
  // have failed following a "partition not available" error. The
  // first time we encounter such a failure we attempt an automatic
  // recompile and set this variable to TRUE. If the same failure is
  // encountered again after the recompile then we return an error to
  // the user.
  NABoolean partitionNameLookupsFailed = FALSE;

  // This boolean indicates whether a prepare has been done as part 
  // of this execution. If that is the case, visibility checks can
  // be skipped because the prepare will have done that already.
  NABoolean donePrepare = FALSE;

  Lng32 recompileReason[3];
  recompileReason[0] = recompileReason[1] = recompileReason[2] = 0;
  Int64 reCompileTime = (Int64)0;
  NABoolean reExecute=FALSE;
  ExMasterStats *masterStats = NULL;

  if (state_ != FIXUP_DONE_)
    state_ = execute_state;
  
  // To ensure correct handling of the implicit transactions (and
  // autocommit clearing and restoring) which happen when the CLI
  // makes recursive calls via CatMapAnsiNameToGuardianName,
  // CatMapGetCatalogVisibility, RTMD fetches, etc, please be sure to
  // call Statement::commitImplicitTransAndResetTmodes before
  // leaving this function.  So it is best not to code a "return" from
  // inside this while loop, but instead, set the retcode local
  // variable, and set the readyToReturnVariable to TRUE, then break
  // from the switch statement.

  NABoolean readyToReturn = FALSE;
  if (stmtStats_ != NULL) 
     masterStats = stmtStats_->getMasterStats();
  while (readyToReturn == FALSE)  
    {
#ifdef _DEBUG
      if (getenv("SHOW_STATE"))
	{
	  char buf[40];

	  switch (state_)
	    {
	    case INITIAL_STATE_: strcpy(buf, "INITIAL_STATE_"); break;
	    case DO_SIM_CHECK_: strcpy(buf, "DO_SIM_CHECK_"); break;
	    case CHECK_DYNAMIC_SETTINGS_: strcpy(buf, "CHECK_DYNAMIC_SETTINGS_"); break;
	    case FIXUP_: strcpy(buf, "FIXUP_"); break;
	    case FIXUP_DONE_: strcpy(buf, "FIXUP_DONE_"); break;
	    case EXECUTE_: strcpy(buf, "EXECUTE_"); break;
	    case ERROR_: strcpy(buf, "ERROR_"); break;
	    case ERROR_RETURN_: strcpy(buf, "ERROR_RETURN_"); break;
	    default: strcpy(buf, "Unknown state!"); break;
	    }
	  cout << "State " << buf << endl;
	}
#endif

      switch (state_)
	{
	case INITIAL_STATE_:
	  {
            // Reclaim Statements if it is available only when the 
            // parent statements are executed
            if (context_->getNumOfCliCalls() == 1)
            {
              // Reclaim Statements if it is available
              context_->reclaimStatements();
            }
            if (masterStats != NULL)
            {
              Int64 jts = NA_JulianTimestamp();
	      if (NOT masterStats->isPrepAndExec() && (!fixupOnly))
	      {
	        masterStats->setElapsedStartTime(jts);
	      }
              if (! stmtStats_->aqrInProgress())
                aqrInitialExeStartTime_ = -1;
              if (! fixupOnly)
                 masterStats->setExeStartTime(aqrInitialExeStartTime_ == -1 ? 
                    jts : aqrInitialExeStartTime_);
	      masterStats->initBeforeExecute(jts);
              if (! stmtStats_->aqrInProgress())
                masterStats->resetAqrInfo();
	      }

	    if (stmt_state != CLOSE_)
	      {
		// Report an error because we are trying to execute a
		// statement which is already in an open state, or one
		// that was never prepared. One exception is a stored
		// procedure result set in the INITIAL_ state. It can
		// be described and executed without the application
		// first having done a prepare.
                if (!(parentCall_ && stmt_state == INITIAL_))
                {
		//ADebug();
		diagsArea << DgSqlCode(- CLI_STMT_NOT_CLOSE);
		state_ = ERROR_;
		statementGlobals_->setCancelState(CLI_CANCEL_TCB_READY);
		break;
	      }
              }

	    if (aqrReprepareNeeded())
	      {
		diagsArea << DgSqlCode(-EXE_USER_PREPARE_NEEDED);
		state_ = ERROR_;
		break;
	      }

	    if (!root_tdb &&
		!allocated() &&
		(statement_id->name_mode == cursor_name) &&
		(statement_id->identifier) &&
		(!isEqualByName((SQLSTMT_ID *)statement_id, cursor_name_))
		)
	      {
		SQLSTMT_ID tmpStmtId = *(SQLSTMT_ID *)statement_id;
		tmpStmtId.name_mode = stmt_name;
		Statement * bindToStmt =
		  context_->getStatement(&tmpStmtId);
		if (!bindToStmt)
		  {
		    diagsArea << DgSqlCode(-CLI_STMT_NOT_EXISTS);
		    state_ = ERROR_;
		    break;
		  }
		bindTo(bindToStmt);
	      }

            // Two cases to consider for CALL statements
            // a) This is a CALL statement. We need to reset the state
            //    of all child result sets before doing this execute. 
            //    The state should have already been reset when the
            //    CALL was closed but we do it again to be safe.
            // b) This is a stored procedure result set. We may need to
            //    to trigger an internal prepare before doing this
            //    execute. We also need to prevent a result set from
            //    being opened multiple times following a single 
            //    execution of the CALL.
            ExRsInfo *rsInfo = getResultSetInfo();
            if (rsInfo)
            {
              // Case a)
              rsInfo->reset();
            }
            if (parentCall_)
            {
              // Case b)
              ExRsInfo *parentRsInfo = parentCall_->getResultSetInfo();
              ex_assert(parentRsInfo, "No parent RS info available");

              ULng32 myIndex = parentRsInfo->getIndex(this);
              NABoolean openWasAttempted =
                parentRsInfo->openAttempted(myIndex);
              
              if (!openWasAttempted)
              {
                parentRsInfo->setOpenAttempted(myIndex);
              }
              else
              {
                diagsArea << DgSqlCode(-EXE_UDR_RS_REOPEN_NOT_ALLOWED)
                          << DgInt0((Lng32) myIndex);
                state_ = ERROR_;
                break;
              }
              
              RETCODE proxyRetcode = rsProxyPrepare(*parentRsInfo, myIndex,
                                                    diagsArea);
              if (proxyRetcode == ERROR)
              {
                state_ = ERROR_;
                break;
              }
            }
  
	    // Recompile if this stmt did not get compiled at 
	    // compilation time,
	    // or if the current transaction mode is different than the 
	    // mode specified at compile time.
	    if (! root_tdb)
	      {
		// A special case:
		// if DISPLAY query and no root_tdb, return. In this
		// case user does not want to execute the query.
		if (isDISPLAY()) 
		  {
			// change state so fetch can 'succeed' with an EOF.
			stmt_state = EOF_;
                        retcode = SUCCESS;
                        readyToReturn = TRUE;
                        break;
		  }

		// AQR has been enabled.
		if ((allocated()) &&
		    (context_->getSessionDefaults()->getAqrType() != 0))
		  {
		    // return error. AQR will handle recompile and retry.
		    diagsArea << DgSqlCode(-8583);
		    state_ = ERROR_;
		    break;
		  }

		state_ = ERROR_;
		break;
	      }
	    else if ((root_tdb->transactionReqd() || root_tdb->isLRUOperation())
		     &&
		     compareTransModes(root_tdb, context_->getTransaction(),
				       (root_tdb->aqrEnabled() ? &diagsArea : NULL))
		     &&
              !systemModuleStmt() )
	      {
		if (root_tdb->aqrEnabled())
		  {
		    // return error. AQR will handle recompile and retry.
		    state_ = ERROR_;
		  }
		else
		  {
                    state_ = ERROR_;
		  }
		break;
	      }

              if (root_tdb->inMemoryObjectDefn())
	      {
		// trying to executed a query which refers to an inMemory
		// object definition.
		// Return error.
                diagsArea << DgSqlCode(-CLI_CANNOT_EXECUTE_IN_MEM_DEFN);
                state_ = ERROR_;
                break;
	      }

            // if statistics were previously returned for this statement
            // (could happen for multiple executions of the same prepared
            //  or an embedded static statement), then re-initizalize the stat
            // area.	    
            ExStatisticsArea *statsArea = getStatsArea();
            if (statsArea != NULL)
            {
              StatsGlobals *statsGlobals = cliGlobals->getStatsGlobals();
              if (statsGlobals != NULL)
              {
                int error = statsGlobals->getStatsSemaphore(cliGlobals->getSemId(),
						      cliGlobals->myPin());
                statsArea->initEntries();
                statsArea->restoreDop();
                statsGlobals->releaseStatsSemaphore(cliGlobals->getSemId(),cliGlobals->myPin());
              }
              else
              {
                statsArea->initEntries();
                statsArea->restoreDop();
              }
            }
            if (stmtStats_ != NULL)
              stmtStats_->setAqrInProgress(FALSE);
            // LRU cannot run in a user transaction
            if (root_tdb && root_tdb->isLRUOperation() && context_->getTransaction()->xnInProgress())
	      {
                diagsArea << DgSqlCode(-EXE_CANT_BEGIN_USER_TRANS_WITH_LRU);
		retcode = ERROR;
	        state_ = ERROR_RETURN_;
                break;
	      }
	    
            // Start a transaction, if needed and one not already running.
	    //			if(!context_->getSuppressAutoXactStartFlag())
	    if ((NOT fixupOnly) ||
		(cliflags & PREPARE_STANDALONE_QUERY))
	      {
		if (beginTransaction(diagsArea))
		  {
		    retcode = ERROR;
		    state_ = ERROR_RETURN_;
		    break;
		  }
	      }

	    setTsMismatched(FALSE);
            state_ = DO_SIM_CHECK_;
	  }
	break;

        case DO_SIM_CHECK_:
          {
            if ((! root_tdb) || (! root_tdb->querySimilarityInfo()))
              {
                state_ = CHECK_DYNAMIC_SETTINGS_;
                break;
              }

            NABoolean simCheckFailed = FALSE;
            retcode =
              doQuerySimilarityCheck(root_tdb->querySimilarityInfo(),
                                     simCheckFailed, diagsArea);
            if (retcode == ERROR)
              {
                state_ = ERROR_;
                break;
              }
            
            state_ = CHECK_DYNAMIC_SETTINGS_;
          }
        break;

        case CHECK_DYNAMIC_SETTINGS_:
        {
          if (fixupState())
          {
            // If this fixed up statement was affected by SET TIMEOUT
            // or by a change in UDR runtime options then we want to
            // make sure it gets fixed up again
            if (statementGlobals_->timeoutSettingChanged() ||
                statementGlobals_->udrRuntimeOptionsChanged())
            {
              setFixupState(0);
            }
          }

          if (!fixupState())
            state_ = FIXUP_;
          else
            state_ = EXECUTE_;

        }
        break;
	
	case FIXUP_:
	  {
	    // We want to ignore any errors that occur as part of dealloc 
	    // when called from here.
            // So, we mark the DiagsArea before making the call to dealloc(),
	    // and then rewind
            // back to there afterwards.
            Lng32 oldDiagsAreaMark = diagsArea.mark();
            Lng32 oldGlobalDiagsAreaMark = 0;
            if (statementGlobals_->getDiagsArea())
	      {
		oldGlobalDiagsAreaMark = statementGlobals_->getDiagsArea()->mark();
	      }
            
            if (dealloc())
	      {
                //Leave the diagsArea as it is in case of error during the dealloc().
		state_ = ERROR_;
		break;
	      }
	    
            // Rewind to ignore all errors that occurred during a successful dealloc()
            if (statementGlobals_->getDiagsArea())
	      {
		statementGlobals_->getDiagsArea()->rewind(oldGlobalDiagsAreaMark, TRUE);
	      }
            diagsArea.rewind(oldDiagsAreaMark, TRUE);
	    space_.freeBlocks();
	    
	    statementGlobals_->reAllocate(1);
	    
	    setState(CLOSE_);
	    
	    setFixupState(0);

            StmtDebug1("[BEGIN fixup] %p", this);

	    NABoolean doSimCheck = FALSE;
	    retcode =
	      fixup(cliGlobals, input_desc, diagsArea, doSimCheck,
                      partitionUnavailable, donePrepare);


            StmtDebug2("[END fixup] %p, result is %s", this,
                       RetcodeToString(retcode));

	    if (((fixupOnly) ||
		 (root_tdb->aqrEnabled())) &&
		((retcode == ERROR) ||
		 (diagsArea.mainSQLCODE() < 0) ||
		 (doSimCheck)))
	      {
		state_ = ERROR_;
		break;
	      }

	    if ((retcode == ERROR) || 
                (partitionUnavailable && partitionAvailabilityChecked))
	      {
                state_ = ERROR_;
		break;
	      }

	    if (doSimCheck || partitionUnavailable)
            {
	      state_ = DO_SIM_CHECK_;
            }
	    else
            {
              state_ = EXECUTE_;

              if (fixupOnly)
		{		   		  
		  if  (NOT(cliflags & PREPARE_STANDALONE_QUERY))
		    {
		      // if an explicitly prepared query, commit any
		      // transaction that was started during fixup
		      // stage. We don't want to hold onto this Xn
		      // between this stmt's prepare and its execute.
		      // Later, when this query is executed, a
		      // transaction would be started.

                      // Wait for UDR transactional replies before
                      // attempting to commit
                      NABoolean allRequests = FALSE;
                      completeUdrRequests(allRequests);

		      // The following call will only reset autoCommit
		      // which is needed for the commitTransaction()
		      // to actually commit.
		      resetAutoCommit(); 

		      // now call commitTransaction since autoCommit has been 
		      // reset
		      if (commitTransaction(diagsArea))
			{
			  state_ = ERROR_;
			  retcode = ERROR;
			  readyToReturn = TRUE;
			  break;
			}
		      retcode = SUCCESS;
		      readyToReturn = TRUE;
		      state_ = FIXUP_DONE_;
		    
		    }
		  else
		    {
		      retcode = SUCCESS;
		      readyToReturn = TRUE;
		      state_ = INITIAL_STATE_;
		    }
                  
		} // if (fixupOnly && (state_ != ERROR_))
            } // if (doSimCheck || partitionUnavailable) else ...
            
            // Transition to the ERROR_ state if errors were recorded
            // in statement globals. Also set readyToReturn to FALSE
            // so we don't return out of this method before processing
            // the state transition.
            if (state_ != ERROR_)
            {
              ComDiagsArea *stmtGlobDiags = statementGlobals_->getDiagsArea();
              if (stmtGlobDiags && stmtGlobDiags->mainSQLCODE() < 0)
              {
                statementGlobals_->takeGlobalDiagsArea(diagsArea);
                state_ = ERROR_;
                readyToReturn = FALSE;
              }
            }
            
	  } // case FIXUP_
	break;
	
	case FIXUP_DONE_:
	  {
	    // Begin a transaction before going to EXECUTE_ state since
	    // the transaction may have been committed
	    if (beginTransaction(diagsArea))
	      {
		retcode = ERROR;
		state_ = ERROR_RETURN_;
		break;
	      }
	    if (masterStats != NULL)
	      {
	       Int64 jts = NA_JulianTimestamp();
                if (NOT masterStats->isPrepAndExec())
	        {
                  masterStats->setElapsedStartTime(jts);
                }
                masterStats->setExeStartTime(aqrInitialExeStartTime_ == -1
                     ? jts : aqrInitialExeStartTime_);
              }
	    state_ = EXECUTE_;
	  }
	  break;

	case EXECUTE_:
	  {
	    if (masterStats != NULL)
	      {
		masterStats->
		  setFixupEndTime(NA_JulianTimestamp());
                if (!masterStats->getValidDDL())
                  {
                    diagsArea << DgSqlCode(-CLI_DDL_REDEFINED);
                    state_ = ERROR_;
                    break;
                  }
                if (!masterStats->getValidPrivs())
                  {
                    diagsArea << DgSqlCode(-CLI_INVALID_QUERY_PRIVS);
                    state_ = ERROR_;
                    break;
                  }
              }
            // In case of master, the unused memory quota needs to be reset
            // with every statement execution. 
            statementGlobals_->resetMemoryQuota();
	    /* execute it */
            if( root_tdb )
            {            
                // check if we have triggers
                if (root_tdb->getTriggersCount() > 0)
                {
                  retcode =
                    getTriggersStatus(root_tdb->stoiStoiList(), diagsArea);
                  if (retcode == ERROR)
                  {
                    state_ = ERROR_;
                    break;                
                  }
                }

                // check for statements with uninitialized mvs          
                char * pMvName;
                if( doesUninitializedMvExist( &pMvName, diagsArea ) )
                {                                
                    diagsArea << DgSqlCode(- CLI_MV_EXECUTE_UNINITIALIZED)
                              << DgTableName( (const char *)pMvName);
                    state_ = ERROR_;
                    break;                
                }
            } 
          
            // in case this is a holdable cursor propagate flag to master executor
            // leaf nodes
            if (isPubsubHoldable() &&
		!root_tdb->isEmbeddedUpdateOrDelete() &&
		!root_tdb->isStreamScan())
	      {
                // Holdable cursors are only supported for streaming cursors
		// and destructive cursors because there are some strange
		// side-effects (locks disappear after commit) that we don't
		// want to inflict on non-Publich/Subscribe functionality at
		// this time. There are no source-code changes needed to allow
		// holdable cursors in these other cases though.
                diagsArea << DgSqlCode(-CLI_CURSOR_CANNOT_BE_HOLDABLE);
                state_ = ERROR_;
                break;
              }
            // BertBert ^^
           
	    ComDiagsArea* diagsPtr = NULL;
	    
	    // if this is an 'update where current of' query, and
	    // the cursor statement name was specified via a hvar,
	    // then find the cursor statement and hook it up here.
	    // In this case, fetched statement has to be searched
	    // before each execute because the hvar value may 
	    // change between calls to Exec.
	    // Also validate that the tablename specified in the upd/del
	    // stmt is the same as the one in the declare cursor stmt.
	    if (root_tdb->updateCurrentOfQuery())
	      {
		if (root_tdb->fetchedCursorName() == NULL) // spec via hvar
		  {
		    // find the hvar that contains the cursor name in the 
		    // input desc list
		    Lng32 cursor_name = 0;
		    input_desc->getDescItem(root_tdb->fetchedCursorHvar(),
					    SQLDESC_VAR_PTR, &cursor_name, 
					    0, 0, 0, 0);
                    char * cursor_name_copy = NULL;
		    if (cursor_name == 0)
		      {
			diagsArea << DgSqlCode(-CLI_TCB_EXECUTE_ERROR);
			state_ = ERROR_;
			break;
		      }
		    else
		      {
                        Lng32 string_length = 0;
                        input_desc->getDescItem(root_tdb->fetchedCursorHvar(),
						SQLDESC_LENGTH, &string_length,
						0, 0, 0, 0);
                        cursor_name_copy = 
                        Descriptor::getCharDataFromCharHostVar
                          (diagsArea,
			   heap_,
                           (char *)((long)cursor_name), 
                           string_length,
			   "CURSOR NAME", 
                           input_desc,
                           root_tdb->fetchedCursorHvar() - 1,  // Pass a zero-based index.
                           REC_BYTE_V_ANSI);
		      }
		    
		    currentOfCursorStatement_ =
		      getCurrentOfCursorStatement((char *)cursor_name_copy);
		    if (cursor_name_copy) heap_.deallocateMemory(cursor_name_copy);

		    if (currentOfCursorStatement_ == NULL)
		      {
			diagsArea << DgSqlCode(- CLI_NON_UPDATABLE_SELECT_CURSOR)
				  << DgString0((char *)((long)cursor_name));
			state_ = ERROR_;
			break;
		      }
		  }

		// make sure that the table name in the update/del stmt is the
		// same as the tablename specified in the cursor.
		ex_root_tdb *cursorTdb = currentOfCursorStatement_->getRootTdb();
		Int16 cursorTableNameLen = 
		  str_len( cursorTdb->getLateNameInfoList()->
						    getLateNameInfo(cursorTdb->baseTablenamePosition()).
						    lastUsedAnsiName());
		
		Int16 updelTableNameLen = 
		  str_len( root_tdb->getLateNameInfoList()->
			   getLateNameInfo(root_tdb->baseTablenamePosition()).
			   lastUsedAnsiName());
		if ( (cursorTableNameLen != updelTableNameLen ) || 

		     (str_cmp(root_tdb->getLateNameInfoList()->
			   getLateNameInfo(root_tdb->baseTablenamePosition()).
			   lastUsedAnsiName(), 
			   cursorTdb->getLateNameInfoList()->
			   getLateNameInfo(cursorTdb->baseTablenamePosition()).
                           lastUsedAnsiName(), 
			   updelTableNameLen
			   ) != 0) 
		    )
		  {
		    diagsArea << DgSqlCode(- CLI_NON_CURSOR_UPDEL_TABLE)
			      << DgString0(root_tdb->fetchedCursorName());
		    retcode = ERROR;
		    state_ = ERROR_RETURN_;
		    //                    readyToReturn = TRUE;
                    break;
		  }
	      }	   
 
	    // Get the row of primary key values from the referenced cursor and
	    // move it to my root tcb and ensure the update columns are valid.
	    if (root_tdb->updateCurrentOfQuery())
	      {
		if (currentOfCursorStatement_ == NULL)
		  {
		    diagsArea << DgSqlCode(- CLI_NON_UPDATABLE_SELECT_CURSOR);
		    state_ = ERROR_;
		    break;
		  }
		
		if (currentOfCursorStatement_->getState() != FETCH_)
		  {
		    // Must have fetched a row to do an update...current of.
		    // Add a better error message here. TBD.
		    diagsArea << DgSqlCode(- EXE_CURSOR_NOT_FETCHED);
		    state_ = ERROR_;
		    break;
		  }

		if (currentOfCursorStatement_->isDeletedCursor())
		  {
		    // Must have fetched a row to do an update...current of.
		    // Cannot update or delete a row that was previously
		    // deleted using this cursor.
		    diagsArea << DgSqlCode(- EXE_CURSOR_NOT_FETCHED);
		    state_ = ERROR_;
		    break;
		  }

		char * pkeyRow = 
		  currentOfCursorStatement_->getRootTcb()->getPkeyRow();
		if (pkeyRow == NULL)
		  {
		    // Add a better error message here. TBD.
		    diagsArea << DgSqlCode(- CLI_TCB_EXECUTE_ERROR);
		    state_ = ERROR_;
		    break;
		  }
		
		root_tcb->inputPkeyRow(pkeyRow);
		
		if (!currentOfCursorStatement_->root_tdb->isUpdateCol(root_tdb))
		  {
		    diagsArea << DgSqlCode(- CLI_INVALID_UPDATE_COLUMN);
		    state_ = ERROR_;
		    break;
		  }
	      }

	     // NOT_ATOMIC_FAILURE_LIMIT was specified through the statement attribute
	     // override any value we get from the CQD
	     if ((getNotAtomicFailureLimit() != 0) && 
	         (root_tdb->isNonFatalErrorTolerated())) {
	      root_tdb->setNotAtomicFailureLimit(getNotAtomicFailureLimit());
	     }
	    
	    // nothing happened yet.
            statementGlobals_->setGlobDiagsArea(0);
	    statementGlobals_->setRowsAffected(0);
	    diagsArea.setRowCount(0);
	    
            // Now that the statement is completely name-resolved, 
            // catalog-visiblity-checked, fixed up, compiled, recompiled, 
            // etc, etc, see if we started an implicit transaction to
            // perform any of these tasks and if so, commit it so that 
            // the statement can run without a trans (since if *we*
            // started the trans then this must be a READ UNCOMMITTED
            // statement.  Also, reset the autocommit setting if we 
            // had to temporarily turn it off.
            commitImplicitTransAndResetTmodes();

	    NABoolean parentIsCanceled = updateChildQid();
	    if (parentIsCanceled)
	    {
	      diagsArea << DgSqlCode(-EXE_CANCELED);
	      state_ = ERROR_;
	      break;
	    }

            if (masterStats != NULL)
              {
                masterStats->setIsBlocking();
                masterStats->setStmtState(STMT_EXECUTE_);
              }
            
            Int32 rc = root_tcb->execute(cliGlobals, statementGlobals_,
                                         input_desc, diagsPtr, reExecute);
            
            if (masterStats != NULL)
              masterStats->setNotBlocking();
            if (rc < 0)
              retcode = ERROR;
            // "diagsPtr" is modified by the foregoing call.
            // If "diagsPtr" is NULL, there are no diags to merge
            // into "diagsArea".  Otherwise, "diagsPtr" is not NULL and does
            // point to a diags area from which we: 1) avoid the SQL function
            // 2) copy the ComCondition objects over.  Then we decrement
            // the reference count to indicate we're done with that
            // ComDiagsArea.
	    
            if (diagsPtr)
              {
                diagsArea.mergeAfter(*diagsPtr);
                diagsPtr->decrRefCount();    
                diagsPtr = NULL;
              }
	    
            if (retcode == ERROR)
              {
                root_tcb->cancel(statementGlobals_,diagsPtr);
                state_ = ERROR_;
                break;
              }
            else
              {
                if (retcode == 0 && diagsArea.mainSQLCODE() > 0)
                  // It's a warning. So return 1. 
                  retcode = (RETCODE)1;
                setState(OPEN_);
                readyToReturn = TRUE;
                break;
              }
          }
        break;
          
	case RE_EXECUTE_:                
	  {
	    // if input descriptor was passed in at execute time, recreate 
	    // the input data
	    // Setting the boolean reExecute to true, will cause the
	    // inputData from the previous execution to be used since we
	    // have no input_desc anymore at this stage. 
	    if (inputData_)
	      heap_.deallocateMemory (inputData_) ;
	    inputData_ = NULL;
	    char * inputData;
	    root_tcb->getInputData(inputData, inputDatalen_);
	    if (inputData)
	      {
		inputData_ = (char*) heap_.allocateMemory (inputDatalen_) ;
		str_cpy_all(inputData_, inputData, (Lng32) inputDatalen_);
	      }
	    
	    setFixupState(0);
	    reExecute=TRUE;
            state_ = CHECK_DYNAMIC_SETTINGS_;
	  }
	break;

	case ERROR_:
	  {
	    retcode = error(diagsArea);
	    state_ = ERROR_RETURN_;
	  }
	break;
	
	case ERROR_RETURN_:
	  {
            readyToReturn = TRUE;
	  }
	break;
	
	default:
	  state_ = ERROR_;
	  break;

	} // switch
    } // while return 

  commitImplicitTransAndResetTmodes();

  StmtDebug2("[END execute] %p, result is %s", this,
             RetcodeToString(retcode));
  return retcode;

} // Statement::execute diags

RETCODE Statement::fetch(CliGlobals * cliGlobals, Descriptor * output_desc,
			 ComDiagsArea &diagsArea,
                         NABoolean newOperation)
{
  StmtDebug2("[BEGIN fetch] %p, stmt state %s", this, stmtState(getState()));

  Int32 timeout = 0;
  Int32 retcode = SUCCESS;
  if (stmt_state == CLOSE_)
    {
      // trying to fetch from a statement which is in CLOSE state
      diagsArea << DgSqlCode(- CLI_STMT_CLOSE);
      StmtDebug3("[END fetch] %p, result is %s, stmt state %s", this,
                 RetcodeToString(ERROR), stmtState(getState()));
      return ERROR;
    }

  if (stmt_state == EOF_) // already returned EOF once.
  {
    if (output_desc && output_desc->rowwiseRowsetEnabled())
      output_desc->setDescItem(0, SQLDESC_ROWSET_NUM_PROCESSED,
				       0, NULL);
    StmtDebug3("[END fetch] %p, result is %s, stmt state %s", this,
               RetcodeToString(SQL_EOF), stmtState(getState()));
    return SQL_EOF;
  }

  if (!root_tcb)
    {
    // trying to fetch from a statement with a null root_tcb;
    // probably, a bug elsewhere. For example, sqlc translates
    //   exec sql prepare S1 from :buf;
    // into
    //   if ((SQLCODE = SQL_EXEC_ClearDiagnostics(&__SQL_id0))  < 0
    //   ||(SQLCODE = SQL_EXEC_SetDescPointers
    //       (&__SQL_id1,1,1,&(buf[0]),NULL)) < 0
    //   ||(SQLCODE = SQL_EXEC_AllocStmt(&__SQL_id0,NULL)) < 0
    //   ||(SQLCODE = SQL_EXEC_Prepare(&__SQL_id0,&__SQL_id1)) < 0);
    // Note that Prepare() will be short-circuited if any of the preceding
    // CLI calls fail silently and the result can be a null root_tcb which
    // will crash arkcmp unless we bulletproof against FETCH S1!
    diagsArea << DgSqlCode(- CLI_INTERR_NULL_TCB);
    StmtDebug3("[END fetch] %p, result is %s, stmt state %s", this,
               RetcodeToString(ERROR), stmtState(getState()));
    return ERROR;
  }
 
  if (newOperation)
  {
    if ((isAnsiHoldable() || isPubsubHoldable()) && transactionReqd())
    {
      if (! context_->getTransaction()->xnInProgress())
      {
        if (beginTransaction(diagsArea))
          return ERROR;
      }
    }
  }
  else
  {
    if ((isAnsiHoldable() || isPubsubHoldable()) && transactionReqd())
    {
      if (! context_->getTransaction()->xnInProgress())
      {
        ex_assert(0, "Transaction is Not Valid");
      }
    }
  }
  timeout = -1 ;

  // Check for suspended query.  The other check called in the 
  // Scheduler::work.  We do it here simply because some users
  // expect if the query is suspended while the client is not 
  // blocked in SQL, the next fetch should not return any row.
  // Without this check, a row could be returned if it was ready,
  // since it would not be needed to call the Scheduler::work(). 
  statementGlobals_->getScheduler()->checkSuspendAndLimit();

  /*fetch row*/
  ComDiagsArea* diagsPtr = NULL;
  NABoolean closeCursorOnError = TRUE;
  ExMasterStats *masterStats =
    (stmtStats_ ? stmtStats_->getMasterStats() : NULL);
  if (masterStats)
    masterStats->setIsBlocking();
  if (output_desc && output_desc->rowwiseRowsetEnabled())
    {
      NABoolean eodSeen=FALSE;
      retcode = root_tcb->fetchMultiple(cliGlobals, statementGlobals_, 
					output_desc,
					diagsPtr, timeout, newOperation,
					closeCursorOnError,eodSeen);
      if ((retcode >0) && (eodSeen))
	{
	  // If a warning is returned along with EOD,we have to return the 
	  // warning retcode to MXCS otherwise they will not retrieve the diags
	  // But remember that eod was returned so we don't go through fetch 
	  // again when we are redriven
	  setState(EOF_);
	}
 StmtDebug1("  root_tcb->fetchMultiple() returned %s",
            RetcodeToString((RETCODE) retcode));

    }
  else
    {
      retcode = root_tcb->fetch(cliGlobals, statementGlobals_, output_desc,
				diagsPtr, timeout, newOperation,
				closeCursorOnError);
      if (output_desc && output_desc->rowwiseRowset())
	{
	  if ((retcode >= 0) &&
	      (retcode != 100))
	    {
	      output_desc->setDescItem(0, SQLDESC_ROWSET_NUM_PROCESSED,
				       1, NULL);
	    }
	  else
	    {
	      output_desc->setDescItem(0, SQLDESC_ROWSET_NUM_PROCESSED,
				       0, NULL);
	    }
	}

      StmtDebug1("  root_tcb->fetch() returned %s",
           RetcodeToString((RETCODE) retcode));

    }

  if (masterStats)
    masterStats->setNotBlocking();

  // "diagsPtr" is modified by the foregoing call.
  // If "diagsPtr" is NULL, there are no diags to merge
  // into "diagsArea".  Otherwise, "diagsPtr" is not NULL and does
  // point to a diags area from which we: 1) avoid the SQL function
  // 2) copy the ComCondition objects over.  Then we decrement
  // the reference count to indicate we're done with that ComDiagsArea.

  if (diagsPtr)
    {
      /*      if (diagsPtr->getNumber(DgSqlCode::WARNING_) > 0 &&
          diagsPtr->getNumber(DgSqlCode::ERROR_) == 0 &&
          retcode == ERROR &&
          diagsPtr->mainSQLCODE() >= 20000 &&
          diagsPtr->mainSQLCODE() <= 20999)
      {
        // Don't know why root_tcb->fetch returns retcode -1 (ERROR)
        // when the SQL/MX Utility internal stored procedure issues
        // warning messages but executes successfully otherwise
        // (i.e., error messages was issued).  Need to set retcode
        // to SQL_EOF so this routine does not issue the unwanted 
        // CLI_TCB_FETCH_ERROR message.  Cannot set retcode to either
        // SUCCESS or WARNING because mxci will issue the following
        // rows right after the warning messages if retcode is set
        // to SUCCESS or WARNING:
        //
        // RECOVERSTATUS
        // -------------
        //
        //     134936872
        //
        // If retcode is set to SQL_EOF, only the warning messages
        // will be printed by mxci.  Note that error/warning numbers
        // range between 20000 and 20999 are used by the MODIFY utility
        // and several other SQL/MX utilities (e.g., DUP, PURGEDATA).
        //
        retcode = SQL_EOF;
	}*/
      diagsArea.mergeAfter(*diagsPtr);
      diagsPtr->decrRefCount();    
      diagsPtr = NULL;
    }
  
  if (retcode < 0)
    {
      if (stmtStats_ != NULL && stmtStats_->getMasterStats() != NULL)
      {
        stmtStats_->getMasterStats()->setRowsAffected(statementGlobals_->getRowsAffected());
      }
      updateStatsAreaInContext();

      // Error case.
      
      // cancel the down request to my child.
      // Do it only if closeCursorOnError is set to TRUE, the cursor
      // remains open otherwise.

      if (closeCursorOnError)
	{
	  // We must do this to clean up the messages from the queues
	  // (Else there are messages left over and these are incorrectly
	  // read if the statement is re-executed.)
	  diagsPtr = NULL;
          if (root_tcb)
            // We could have deallocated the root tcb earlier
            retcode = root_tcb->cancel(statementGlobals_,diagsPtr);
            StmtDebug1("  root_tcb->cancel() returned %s",
                       RetcodeToString((RETCODE) retcode));

	  if (diagsPtr)
	    {
	      diagsArea.mergeAfter(*diagsPtr);
	      diagsPtr->decrRefCount();    
              diagsPtr = NULL;
	    }

          setState(CLOSE_);
	}

      // rollback savepoints, if they are being done.
      NABoolean doXnRollback = FALSE;
      rollbackSavepoint(diagsArea, doXnRollback);
      
      // abort the transaction, if auto commit is on or
      // rollbackTransaction flag is set in the diags area or
      // this is a query that would have dirtied the disk(like,
      // insert/update/delete). 
      if (rollbackTransaction(diagsArea, doXnRollback))
      {
        StmtDebug3("[END fetch] %p, result is %s, stmt state %s", this,
                   RetcodeToString(ERROR), stmtState(getState()));
        return ERROR;
      }

      // If fatal error, we need to start over again
      if (root_tcb && root_tcb->fatalErrorOccurred())
      {
        dealloc();
        space_.freeBlocks();
        statementGlobals_->reAllocate(1);
        setFixupState(0);
      }
      
      if (diagsArea.getNumber(DgSqlCode::ERROR_) == 0)
	{
	  // add an error indicating no error in diags. 
	  // We will aqr retry on this error.
	  diagsArea << DgSqlCode(-CLI_NO_ERROR_IN_DIAGS);
	}

      StmtDebug3("[END fetch] %p, result is %s, stmt state %s", this,
                 RetcodeToString(ERROR), stmtState(getState()));
      return ERROR;
    }

  if ( !newOperation 
       )
    {
      if (handleUpdDelCurrentOf(diagsArea) == SQL_EOF)
	  retcode = SQL_EOF;
    }

  if ((retcode != NOT_FINISHED) && (retcode != SQL_EOF) && 
      (getRootTdb()->isEmbeddedIUDWithLast1()))
      {
      	// Add the affected row count that was directly placed into
	// the master globals to those that are already in the diags
	// area.
	diagsArea.setRowCount(statementGlobals_->getRowsAffected());
      }

  if (retcode == WARNING)
    {
    StmtDebug3("[END fetch] %p, result is %s, stmt state %s", this,
		 RetcodeToString(WARNING), stmtState(getState()));
    return WARNING;
  }
  else if (retcode == SQL_EOF)
  {
    StmtDebug1("  [EOF] Fetched SQL_EOF for statement %p", this);
    
    if (!(getRootTdb()->isEmbeddedIUDWithLast1()))
      {
	// Add the affected row count that was directly placed into
	// the master globals to those that are already in the diags
	// area. Make both row counts (diags and statementGlobals_) the same.
	diagsArea.addRowCount(statementGlobals_->getRowsAffected());
	statementGlobals_->setRowsAffected(diagsArea.getRowCount());
      }
    if (stmtStats_ != NULL && stmtStats_->getMasterStats() != NULL)
    {
      stmtStats_->getMasterStats()->setRowsAffected(statementGlobals_->getRowsAffected());
    }
    updateStatsAreaInContext();
    
    setState(FETCH_);
    
    // If this is a stored procedure result set, do bookkeeping for
    // this EOF and if this is EOF for the final result set, then put
    // the parent CALL in an EOF state (which has the side effect of
    // ending an AUTOCOMMIT transaction that may be associated with
    // the CALL).
    if (parentCall_)
    {
      StmtDebug1("  [EOF] Parent CALL %p", parentCall_);

      ExRsInfo *parentRsInfo = parentCall_->getResultSetInfo();
      ex_assert(parentRsInfo, "No parent RS info available");
      
      ULng32 rsIndex = parentRsInfo->getIndex(this);
      parentRsInfo->setCloseAttempted(rsIndex);
      StmtDebug2("  [EOF] RS index %u, Num closed since CALL %u",
                 rsIndex, parentRsInfo->getNumClosedSinceLastCall());

      if (parentRsInfo->allResultsAreClosed())
      {
        RETCODE closeResult = parentCall_->close(diagsArea);
        StmtDebug1("  [EOF] parentCall_->close() returned %s",
                   RetcodeToString(closeResult));
        if (closeResult != ERROR)
        {
          parentCall_->setState(EOF_);
        }
        else
        {
          StmtDebug3("[END fetch] %p, result is %s, stmt state %s", this,
			     RetcodeToString(ERROR), stmtState(getState()));
          return ERROR;
        }
      }
    }
    
    StmtDebug0("  [EOF] About to call commitTransaction()...");
    
    // end the transaction, if auto commit is on.
    if (commitTransaction(diagsArea))
    {
      StmtDebug3("[END fetch] %p, result is %s, stmt state %s", this,
		     RetcodeToString(ERROR), stmtState(getState()));
      // In case there is a commit conflict, we need to reset the rowcount 
      // since none of the rows would have got committed. 
      diagsArea.setRowCount(0);
      stmtStats_->getMasterStats()->setRowsAffected(0);
      return ERROR;
    }

    StmtDebug0("  [EOF] Done. commitTransaction() was successful");

    setState(EOF_);
    
    if (output_desc)
    {
      // move EOF condition to diags area.
      diagsArea << DgSqlCode(SQL_EOF);
    }
    
    StmtDebug3("[END fetch] %p, result is %s, stmt state %s", this,
		 RetcodeToString(SQL_EOF), stmtState(getState()));
    return SQL_EOF;
  }

 
  else
    {
      setState(FETCH_);

      if (getRootTdb()->updatableSelect())
	resetDeletedCursor();

    StmtDebug3("[END fetch] %p, result is %s, stmt state %s", this,
		 RetcodeToString(SUCCESS), stmtState(getState()));
    return SUCCESS;
  }

} // Statement::fetch()

short Statement::handleUpdDelCurrentOf(ComDiagsArea &diags)
{
  short retcode = SUCCESS;

  // if this is an update, delete, or insert query and no rows were
  // affected and there are no warnings, return SQL_EOF. 
  // If there is a warning, return the warning.
  // This is an ANSI requirement.
  if (noRowsAffected(diags))
    {
      // if this is an "update/delete where current of" operator
      // and no rows were returned,
      // raise a warning. This is done since an absence of this
      // row at this point indicates that someone deleted this
      // row between the time it was fetched (using the
      // FETCH <cursor> INTO...  statement) and now.
      if ((isDeleteCurrentOf()) || (isUpdateCurrentOf()))
	{
	  diags << DgSqlCode(EXE_CURSOR_UPDATE_CONFLICT);
	}
	  
      retcode = ((diags.getNumber(DgSqlCode::WARNING_) > 0) ? 0 : SQL_EOF);
      // move EOF warning to diags area.
      if (retcode == SQL_EOF)
	diags << DgSqlCode(SQL_EOF);

    }
  else
    {
      // if delete where current of, mark the cursor that this fetched
      // row was deleted. This is to prevent another cursor delete/update
      // (ANSI positioned delete/update) on this deleted row.
      if (isDeleteCurrentOf())
	{
	  currentOfCursorStatement()->setDeletedCursor();
	}
    }
  return retcode;
}
  
void Statement::updateTModeValues()
{
  // Get the current transmode and update the values
  // for transaction typing.
  TransMode * cmpTransMode = root_tdb->getTransMode();
  TransMode * runTransMode = context_->getTransaction()->getTransMode();

  // In the unlikely event that we don't have a runtime transMode
  // just use the compiletimeTransMode.
  if (!runTransMode)
    runTransMode = cmpTransMode ;

  short roval = runTransMode->getAccessMode();
  short rbval = runTransMode->getRollbackMode();
  Lng32  aival = runTransMode->getAutoAbortIntervalInSeconds();

  // if AccessMode is not set at runtime then the the compile time 
  // setting is applied. Note that roval has an effect on the
  // transaction only if its value is READ_ONLY or READ_ONLY_SPECIFIED_BY_USER
  if ((roval != TransMode::READ_ONLY_) &&
      (roval != TransMode::READ_ONLY_SPECIFIED_BY_USER_))
	roval = cmpTransMode->getAccessMode();

  //if No rollback is specified through an IUD statement then it gets precedence
  // in compareTransMode we check that autocommit is on at runtime for this setting
  if (cmpTransMode->getRollbackMode() == TransMode::NO_ROLLBACK_IN_IUD_STATEMENT_)
    rbval = TransMode::NO_ROLLBACK_ ;

  // if AutoAbortInterval is not set at runtime then the the compile time 
  // setting is applied.
  if (aival == -1)
    aival = cmpTransMode->getAutoAbortIntervalInSeconds();
        
  context_->getTransaction()->updateROVal(roval);
  context_->getTransaction()->updateRBVal(rbval);
  context_->getTransaction()->updateAIVal(aival);

}


RETCODE Statement::doOltExecute(CliGlobals *cliGlobals,
				Descriptor * input_desc, 
				Descriptor * output_desc,
				ComDiagsArea &diagsArea,
				NABoolean &doNormalExecute,
				NABoolean &reExecute)
{
  Int32 retcode;

  if (!root_tdb)
    {
      diagsArea << DgSqlCode(-CLI_STMT_NOT_EXISTS);
      return error(diagsArea);
    }

  if (stmt_state != CLOSE_)
    {
      // trying to execute a statement which is already in open
      // state
      diagsArea << DgSqlCode(- CLI_STMT_NOT_CLOSE);
      return ERROR;
    }
  
  ExMasterStats * masterStats = NULL;
  if (root_tdb && getStmtStats() && 
      (NULL != (masterStats = getStmtStats()->getMasterStats())))
    {
      if (!masterStats->getValidDDL())
        {
          diagsArea << DgSqlCode(-CLI_DDL_REDEFINED);
          return ERROR;
        }
      if (!masterStats->getValidPrivs())
        {
          diagsArea << DgSqlCode(-CLI_INVALID_QUERY_PRIVS);
          return ERROR;
        }
      if (root_tdb->qCacheInfoIsClass() && root_tdb->qcInfo())
        masterStats->setCompilerCacheHit(
                            root_tdb->qcInfo()->cacheWasHit());
     Int64 jts = NA_JulianTimestamp();
     if (NOT masterStats->isPrepAndExec())
	 masterStats-> setElapsedStartTime(jts);
     masterStats->setFixupStartTime(-1);
     masterStats->setFreeupStartTime(-1);
     masterStats->setExeStartTime(aqrInitialExeStartTime_ == -1 ? jts :
                               aqrInitialExeStartTime_);
     masterStats->setSqlErrorCode(0); 
     masterStats->setStmtState(STMT_EXECUTE_);
   }

  // Get the current transmode and update the values
  // for transaction typing.  Code is here so values
  // will be updated for BEGIN WORK statements.
  updateTModeValues();

  // Start a transaction, if needed and one not already running.
  if (root_tdb->transactionReqd())
    {
      // A user started transaction must be present for olt execution.
      // if no user started transaction, then return and do normal
      // execution.
      if ((! context_->getTransaction()->xnInProgress()) ||
	  ((context_->getTransaction()->exeStartedXn()) &&
	   (context_->getTransaction()->implicitXn())))
	{
	  doNormalExecute = TRUE;
	  reExecute = FALSE;
	  return SUCCESS;
	}
      else
	{
          if (compareTransModes(root_tdb, context_->getTransaction(),
				(root_tdb->aqrEnabled() ? &diagsArea : NULL))
              && !systemModuleStmt() )
            {
              if (root_tdb->aqrEnabled())
                {
                  // return error. AQR will handle recompile and retry.
                  return(ERROR);
                }
              else
                {
                  doNormalExecute = TRUE;
                  reExecute = FALSE;
                  return SUCCESS;
                }
            }
          
          // move the transid from executor globals to statement globals,
	  // if a transaction is running.
	  statementGlobals_->getTransid() =
	    context_->getTransaction()->getExeXnId();

	  if (root_tdb->getUpdSavepointOnError())
	    {
	      // get a savepoint id which will be sent to DP2.
	      context_->getTransaction()->generateSavepointId();
	      
	      statementGlobals_->getSavepointId() =
		context_->getTransaction()->getSavepointId();
	    }
	}
    }
  
  ExStatisticsArea *statsArea = getStatsArea();
  if (statsArea != NULL)
    {
      StatsGlobals *statsGlobals = cliGlobals->getStatsGlobals();
      if (statsGlobals != NULL)
      {
        int error = statsGlobals->getStatsSemaphore(cliGlobals->getSemId(),
					      cliGlobals->myPin());
        statsArea->initEntries();
        statsArea->restoreDop();
        statsGlobals->releaseStatsSemaphore(cliGlobals->getSemId(),cliGlobals->myPin());
      }
      else
      {
        statsArea->initEntries();
        statsArea->restoreDop();
      }
   }

  // do similarity check 
  if (root_tdb && root_tdb->querySimilarityInfo())
    {
      NABoolean simCheckFailed = FALSE;
      retcode =
        doQuerySimilarityCheck(root_tdb->querySimilarityInfo(),
                               simCheckFailed, diagsArea);
      
      if (retcode == ERROR)
        {
          return ERROR;
        }
    }

  ComDiagsArea* diagsPtr = NULL;
  if (! fixupState()) // first time
    {
     if ((stmtStats_) && (stmtStats_->getMasterStats()))
      {
	stmtStats_->getMasterStats()->
	  setFixupStartTime(NA_JulianTimestamp());
      }
      if (dealloc())
        goto retError;
      
      space_.freeBlocks();
      
      statementGlobals_->reAllocate(1);
      
      setState(CLOSE_);
      
      setFixupState(0);

      NABoolean doSimCheck = FALSE;
      NABoolean partitionUnavailable = FALSE;
      retcode = fixup(cliGlobals, input_desc, diagsArea, doSimCheck, partitionUnavailable, FALSE);
      if (doSimCheck || partitionUnavailable)
	{
	  commitImplicitTransAndResetTmodes();
 
          // Redrive the execution if fixup said so.
          // It is OK to clear the diags area, because
          // normal execution will perform the visibility check again.
          diagsArea.clear();

	  setTsMismatched(FALSE);

	  doNormalExecute = TRUE;
	  reExecute = FALSE;
	  return SUCCESS;
	}
      if ((stmtStats_) && (stmtStats_->getMasterStats()))
      {
	stmtStats_->getMasterStats()->
	  setFixupEndTime(NA_JulianTimestamp());
      }

      commitImplicitTransAndResetTmodes();
      if (retcode == ERROR)
        goto retError;
     
    }

  /* execute it */

  // nothing happened yet.
  statementGlobals_->setGlobDiagsArea(0);
  statementGlobals_->setRowsAffected(0);
  setState(OPEN_);
  updateChildQid();
  if (masterStats)
     masterStats->setIsBlocking();
  retcode = root_tcb->oltExecute(statementGlobals_, input_desc, 
				 output_desc, diagsPtr);
  StmtDebug1("  root_tcb->oltExecute() returned %s",
             RetcodeToString((RETCODE) retcode));

  if (masterStats)
     masterStats->setNotBlocking(); 
  if (diagsPtr)
    {      
      NABoolean lostOpen = diagsPtr->contains(-EXE_LOST_OPEN);

      if (lostOpen)
        {
          NABoolean retryableStatement = root_tdb->retryableStmt();
          
          if (retryableStatement)
            {
	      retcode = root_tcb->cancel(statementGlobals_,diagsPtr);
	      StmtDebug1("  root_tcb->cancel() returned %s",
			 RetcodeToString((RETCODE) retcode));
	      
              setState(CLOSE_);
	      doNormalExecute = TRUE;
	      reExecute = TRUE;
	      return SUCCESS;
            }
          else
            {
              // lost the open on a non-retryable statement;
              // force a fresh fix-up on next execution.
              setFixupState(0);
            }
	}
      
      diagsArea.mergeAfter(*diagsPtr);
      diagsPtr->decrRefCount();    
      diagsPtr = NULL;
    }

  if (retcode >= 0 && root_tcb->anyCbMessages())
  {
    Int32 cancelRetcode = root_tcb->cancel(statementGlobals_,diagsPtr);
    StmtDebug1("  root_tcb->cancel() returned %s",
             RetcodeToString((RETCODE) cancelRetcode));

    setState(CLOSE_);
    releaseTransaction(TRUE);
  }

  updateStatsAreaInContext();
  if (retcode < 0)
    {
      // rollback savepoints, if they are being done.
      NABoolean doXnRollback = FALSE;
      rollbackSavepoint(diagsArea, doXnRollback);

      retcode = root_tcb->cancel(statementGlobals_,diagsPtr);
      StmtDebug1("  root_tcb->cancel() returned %s",
                 RetcodeToString((RETCODE) retcode));

      setState(CLOSE_);

      // abort the transaction, if auto commit is on or
      // rollbackTransaction flag is set in the diags area or
      // this is a query that would have dirtied the disk(like,
      // insert/update/delete). 
      if (rollbackTransaction(diagsArea, doXnRollback))
	return ERROR;
 
      // if no other diags, as a last resort emit this rather 
      // cryptic message
      if (diagsArea.getNumber(DgSqlCode::ERROR_) == 0)
	diagsArea << DgSqlCode(- CLI_TCB_EXECUTE_ERROR);
      
      return ERROR;
      //      return error(diagsArea);
    }
  else if (retcode == SUCCESS)
    return SUCCESS;
  else if (retcode == WARNING)
    return WARNING; 
  else
    {
      diagsArea.setRowCount(statementGlobals_->getRowsAffected());
      if (getStmtStats() && (getStmtStats()->getMasterStats()))
          stmtStats_->getMasterStats()->setRowsAffected(statementGlobals_->getRowsAffected());
      if ((statementGlobals_->getRowsAffected() > 0) ||
	  (root_tdb->thereIsACompoundStatement()))
	return SUCCESS;
      else 
	{
	  if ((output_desc) ||
	      (root_tdb && (root_tdb->updDelInsertQuery())))
	    {
	      diagsArea << DgSqlCode(SQL_EOF);
	      return SQL_EOF;
	    }
	  else
	    return SUCCESS;
	}
    }
retError:
    return error(diagsArea);
}

Lng32 Statement::cancel()
{  
  StmtDebug2("[BEGIN cancel] %p, stmt state %s", this, stmtState(getState()));

  CancelState s = statementGlobals_->getCancelState();
  Lng32 retcode = 0;

  switch (s)
  {
  case CLI_CANCEL_TCB_INVALID:
    // 
    statementGlobals_->setCancelState(CLI_CANCEL_REQUESTED);
    break;

  case CLI_CANCEL_TCB_READY:
    // request to cancel down the tcb tree. 
    root_tcb->requestCancel();
    break;
  
  case CLI_CANCEL_DISABLE:
    retcode = -CLI_CANCEL_REJECTED;
    break;

  default:
    // CLI_CANCEL_REQUESTED
    // ignore since an outstanding cancel request exists.
    break;
  }

  StmtDebug3("[END cancel] %p, result is %s, stmt state %s",
             this, RetcodeToString((RETCODE) retcode), stmtState(getState()));
  return retcode;
}

void Statement::releaseStats()
{
  ExStatisticsArea *myStats = getStatsArea();
  ExStatisticsArea *myOrigStatsArea = getOrigStatsArea();
  ExStatisticsArea *ctxStats = context_->getStats();
  ExStatisticsArea *newStats;
  StatsGlobals *statsGlobals = cliGlobals_->getStatsGlobals();
  if (ctxStats && (ctxStats == myStats) && 
        ((Int32)myStats->getCollectStatsType() != SQLCLI_NO_STATS))
  {
    if (statsGlobals != NULL && stmtStats_ != NULL &&
        (Int32)myStats->getCollectStatsType() != SQLCLI_ALL_STATS) 
    {
      int error = statsGlobals->getStatsSemaphore(cliGlobals_->getSemId(),
                            cliGlobals_->myPin());
      // Make sure the ex_globals doesn't delete this stats area
      // in case of dynamic statements, since stmtStats is also
      // pointing to the same area
      getGlobals()->setStatsArea(NULL);
      // Context is pointing to it. Remove query shouldn't
      // deallocate it
      stmtStats_->setStmtStatsUsed(TRUE);
      context_->setStatsArea(myStats, FALSE, TRUE, FALSE);
      // Set the StmtStats that can be used to reset the used flag
      context_->setPrevStmtStats(stmtStats_);
      statsGlobals->releaseStatsSemaphore(cliGlobals_->getSemId(),
                                cliGlobals_->myPin());
    }
    else
    {
      // Resources for this statement are being deallocated. If the
      // context is pointing to my stats area, make a new copy of the
      // stats area and attach it to context.
      newStats = new (context_->exHeap())
      ExStatisticsArea(context_->exHeap(), 0,
                       myStats->getCollectStatsType());
      newStats->setStatsEnabled(myStats->statsEnabled());
      newStats->merge(myStats);
      if (newStats->getMasterStats() == NULL && stmtStats_ != NULL 
                   && stmtStats_->getMasterStats() != NULL)
      {
        ExMasterStats * ems = new(context_->exHeap())
              ExMasterStats(context_->exHeap());
        ems->copyContents(stmtStats_->getMasterStats());
        newStats->setMasterStats(ems);
      }
      if (stmtStats_ != NULL)
         stmtStats_->setStatsArea(NULL);
      // Attach the new stats area to the context
      context_->setStatsArea(newStats, TRUE, FALSE, TRUE);
    }
  }
  else
  if (myOrigStatsArea != NULL)
  {
    // Make sure the ex_globals doesn't delete this stats area
    // in case of dynamic statements, since stmtStats is also
    // pointing to the same area
    if (stmtStats_ != NULL && myOrigStatsArea != NULL &&
          (Int32)myOrigStatsArea->getCollectStatsType() != SQLCLI_ALL_STATS) 
       getGlobals()->setStatsArea(NULL);
  }
}

RETCODE Statement::releaseTcbs(NABoolean closeAllOpens)
{

  if (root_tcb)
  {
  releaseStats();
    // The root tcb takes care of deleting itself and of deleting
    // the statement globals.
    if (statementGlobals_)
    {
      ExRtFragTable *ft = statementGlobals_->getRtFragTable();
      
      // finish any transactional messages outstanding
      // for this statement, since the statement won't
      // be found anymore on the context's statement list
      // Should do this before releaseEsps, so that they 
      // will not be sending work or continue messages to 
      // each other after the deallocation of fragment 
      // instances has begun (see Soln 10-060504-6268).
      releaseTransaction(TRUE);

      // release all esps next
      releaseEsps(closeAllOpens);

      // Deallocate TCB trees for all stored procedure result set
      // children. The UDR leaf nodes in the result set TCB tree are
      // not valid once the UDR leaf node in this CALL statement
      // goes away, so those result set TCBs must be deallocated first.
      ExRsInfo *rsInfo = getResultSetInfo();
      if (rsInfo)
      {
        StmtDebug0("  About to call ExRsInfo::reset()");
        rsInfo->reset();
        
        ULng32 numChildren = rsInfo->getNumEntries();
        StmtDebug1("  Num RS children: %d", (Lng32) numChildren);
        
        for (ULng32 i = 1; i <= numChildren; i++)
        {
          Statement *rsChild = NULL;
          const char *proxySyntax = NULL;
          NABoolean open = FALSE;
          NABoolean closed = FALSE;
          NABoolean prepared = FALSE;
          
          NABoolean found = rsInfo->getRsInfo(i, rsChild, proxySyntax,
                                              open, closed, prepared); 
          
          if (found && rsChild)
          {
            StmtDebug1("  About to call dealloc() on RS %p", rsChild);
            rsChild->dealloc();
          }
          
        } // for each RS child
      } // if (rsInfo)

      // This call to deallocAndDelete() will trigger destructor calls
      // for all TCBs
      Int32 retcode = root_tcb->deallocAndDelete(statementGlobals_,ft);

      if (retcode < 0)
      {
        context_->diags() << DgSqlCode(- EXE_INTERNAL_ERROR);
        return ERROR;
      }
      
      root_tcb = NULL;
      
      //
      // Deallocating the TCB tree may have caused more messages
      // to be sent. To be safe, we once again wait for completion
      // of transactional messages.
      //
      releaseTransaction(TRUE);
      
    } // if (statementGlobals_)
    
  } // if (root_tcb)
  
  root_tcb = NULL;
  return SUCCESS;
}

RETCODE Statement::dealloc(NABoolean closeAllOpens)
{
  StmtDebug2("[BEGIN dealloc] %p, stmt state %s", this, stmtState(getState()));

  RETCODE result = SUCCESS;

  // stop the transaction, if once was started
  if ((context_->aqrInfo()->xnStartedAtPrepare()) &&
      (context_->getTransaction()->xnInProgress()) &&
      (context_->getTransaction()->exeStartedXn()) &&
      (context_->getTransaction()->autoCommit()) &&
      (autocommitXn()))
    {
      context_->aqrInfo()->setXnStartedAtPrepare(FALSE);
      
      if (commitTransaction(context_->diags()))
	{
	  // ignore error and proceed to deallocate
	}
    }
  
  context_->removeFromStatementWithEspsList(this);
  
  result = releaseTcbs(closeAllOpens);
  
  if (result == SUCCESS)
  {
    setState(CLOSE_);
    setFixupState(0);
    setComputeBulkMoveInfo(TRUE);
    
    // deallocate all cloned statements
    clonedStatements->position();
    Statement * clone = (Statement*)clonedStatements->getNext();
    for (; clone != NULL; clone = (Statement*)clonedStatements->getNext())
    {
      StmtDebug1("  About to call dealloc on clone %p", clone);
      clone->dealloc();
    }
    
    context_->removeFromCloseStatementList(this, FALSE);

    if (extractConsumerQueryTemplate_)
    {
      heap_.deallocateMemory(extractConsumerQueryTemplate_);
      extractConsumerQueryTemplate_ = NULL;
    }
  } // if (result == SUCCESS)

  StmtDebug2("[END dealloc] %p, stmt state %s", this, stmtState(getState()));
  return result;
}

static Lng32 getMaxParamIdx(ex_root_tdb *rootTdb){
  Lng32 maxParamIdx = 0;
  if(rootTdb->inputExpr()){
    maxParamIdx = rootTdb->inputExpr()->getMaxParamIdx();
  }
  
  if(rootTdb->outputExpr()){
    Lng32 outputParamIdx = rootTdb->outputExpr()->getMaxParamIdx();
    if(outputParamIdx > maxParamIdx)
      maxParamIdx = outputParamIdx;
  }
  return maxParamIdx;
}

RETCODE Statement::describe(Descriptor * desc, Lng32 what_desc,
			    ComDiagsArea &diagsArea)
{
  // One special case is for stored procedure result set proxy
  // statements. CLI callers do not prepare them. We do internal
  // prepares whenever the CLI caller describes or executes them.
  if (parentCall_)
  {
    ExRsInfo *rsInfo = parentCall_->getResultSetInfo();
    if (rsInfo)
    {
      ULng32 rsIndex = rsInfo->getIndex(this);
      RETCODE proxyRetcode = rsProxyPrepare(*rsInfo, rsIndex, diagsArea);
      if (proxyRetcode == ERROR)
        return ERROR;
    }
  }

  if (!root_tdb)
    return SUCCESS;

  InputOutputExpr *expr;
  enum ex_expr::exp_return_type expRType;

  Int32 retcode = 0; // be optimistic

  // A special case for DESCRIBE is when the SQL statement is a CALL
  // statement and the CLI caller wants to use a "wide" descriptor for
  // the CALL.
  if (root_tdb->hasCallStmtExpressions() && desc->isDescTypeWide())
  {
    // First populate the caller's descriptor with information from
    // the INPUT expression, the overlay information from the OUTPUT
    // expression into the same descriptor.

    Lng32 eNumEntries = getMaxParamIdx(root_tdb);
    if (desc->getMaxEntryCount() < eNumEntries){
      diagsArea << DgSqlCode(CLI_TDB_DESCRIBE_ERROR);
      return ERROR;
    }
    else if (desc->getUsedEntryCount() < eNumEntries) {
      desc->dealloc();
      desc->alloc(eNumEntries);
    }

    // The code in expr->describe sets the entry count in case of a Call stmt
    // only if the new count is greater than the old count. This
    // causes the old count to be returned during describe, if the 
    // same descriptor was reused and the number of entries in the new
    // query is less than the old count. 
    // Setting the entry count to 0 before calling describe.
    desc->setUsedEntryCount(0);

    if (expr = root_tdb->inputExpr())
    {
      UInt32 flags = 0;
      expr->setIsODBC(flags, root_tdb->odbcQuery());
      expr->setInternalFormatIO(flags, 
				context_->getSessionDefaults()->
				getInternalFormatIO());
      expr->setIsRWRS(flags, (root_tdb->getRWRSInfo() != NULL));
      expr->setIsDBTR(flags,
		      context_->getSessionDefaults()->getDbtrProcess());

      expRType = expr->describeInput(desc, NULL, flags);
      if(expRType != ex_expr::EXPR_OK)
	retcode = -1;
    }
    
    if ((retcode == 0) && (expr = root_tdb->outputExpr()))
    {
      UInt32 flags = 0;
      expr->setIsODBC(flags, root_tdb->odbcQuery());
      expr->setInternalFormatIO(flags, 
				context_->getSessionDefaults()->
				getInternalFormatIO());
      expr->setIsDBTR(flags,
		      context_->getSessionDefaults()->getDbtrProcess());
      expRType = expr->describeOutput(desc, flags);
      if(expRType != ex_expr::EXPR_OK)
	retcode = -1;
    }
  }
  else{
    if (what_desc == SQLWHAT_INPUT_DESC)
      {
      /* describe input */
      // retcode = root_tdb->describe(desc, 0);
      expr = root_tdb->inputExpr();
      if (expr == NULL)
	{
	  // set the entry count to zero. Otherwise desc will contain the
	  // entry count of the last describe.
	  desc->setUsedEntryCount(0);
	  return SUCCESS;
	}

      if (desc->getMaxEntryCount() < expr->getNumEntries())
	{
	  desc->setMaxEntryCount(expr->getNumEntries());
	}

      if (desc->getUsedEntryCount() < expr->getNumEntries())
	{
	  desc->dealloc();
	  desc->alloc(expr->getNumEntries());
	}
      
      UInt32 flags = 0;
      expr->setIsODBC(flags, root_tdb->odbcQuery());
      expr->setInternalFormatIO(flags, 
				context_->getSessionDefaults()->
				getInternalFormatIO());
      expr->setIsRWRS(flags, (root_tdb->getRWRSInfo() != NULL));
      expr->setIsDBTR(flags,
		      context_->getSessionDefaults()->getDbtrProcess());
      if (expr->describeInput(desc, root_tdb->getRWRSInfo(), flags) 
	  != ex_expr::EXPR_OK)
	retcode = -1;
      }
    else
      {
	/* describe output */
	// retcode = root_tdb->describe(desc, -1);
	expr = root_tdb->outputExpr();
	if (expr == NULL)
	  {
	    // set the entry count to zero. Otherwise desc will contain the
	    // entry count of the last describe.
	    desc->setUsedEntryCount(0);
	    return SUCCESS;
	  }
	
	if (desc->getMaxEntryCount() < expr->getNumEntries())
	  {
	    desc->setMaxEntryCount(expr->getNumEntries());
	  }

	if (desc->getUsedEntryCount() < expr->getNumEntries())
	  {
	    desc->dealloc();
	    desc->alloc(expr->getNumEntries());
	  }
	
	UInt32 flags = 0;
	expr->setIsODBC(flags, root_tdb->odbcQuery());
	expr->setInternalFormatIO(flags, 
				  context_->getSessionDefaults()->
				  getInternalFormatIO());
	expr->setIsDBTR(flags,
			context_->getSessionDefaults()->getDbtrProcess());
	if (expr->describeOutput(desc, flags) != ex_expr::EXPR_OK)
	  retcode = -1;
      }
  }
  if (retcode)
  {
    diagsArea << DgSqlCode(- CLI_TDB_DESCRIBE_ERROR);
    return ERROR;
  }

  return SUCCESS;
}

void Statement::copyGenCode(char * gen_code, ULng32 gen_code_len,
			    NABoolean unpackTDBs)
{
  StmtDebug3("[BEGIN copyGenCode] this %p, gen_code %p, len %u",
             this, gen_code, gen_code_len);

  ex_assert(!isCloned(),
            "copyGenCode() should not be called on a cloned statement");

  // Release the TDB tree if one exists
  assignRootTdb(NULL);

  // do some basic sanity checking
  if ((gen_code == 0) || (gen_code_len <= 0))
  {
    //    gen_code = 0;
    //    gen_code_len = 0;
    return;
  }
  
  CollHeap * h = cliGlobals_->getArkcmp()->getHeap();
  char *newTdbTree = (char *) (new (h) char[gen_code_len]);
  str_cpy_all(newTdbTree, gen_code, (Lng32) gen_code_len);
  
  assignRootTdb((ex_root_tdb *) newTdbTree);
  root_tdb_size = (Lng32) gen_code_len;
  
  if (unpackTDBs)
  {
  // Set up the reallocator for use when object version migration occurs.
  //
  ComTdb dummyTdb;
  ex_root_tdb *newRoot = (ex_root_tdb *)
    root_tdb->driveUnpack((void *)root_tdb,&dummyTdb, unpackSpace_);

  assignRootTdb(newRoot);
  
  if (root_tdb == NULL)
  {
    // ERROR during unpacking. Most likely case is verison-unsupported.
    // How do I report an error here ???
    //
    // diagsArea << DgSqlCode(- CLI_STMT_NOT_PREPARED);
    // return ERROR;
    //
    // Alternative: add code to drive a recompilation. Invalidate the plan.
    //
  }

  if ((stmt_type == STATIC_STMT) && (root_tdb))
    setRecompWarn(root_tdb->recompWarn());
    
  } // if (unpackTDBs)
  
  StmtDebug1("[END copyGenCode] this %p", this);
}

void Statement::copyInSourceStr(char * in_source_str_, Lng32 src_len_in_octets,
			 Lng32 charset)
{
  charset_ = charset;
  NAHeap * heap = context_->exHeap();
  if (source_str)
    NADELETEBASIC(source_str, heap);

  // do some basic sanity checking
  if ((in_source_str_ == 0) || (src_len_in_octets <= 0))
  {
     source_str = 0;
     source_length = 0;
     return;
  }

  Int32 maxBytesPerChar = CharInfo::maxBytesPerChar((CharInfo::CharSet)charset);
  source_str = new (heap) char[src_len_in_octets+maxBytesPerChar];
  str_cpy_all(source_str, in_source_str_, src_len_in_octets);
  if (charset == SQLCHARSETCODE_UCS2)
    ((NAWchar*)source_str)[src_len_in_octets/maxBytesPerChar] = 0;
  else
    source_str[src_len_in_octets] = '\0';
  source_length = src_len_in_octets;
}

void Statement::copyOutSourceStr(char * out_source_str, 
				 Lng32 &out_src_len_in_octets) // INOUT
{
  // do some basic sanity checking
  if ((out_source_str == NULL) || (out_src_len_in_octets <= 0) ||
      (out_src_len_in_octets < source_length))
    {
      out_src_len_in_octets = 0;
      return;
    }

  Int32 maxBytesPerChar = CharInfo::maxBytesPerChar((CharInfo::CharSet)charset_);
  str_cpy_all(out_source_str, source_str, source_length);
  if (charset_ == SQLCHARSETCODE_UCS2)
    ((NAWchar*)out_source_str)[source_length/maxBytesPerChar] = 0;
  else
    out_source_str[source_length] = '\0';

  out_src_len_in_octets = source_length;
}

void Statement::copySchemaName(char * schemaName, Lng32 schemaNameLength)
{
  if (schemaName_)
    NADELETEBASIC(schemaName_, (&heap_));

  // do some basic sanity checking
  if ((schemaName == 0) || (schemaNameLength <= 0))
  {
     schemaName_ = 0;
     schemaNameLength_ = 0;
     return;
  }

  schemaName_ = new (&heap_) char[schemaNameLength + 1];
  str_cpy_all(schemaName_, schemaName, schemaNameLength);
  schemaName_[schemaNameLength] = '\0';
  schemaNameLength_ = schemaNameLength;
}

void Statement::copyRecompControlInfo(char * basePtr,
				      char * recompControlInfo, 
				      Lng32 recompControlInfoLength)
{
}


void Statement::setCursorName(const char * cn)
{
  // as a side effect of this method the statement is added
  // to the cursorList of the current context. If the cursorName
  // changes, the statement is removed from the cursorList and
  // then re-inserted with the new name. This is neccessary,
  // because the name is used for hashing into the cursorList.

  StmtDebug2("  Setting cursor name for statement %p to \"%s\"",
             this, (cn ? cn : "(NULL)"));

 ComDiagsArea &diags = context_->diags();

  Lng32 nameLength = 0;
  char *copy_of_cn;
 

  if (cursor_name_) {

// Need to use length in comparison when 
// the length argument is added for "cn".

    // if we are changing it to the same name, save some work...
    if (cn && !strcmp(cn, cursor_name_->identifier))
       return;
    context_->removeCursor(cursor_name_, statement_id->module);
    heap_.deallocateMemory(cursor_name_);
  }

  if (cn) {
    nameLength = str_len(cn);
    copy_of_cn = new (&heap_) char [nameLength+1];
    str_cpy_all(copy_of_cn,cn,nameLength);
    copy_of_cn[nameLength] = '\0';

    cursor_name_ =  (SQLSTMT_ID *)(heap_.allocateMemory(sizeof(SQLSTMT_ID)));
    init_SQLCLI_OBJ_ID(cursor_name_, SQLCLI_CURRENT_VERSION,
             cursor_name, 0, copy_of_cn, 0,
           SQLCHARSETSTRING_ISO88591, str_len(cn));

    StmtDebug1("  Adding statement %p to the cursor list", this);
    context_->addToCursorList(*this);
  }
  else
     cursor_name_ = 0;
}

short Statement::transactionReqd()
{
  return ((short) (root_tdb && root_tdb->transactionReqd()));
}

Int64 Statement::getRowsAffected()
{
  return statementGlobals_->getRowsAffected();
}

//////////////////////
// PRIVATE methods
//////////////////////


// starts a transaction, if one has not already been started
// and if needed.
short Statement::beginTransaction(ComDiagsArea &diagsArea)
{

  // Get the current transmode and update the values
  // for transaction typing.  Code is here so values
  // will be updated for BEGIN WORK statements.
  updateTModeValues();

  // implicit xns for ddl stmts will be started and committed/aborted
  // in arkcmp if auto commit is on. Otherwise, it will be started here.
  if ((root_tdb->transactionReqd()) &&
      ((NOT root_tdb->ddlQuery()) ||
       (NOT context_->getTransaction()->autoCommit())))
    {
      // the trans mode at compile time of this query must be the
      // same as the transaction mode at execution time.
      if (!systemModuleStmt() && 
            compareTransModes(
	    root_tdb,
	    context_->getTransaction(),
	    &diagsArea, systemModuleStmt()))
	return ERROR;
      if (context_->getTransaction()->userEndedExeXn())
      {
        if (!diagsArea.contains(-CLI_USER_ENDED_EXE_XN))
            diagsArea << DgSqlCode(- CLI_USER_ENDED_EXE_XN);
        return ERROR;
      }
      if (! context_->getTransaction()->xnInProgress())
        {
	  // if no auto begin, then do not start the transaction.
	  if (context_->getTransaction()->getTransMode()->getAutoBeginOff())
	    {
	      // return error. A transaction is needed, one is not
	      // running and autobegin has been disabled.
	      diagsArea << DgSqlCode(- CLI_AUTO_BEGIN_TRANSACTION_ERROR);
              return ERROR;
	    }

          StmtDebug1("  About to BEGIN TX for statement %p...", this);
	  
          // start a transaction since one is not already running.
          short taRetcode =
            context_->getTransaction()->beginTransaction();

          StmtDebug1("  Return code is %d", (Lng32) taRetcode);

          if (taRetcode != 0)
            {
	      diagsArea.mergeAfter(*context_->getTransaction()->getDiagsArea());
	      //          diagsArea << DgSqlCode(- CLI_BEGIN_TRANSACTION_ERROR);
              return ERROR;
            }

          context_->getTransaction()->implicitXn() = TRUE;

	  // this statement started a transaction in autocommit mode.
	  // It means that this xn will only be committed when this
	  // statement ends execution.
	  if (context_->getTransaction()->autoCommit())
          {
	    setAutocommitXn(TRUE);
            StmtDebug0("  AUTOCOMMIT transaction successfully started");
          }
	  else
          {
	    setAutocommitXn(FALSE);
            StmtDebug0("  Transaction successfully started");
          }

        } // if (! context_->getTransaction()->xnInProgress())

      // move the transid from executor globals to statement globals,
      // if a transaction is running.
      statementGlobals_->getTransid() =
        context_->getTransaction()->getExeXnId();
      
      StmtDebug2("  Statement %p now has trans ID %s", this,
                 TransIdToText(statementGlobals_->getTransid()));
	        
      // We might have suspended work on this or a previous transaction
      // during the last CLOSE operation.  Indicate to the root TCB that
      // we are willing to work on a transaction again and that it is
      // ok to send out transactional requests (to DP2 and to ESPs)
      if (statementGlobals_ && statementGlobals_->getRtFragTable())
        {
          statementGlobals_->getRtFragTable()->continueWithTransaction();
        }

      if (root_tdb->getUpdSavepointOnError())
	{
	  // get a savepoint id which will be sent to DP2.
	  context_->getTransaction()->generateSavepointId();

	  statementGlobals_->getSavepointId() =
	    context_->getTransaction()->getSavepointId();
	}
    } // if (root_tdb->transactionReqd())

    else
    {
      // Browse access cursors or the load phase of index will
      // have the transaction passed (to ESPs?) if one exists
      // in its statement globals
      if (context_->getTransaction()->xnInProgress())
        {
          statementGlobals_->getTransid() =
            context_->getTransaction()->getExeXnId();
        }
    }
    if (stmtStats_ && stmtStats_->getMasterStats() != NULL)
        stmtStats_->getMasterStats()->setTransId(statementGlobals_->getTransid());
  return 0;
}
  
// ends(commits) transaction, if one is running and auto commit is on.
short Statement::commitTransaction(ComDiagsArea &diagsArea)
{
  if (context_->getTransaction()->userEndedExeXn())
    {
      if (!diagsArea.contains(-CLI_USER_ENDED_EXE_XN))
         diagsArea << DgSqlCode(- CLI_USER_ENDED_EXE_XN);
      return ERROR;
    }

  if ((context_->getTransaction()->xnInProgress()) &&
      (context_->getTransaction()->exeStartedXn()) &&
      (context_->getTransaction()->autoCommit()) &&
      (autocommitXn()))
    {
      if (context_->aqrInfo())
	context_->aqrInfo()->setXnStartedAtPrepare(FALSE);

      // get current context and close all statements
      // started under the current transaction
      context_->closeAllCursors(ContextCli::CLOSE_ALL, ContextCli::CLOSE_CURR_XN);
      // Capture any errors that happened and return eg. transaction 
      // related errors that happen during 
      // Statement::close-> ExTransaction::commitTransaction that get called 
      // in ::closeAllCursors
      if (diagsArea.mainSQLCODE() <0)
        {
          return ERROR;
        }
      
      // if transaction is still active(it may have been committed at
      // close cursor time if auto commit is on), commit it.
      if (context_->getTransaction()->xnInProgress())
	{
	  StmtDebug2("  About to COMMIT, stmt %p, tx %s...", this,
		     TransIdToText(statementGlobals_->getTransid()));
	  // do waited commit for DDL queries
	  short taRetcode = context_->commitTransaction();
	  
          StmtDebug1("  Return code is %d", (Lng32) taRetcode);
      
	  setAutocommitXn(FALSE);

	  if (taRetcode != 0)
	    {
              // If there are diagnostics in the statement globals then add
              // them to the caller's diags area first. They may contain
              // information about something that went wrong before the
              // COMMIT was attempted. Then add information about the COMMIT
              // failure that just occurred.
              statementGlobals_->takeGlobalDiagsArea(diagsArea);
              diagsArea.mergeAfter(*context_->getTransaction()->getDiagsArea());
              return ERROR;
            }
          StmtDebug0("  COMMIT was successful");
        }
    }
  else
    {
      StmtDebug0("  No AUTOCOMMIT transaction for this stmt");
    }
  
  return 0;
}

short Statement::rollbackSavepoint(ComDiagsArea & diagsArea,
				   NABoolean &rollbackXn)
{
  rollbackXn = FALSE;
  
  NABoolean rollbackSP = FALSE;

  if (context_->getTransaction()->xnInProgress())
    {
      if ((context_->getTransaction()->exeStartedXn()) &&
	  (context_->getTransaction()->autoCommit()))
	{
	  rollbackSP = FALSE;
	}
      else if (diagsArea.getRollbackTransaction())
	rollbackSP = FALSE;
      else if (root_tdb && 
	       (root_tdb->transactionReqd() != 0))
	{
	  if (root_tdb->getUpdAbortOnError())
	    rollbackSP = FALSE;
	  else if (root_tdb->getUpdPartialOnError())
	    rollbackSP = FALSE;
	  else if (root_tdb->getUpdSavepointOnError())
	    rollbackSP = TRUE;
	  else if ((NOT root_tdb->getUpdErrorOnError()) &&
		   (NOT diagsArea.getNoRollbackTransaction()))
	    rollbackSP = FALSE;
	}
    }

  if (rollbackSP)
    {
      short retcode = root_tcb->rollbackSavepoint();
      if (retcode)
	{
	  diagsArea.mergeAfter(*statementGlobals_->getDiagsArea());
	  diagsArea << DgSqlCode(-CLI_SAVEPOINT_ROLLBACK_FAILED);
	  rollbackXn = TRUE;
	}
      else
	{
	  // do not abort this transaction.
	  rollbackXn = FALSE;
	  diagsArea << DgSqlCode(CLI_SAVEPOINT_ROLLBACK_DONE);
	  // clr count of affected rows, CLI_SAVEPOINT_ROLLBACK_DONE.
	  statementGlobals_->setRowsAffected(0);
	  diagsArea.setRowCount(0);
	}
    }

  return 0;
}

// abort (rollback) transaction, if one is running
short Statement::rollbackTransaction(ComDiagsArea & diagsArea,
				     NABoolean doXnRollback)
{
  ContextCli::CloseCursorType closeCursorType;

  if (context_->getTransaction()->userEndedExeXn())
    {
      if (!diagsArea.contains(-CLI_USER_ENDED_EXE_XN))
         diagsArea << DgSqlCode(- CLI_USER_ENDED_EXE_XN);
      return ERROR;
    }

  if (context_->getTransaction()->xnInProgress())
    {
      if (context_->aqrInfo())
	context_->aqrInfo()->setXnStartedAtPrepare(FALSE);

      NABoolean rollbackXn = FALSE;
      NABoolean autoCommitRollback = FALSE;
      if ((context_->getTransaction()->exeStartedXn()) &&
	  (context_->getTransaction()->autoCommit()))
	{
	  rollbackXn = TRUE;
	  autoCommitRollback = TRUE;
	}
      else if (diagsArea.getRollbackTransaction())
	rollbackXn = TRUE;
      else if (root_tdb && 
	       (root_tdb->transactionReqd() != 0))
	{
	  if (root_tdb->getUpdAbortOnError())
	    rollbackXn = TRUE;
	  else if (root_tdb->getUpdPartialOnError())
	    rollbackXn = FALSE;
	  else if ((NOT root_tdb->getUpdSavepointOnError()) &&
		   ((NOT root_tdb->getUpdErrorOnError()) &&
		    (NOT diagsArea.getNoRollbackTransaction())))
	    rollbackXn = TRUE;
	  else if (doXnRollback)
	    rollbackXn = TRUE;

	  // If aqr has been enabled and this query returned a 
	  // special error due to a concurrent ddl operation,
	  // then do not abort the transaction. This query will be retried
	  // and if this error persists, then the Xn will be aborted.
	  if (root_tdb->aqrEnabled() &&
	      ((diagsArea.mainSQLCODE() == -EXE_TIMESTAMP_MISMATCH)  ||
               (diagsArea.mainSQLCODE() == -CLI_INVALID_QUERY_PRIVS) ||
               (diagsArea.mainSQLCODE() == -CLI_DDL_REDEFINED)       ||
               (diagsArea.mainSQLCODE() == -EXE_SCHEMA_SECURITY_CHANGED)))
	    {
	      rollbackXn = FALSE;
	    }

          // If aqr has been enabled and this query returned a lost open
          // error due to a concurrent ddl operation, allow transaction
          // rollback if IUD.  IUD operations may have updated a subset of 
          // partitions before the lost open error was raised.  For example,
          // an earlier execution updated partitions 2, 3, and 4.  A ddl
          // operation now blows away these opens.  The re-exec updates 
          // partition #1, and the lost open error is raised for 2, 3, 
          // and 4.  The result can be data corruption unless we roll 
          // back the transaction.  See solution 10-100604-0887.
          //
          // But if not IUD, This query will be retried and if this error
          // persists, then the Xn will be aborted.
	  if (root_tdb->aqrEnabled() &&
	      (diagsArea.mainSQLCODE() == -EXE_LOST_OPEN) &&
	      (NOT root_tdb->updDelInsertQuery()))
	    {
	      rollbackXn = FALSE;
	    }
	}
      if (root_tdb && root_tdb->getPsholdCloseOnRollback())
        closeCursorType = ContextCli::CLOSE_ALL_INCLUDING_ANSI_PUBSUB_HOLDABLE;
      else
        closeCursorType = ContextCli::CLOSE_ALL_INCLUDING_ANSI_HOLDABLE;
      if (rollbackXn)
	{
	  short taRetcode;

          // clr count of affected rows.
          // ALM CR 6903 -- although some rows may have been affected
          // if an IUD used NO ROLLBACK, we don' currently have an accurate
          // way to count these, due to the way EXE cancels sessions
          // during error handling and the way the TSE does not dispatch
          // exe-in-dp2 sessions when raising errors such as lock timeouts.
          // So the fix for 6903 is to consistently return 0 rows affected.
          // In the future, we might enhance this.
	  statementGlobals_->setRowsAffected(0);
	  diagsArea.setRowCount(0);

	  NABoolean implicitTran = 
	    context_->getTransaction()->implicitXn();
          // get current context and close all statements
          // started under the current transaction
          context_->closeAllCursors(closeCursorType, ContextCli::CLOSE_CURR_XN,0,TRUE);

	  if (! context_->getTransaction()->xnInProgress())
	    return 0;

	  if (NOT autoCommitRollback)
	    {
	      //////////////////////////////////////////////////////////////
	      // An error occurred while doing an upd/ins/del stmt.
	      // We really need to roll back stmt, but until stmt atomicity
	      // support is not in, we must abort Xn.
	      // RollbackStatement ALWAYS rollbacks Xn. RollbackTransaction
	      // only rollbacks if executor started the Xn.
	      //////////////////////////////////////////////////////////////
	      if (context_->getTransaction()->exeStartedXn())
            {
              StmtDebug1("  About to rollback statement %p...", this);
		taRetcode = context_->getTransaction()
		  ->rollbackStatement();
            }
	      else
		{
		  // doom the transaction
              StmtDebug1("  About to DOOM TX for statement %p...", this);
		  taRetcode = context_->getTransaction()
		    ->doomTransaction();
		}
	    }
	  else
	    {
            StmtDebug1("  About to ROLLBACK TX for statement %p...", this);
	      taRetcode = context_->getTransaction()
		->rollbackTransactionWaited();
	    }

          StmtDebug1("  Return code is %d", (Lng32) taRetcode);

	  // release all outstanding I/Os with transactions, just like
	  // we do when we commit the transaction
	  context_->releaseAllTransactionalRequests();

          // fix 10-040526-4462. We need to force the transid in the context_
          // and the statement global to be in sync. Otherwise, the obsolete transid
          // in the statement global will be passed to the ESP during releaseESPs() 
          // calls. For any remote ESP, the bad transid will be rejected by the TMF
          // (inside the body of FS2_transid_to_buffer()) and the releasing operation 
          // on that ESP will fail, including the termination of the remote ESP. 
          // In some cases, the master will hung.
          //
          // After setting the transid in the statement global to -1 here, we just
          // bypass the call to FS2_transid_to_buffer(). Since remote ESPs caches
          // the transid, the cleanup operation will still use the "good" transid.
          // Note here the transid is obsolete from TMF point of view, but still  
          // valid (good) in terms of SQL/MX data structures (e.g., transid as the key
          // for table lookup).
          //
          // Note the transid in statement global should be to -1 after calling 
          // context::releaseAllTransactionalREquests() because that method calls 
          // statement::releaseTransaction() which uses the transid.
          statementGlobals_->getTransid() = (Int64)-1;

	  if (taRetcode != 0)
	    {
	      diagsArea.mergeAfter(*context_->
				   getTransaction()->getDiagsArea());
	      return ERROR;
	    }
	  else
	    {
              // Fix for solution 10-090908-4444 requires an extra
              // diags condition, error 8839.  To avoid changing lots
              // of expected files, don't do this in the regression
              // test environment.
	      if (! implicitTran)
		{
                  diagsArea << DgSqlCode(- CLI_VALIDATE_TRANSACTION_ERROR);
                  return ERROR;
                }
              else 
                {
                  if (context_->aqrInfo())
                    context_->aqrInfo()->setAbortedTransWasImplicit();
                }
            }
        }
      else if ((root_tdb) &&
	       (root_tdb->getUpdPartialOnError()))
	{
	  diagsArea << DgSqlCode(CLI_PARTIAL_UPDATED_DATA);

	  // Add the affected row count that was directly placed into
	  // the master globals to those that are already in the diags
	  // area. Make both row counts (diags and statementGlobals_)the same.
	  diagsArea.addRowCount(statementGlobals_->getRowsAffected());
	  statementGlobals_->setRowsAffected(diagsArea.getRowCount());
	}
    }

  return 0;
}

static
const NAWchar* get_name_mode(Lng32 name_mode)
{
  switch (name_mode)
  {
  case stmt_handle:
    return L"stmt_handle";
    break;

  case stmt_name:
    return L"stmt_name";
    break;

  case cursor_name:
    return L"cursor_name";
    break;

  case stmt_via_desc:
    return L"stmt_via_desc";

  case curs_via_desc:
    return L"curs_via_desc";
    break;

  default:
    return L"unknown";
    break;
  }
}

void Statement::dump(ostream * outstream)
{
  *outstream << "Statement:      " << this << '\n';

  *outstream << "Module:         ";
  if ((statement_id->module) && (statement_id->module->module_name))
//    *outstream << getModNameInLocale(statement_id->module);
    *outstream << (char *)(statement_id->module->module_name);  
  *outstream << '\n';

  *outstream << "Statement Name: "; 
  if (statement_id->identifier)
//    *outstream << getIdInLocale((SQLCLI_OBJ_ID*)statement_id);
    *outstream << (char *)(statement_id->identifier);
  *outstream << '\n';
  
  *outstream << "Cursor Name:    ";
  if (cursor_name_)
//    *outstream << getIdInLocale((SQLCLI_OBJ_ID*)cursor_name_);
    *outstream << (char *)(cursor_name_);
  *outstream << '\n';

  *outstream << "Name Mode:      " << get_name_mode(statement_id->name_mode) << '\n';

  *outstream << "Type:           " << (allocated() ? "DYNAMIC" : "STATIC") << '\n';

  *outstream << "Heap (total):   " << heap_.getTotalSize() << '\n';
  *outstream << "Heap (alloc):   " << heap_.getAllocSize() << '\n';
  *outstream << "Space (total):  " << space_.getAllocatedSpaceSize() << '\n';

  if (source_str)
    *outstream << source_str << '\n';

  *outstream << "----------------------------------------------------\n";
}

void Statement::setState(State newState) {
  // change the state of the statement. As a side effect the statement
  // might be removed or added from/to the openStatementList()
  switch (stmt_state) {
  case OPEN_:
  case EOF_:
  case FETCH_: //gps Add FETCH_ to "transition from" cases. (4/21/99)
  case RELEASE_TRANS_:
    // remove from list if newState is CLOSE_ or DEALLOCATED_
    if ((newState == CLOSE_) || (newState == DEALLOCATED_))
      {
        State originalState = stmt_state;

	// In certain cases, this statement is not added to the open
	// statement list. This is a performance optimization for
	// unique OLT queries. These queries are non-cursor queries
	// that are completed within one CLI call (ClearExecFetchClose).
	// See PerformTasks method in Cli.cpp for details.
	// Do not add them to open stmt list, 
	stmt_state = newState;
	if (NOT oltOpt())
	  context_->removeFromOpenStatementList(statement_id);

        // If this is a stored procedure result set and it is
        // transitioning out of an open state, then we have some
        // bookkeeping to do
        if (parentCall_ && originalState != EOF_)
        {
          ExRsInfo *parentRsInfo = parentCall_->getResultSetInfo();
          if (parentRsInfo)
          {
            StmtDebug2("  setState() changing RS state to %s, this %p",
                       stmtState(getState()), this);
            ULng32 rsIndex = parentRsInfo->getIndex(this);
            parentRsInfo->setCloseAttempted(rsIndex);
            StmtDebug2("  RS index %u, Num closed since CALL %u",
                       rsIndex, parentRsInfo->getNumClosedSinceLastCall());
          }
        }
        
      }
    break;

  case PREPARE_:
    // remove from list if newState is CLOSE_ or DEALLOCATED_ or INITIAL_
    if ((newState == CLOSE_) || (newState == DEALLOCATED_) || (newState == INITIAL_))
      {
	context_->removeFromOpenStatementList(statement_id);
      }
    break;

  case INITIAL_:
  case CLOSE_:
    // add to openStatementList if new state is OPEN_ or PREPARE_
    if ((newState == OPEN_) || (newState == PREPARE_))
      {
	if (NOT oltOpt())
	  context_->addToOpenStatementList(statement_id, this);
	else
	  context_->removeFromCloseStatementList(this, FALSE);
      }
    break;
  }

  if (stmt_state != newState)
  {
    StmtDebug3("*** Statement %p state change: %s -> %s",
               this, stmtState(stmt_state), stmtState(newState));
  }

  stmt_state = newState;

  if (stmtStats_ != NULL) 
  {
    if (stmtStats_->getMasterStats() != NULL)
     stmtStats_->getMasterStats()->setStmtState(newState);
    stmtStats_->setMergeReqd(TRUE);
  }
}

NABoolean Statement::noRowsAffected(ComDiagsArea & diagsArea)
{
  // ANSI says that an EOF is to be returned if no rows were affected
  // by an update/delete/insert operation.
  if ((root_tdb) && 
      (root_tdb->updDelInsertQuery()) &&
      (diagsArea.getRowCount() == 0) &&
      getRowsAffected() == 0)
    return TRUE;
  else
    return FALSE;
}


NABoolean Statement::isSelectInto()
{
  return (getRootTdb() && getRootTdb()->selectIntoQuery());
}

NABoolean Statement::isDeleteCurrentOf()
{
  return (getRootTdb() && getRootTdb()->deleteCurrentOfQuery());
}

NABoolean Statement::isUpdateCurrentOf()
{
  return (getRootTdb() && getRootTdb()->updateCurrentOfQuery());
}
// BertBert VV
NABoolean Statement::isEmbeddedUpdateOrDelete()
{
  return (getRootTdb() && getRootTdb()->isEmbeddedUpdateOrDelete());
}
NABoolean Statement::isStreamScan()
{
  return (getRootTdb() && getRootTdb()->isStreamScan());
}
// BertBert ^^

RETCODE Statement::setHoldable(ComDiagsArea &diagsArea, NABoolean h)
{
  if (root_tdb == NULL)
    return setAnsiHoldable(diagsArea, h);
  else
    return setPubsubHoldable(diagsArea, h);
}

RETCODE Statement::setPubsubHoldable(ComDiagsArea &diagsArea, NABoolean h)
{
  // tbd -- error for open stmt??
  if (h &&
      root_tdb &&
      !root_tdb->isEmbeddedUpdateOrDelete() &&
      !root_tdb->isStreamScan())
    {
      // Holdable cursors are only supported for streaming cursors
      // and destructive cursors because there are some strange
      // side-effects (locks disappear after commit) that we don't
      // want to inflict on non-Publich/Subscribe functionality at
      // this time. There are no source-code changes needed to allow
      // holdable cursors in these other cases though.
      diagsArea << DgSqlCode(-CLI_CURSOR_CANNOT_BE_HOLDABLE);
      return ERROR;
    }
  if (stmt_state == OPEN_ || stmt_state == FETCH_ || stmt_state == RELEASE_TRANS_)
    {
      // Cannot change holdable attribute while cursor is open.
      diagsArea << DgSqlCode(-CLI_CURSOR_ATTR_CANNOT_BE_SET);
      return ERROR;
    }
  
  if (h)
    holdable_ = SQLCLIDEV_PUBSUB_HOLDABLE;
  else
    holdable_ = SQLCLIDEV_NONHOLDABLE;
  return SUCCESS;
}

RETCODE Statement::setAnsiHoldable(ComDiagsArea &diagsArea, NABoolean h)
{
  // SQL_Exec_SetStmtAttr for setting the holdable cursor can't be called 
  // after the statement is prepared
  if (root_tdb || stmt_state == OPEN_ || stmt_state == FETCH_ || stmt_state == RELEASE_TRANS_)
    {
      // Cannot change holdable attribute while cursor is open.
      diagsArea << DgSqlCode(-CLI_CURSOR_ATTR_CANNOT_BE_SET);
      return ERROR;
    }
  
  if (h)
    holdable_ = SQLCLIDEV_ANSI_HOLDABLE;
  else
    holdable_ = SQLCLIDEV_NONHOLDABLE;
  return SUCCESS;
}

RETCODE Statement::setInputArrayMaxsize(ComDiagsArea &diagsArea, const Lng32 inpArrSize)
{
  if (inpArrSize < 0) {
    diagsArea << DgSqlCode(-CLI_ARRAY_MAXSIZE_INVALID_ENTRY);
    return ERROR;
  }

  inputArrayMaxsize_ = inpArrSize ;
  return SUCCESS ;
}

RETCODE Statement::setRowsetAtomicity(ComDiagsArea &diagsArea, const AtomicityType atomicity)
{
  if ((atomicity != UNSPECIFIED_) && (atomicity != ATOMIC_) && (atomicity != NOT_ATOMIC_)) {
    diagsArea << DgSqlCode(-CLI_INVALID_ATTR_VALUE);
    return ERROR;
  }

  rowsetAtomicity_ = atomicity ;
  return SUCCESS ;
}
  
RETCODE Statement::setNotAtomicFailureLimit(ComDiagsArea &diagsArea, const Lng32 limit)
{
  if (limit < 30) {
    diagsArea << DgSqlCode(-CLI_INVALID_ATTR_VALUE);
    return ERROR;
  }

  notAtomicFailureLimit_ = limit ;
  return SUCCESS ;
}
  
  

void Statement::setOltOpt(NABoolean v)
{
  if (! getRootTdb())
    return;

  if (v && getRootTdb()->doOltQueryOpt())
    flags_ |= OLT_OPT;
  else
    flags_ &= ~OLT_OPT; 
}

// Must be in CLOSE_ state.
// Will cause fixup at open.
Lng32 Statement::releaseSpace()
{
  StmtDebug2("[BEGIN releaseSpace] %p, stmt state %s",
             this, stmtState(getState()));

  if (stmt_state == INITIAL_)
  {
    StmtDebug2("[END releaseSpace] %p, result is %s",
               this, RetcodeToString(SUCCESS));
    return SUCCESS;
  }

  // Bugzilla 1662
  // A statement being reclaimed might be in the EOF_ state. We will
  // not attempt to reclaim these statements. Here's one way an EOF_
  // statement can be encountered:
  // * The statement has an autocommit transaction
  // * End-of-data is fetched
  // * Inside the CLI fetch, we commit the transaction, put the
  //   statement in the CLOSED_ state, and place the statement on
  //   the closed statement list
  // * Then we change the statement state to EOF_ so that a subsequent
  //   SQL_EXEC_CloseStmt will succeed
  // * The statement is now on the closed statement list, is in the
  //   EOF_ state, but is not actually a valid candidate for reclaim
  //   until the CLI caller issues SQL_EXEC_CloseStmt
  if (stmt_state == EOF_)
  {
    StmtDebug2("[END releaseSpace] %p, result is %s",
               this, RetcodeToString(SUCCESS));
    return SUCCESS;
  }

  assert(stmt_state == CLOSE_);
  RETCODE result = releaseTcbs(FALSE);
  
  if (result == SUCCESS)
  {
    setState(CLOSE_); // The state may have changed by a call within releaseTcbs()
    space_.freeBlocks();
    setFixupState(0);  // will fixup at exec()
    // To recalculate the bulk move info when the tcb is re-generated
    setComputeBulkMoveInfo(TRUE);
    if (stmtStats_ != NULL && stmtStats_->getMasterStats() != NULL)
      stmtStats_->getMasterStats()->incReclaimSpaceCount();
  }

  StmtDebug2("[END releaseSpace] %p, result is %s",
             this, RetcodeToString(result));
  return (Lng32) result;
}

NABoolean Statement::isReclaimable()
{
  if (root_tdb != NULL && 
      (root_tdb->getQueryType() == ComTdbRoot::SQL_INSERT_RWRS ||
       root_tdb->cantReclaimQuery()))
    return FALSE;
  else
    return TRUE;
}

NABoolean Statement::returnRecompWarn()
{
  if (stmt_type == STATIC_STMT)
    return recompWarn();
  else if (root_tdb)
    return root_tdb->recompWarn();
  else
    return FALSE;
}

// Wait for completion of UDR requests associated with this
// statement. If allRequests is FALSE then only wait for transactional
// requests.
RETCODE Statement::completeUdrRequests(NABoolean allRequests) const
{

  RETCODE result = SUCCESS;
  while (statementGlobals_ &&
         ((allRequests && statementGlobals_->numUdrMsgsOut() > 0) ||
          (!allRequests && statementGlobals_->numUdrTxMsgsOut() > 0)))
  {
    // First attempt to complete requests on scalar udr server
    IpcConnection *conn = statementGlobals_->getUdrConnection();
    ExUdrServer *udrServ = statementGlobals_->getUdrServer();
    if(conn != NULL && udrServ != NULL)
    {
      StmtDebug1(
      "  About to call ExUdrServer::completeUdrRequests(%p, FALSE)...",
        conn);

      udrServ->completeUdrRequests(conn, FALSE);
    }

    // Next, attempt to complete requests on dedicated udr servers
    // if there are any.
    LIST(ExUdrServer *) udrServList = statementGlobals_->getUdrServersD();
    for (CollIndex i = 0; i < udrServList.entries(); i++)
    {
      ExUdrServer *udrServ = udrServList[i];
      IpcConnection *conn = udrServ->getUdrControlConnection();
      
      StmtDebug1(
        "  About to call ExUdrServer::completeUdrRequests(0x%08x, FALSE)...",
        conn);
      udrServ->completeUdrRequests(conn, FALSE);
    }
    StmtDebug0("  Done");
  }
  
  return result;
}

void Statement::setUniqueStmtId(char * id)
{
  if (uniqueStmtId_)
    {
      // get start & finished messages to cancel broker cleaned up
      // before switching qid.
      if (root_tcb && root_tcb->anyCbMessages())
        releaseTransaction(TRUE);

      NADELETEBASIC(uniqueStmtId_, &heap_);
      uniqueStmtId_ = NULL;
    }

  if (id)
    {
      uniqueStmtId_ = new(&heap_) char[strlen(id)+1];
      strcpy(uniqueStmtId_, id);
      uniqueStmtIdLen_ = strlen(uniqueStmtId_);
    }
  else
    {
      // generate a unique id and set it.
      uniqueStmtId_ = new(&heap_) char[ComSqlId::MAX_QUERY_ID_LEN+1];
      
      char tmpLong[ 20 ];
      if (statement_id->name_mode == stmt_handle)
	str_ltoa((ULong)getStmtHandle(), tmpLong);
      ComSqlId::createSqlQueryId(uniqueStmtId_,
				 ComSqlId::MAX_QUERY_ID_LEN+1,
				 uniqueStmtIdLen_,
				 strlen(context_->getSessionId()),
				 context_->getSessionId(),
				 cliGlobals_->getNextUniqueNumber(),
				 ((statement_id->name_mode == stmt_handle)
				  ? strlen(tmpLong)
				  : strlen(getIdentifier())),
				 (char*)
				 ((statement_id->name_mode == stmt_handle)
				  ? tmpLong
				  : getIdentifier())
				 );
    }
}

// This method should always be used to assign a new value to the
// root_tdb data member. The method will keep the root_tdb pointer for
// a given statement in sync with its clones.
//
// NOTE: we really should have this method keep the root_tdb_size data
// member in sync with root_tdb. But currently root_tdb_size is only
// used by SHOWPLAN code paths and on other paths is not maintained. A
// possible future improvement is to keep root_tdb and root_tdb_size
// in sync on all code paths.

ex_root_tdb * Statement::assignRootTdb(ex_root_tdb *new_root_tdb)
{
  if (root_tdb == new_root_tdb)
    return root_tdb;

  if (root_tdb)
  {
    // dealloc() will release the TCB tree for this statement and will
    // also call dealloc() for any cloned statements
    dealloc();
    
    if (!isCloned())
    {
      // solution 10-040803-8511: root_tdb is not unpacked for SHOWPLAN
      // the lateNameInfoList is still the offset, not valid pointer
      if (!root_tdb->isPacked() && root_tdb->getLateNameInfoList() != NULL)
        for (Int32 i = 0;
             i < (Int32) (root_tdb->getLateNameInfoList()->getNumEntries());
             i++)
          root_tdb->getLateNameInfoList()->
            getLateNameInfo(i).zeroLastUsedAnsiName();     
      CollHeap *h = cliGlobals_->getArkcmp()->getHeap();
      h->deallocateMemory((void *) root_tdb);
      StmtDebug2("  Stmt %p deallocated root TDB %p", this, root_tdb);
    }
  }

  root_tdb = new_root_tdb;
  StmtDebug2("  Stmt %p root TDB is now %p", this, root_tdb);

#ifdef _DEBUG
  Lng32 rs = (Lng32) (root_tdb ? root_tdb->getMaxResultSets() : 0);
  if (rs > 0)
    StmtDebug1("  Max result sets: %d", rs);
#endif

  clonedStatements->position();
  Statement *clone = (Statement *) clonedStatements->getNext();
  for (; clone != NULL; clone = (Statement *) clonedStatements->getNext())
  {
    clone->root_tdb = new_root_tdb;
    StmtDebug2("  Clone %p root TDB is now %p", clone, new_root_tdb);
  }

  return root_tdb;
}

RETCODE Statement::addDescInfoIntoStaticDesc(Descriptor * desc,
					     Lng32 what_desc,
					     ComDiagsArea &diagsArea)
{
  if(!root_tdb){
    return SUCCESS;
  }

  InputOutputExpr *expr;
  enum ex_expr::exp_return_type expRType;

  Int32 retcode = 0; // be optimistic

  // A special case for DESCRIBE is when the SQL statement is a CALL
  // statement and the CLI caller wants to use a "wide" descriptor for
  // the CALL.
  if (root_tdb->hasCallStmtExpressions() && desc->isDescTypeWide())
  {
    // First populate the caller's descriptor with information from
    // the INPUT expression, the overlay information from the OUTPUT
    // expression into the same descriptor.

    if(expr = root_tdb->inputExpr())
    {
      expRType = expr->addDescInfoIntoStaticDesc(desc, TRUE /*input*/);
      if(expRType != ex_expr::EXPR_OK)
	retcode = -1;
    }
    
    if((retcode == 0) && (expr = root_tdb->outputExpr()))
    {
      expRType = expr->addDescInfoIntoStaticDesc(desc, FALSE /*output*/);
      if(expRType != ex_expr::EXPR_OK)
	retcode = -1;
    }
  }
  else{
    NABoolean isInput;
    if (what_desc == SQLWHAT_INPUT_DESC){
      expr = root_tdb->inputExpr();      // input expr -> desc
      isInput = TRUE;
    }
    else{
      expr = root_tdb->outputExpr();	// output expr -> desc
      isInput = FALSE;
    }
    if(expr)
    {
      expRType = expr->addDescInfoIntoStaticDesc(desc, isInput);
      if(expRType != ex_expr::EXPR_OK)
	retcode = -1;
    }
  }
  
  if (retcode)
  {
    diagsArea << DgSqlCode(- CLI_TDB_DESCRIBE_ERROR);
    return ERROR;
  }

  return SUCCESS;
}

NABoolean Statement::containsUdrInteractions() const
{
  return (root_tdb && root_tdb->containsUdrInteractions());
}

//------------------------------------------------------------------------------
// 
// For each stoi that is marked as subject table, get trigger status array from 
// the corresponding rfork. This status array is used to update the status of the
// relevant triggers in the call to updateTriggerStatusPerTable()
//
RETCODE Statement::getTriggersStatus(SqlTableOpenInfoPtr* stoiList, ComDiagsArea &diagsArea)
{
  
  TriggerStatusWA triggerStatusWA(&heap_, root_tcb);
  SqlTableOpenInfo* stoi;
  RETCODE rc = SUCCESS;
  
  for (Int32 i=0; i< root_tcb->getTableCount(); i++)
    {
      stoi=stoiList[i];
      if (stoi->subjectTable())
        {
          
          // save the current diags before entering CLI again
          ComDiagsArea* copyOfDiagsArea = diagsArea.copy(); 
          // remove warning 100 from diags.
          diagsArea.removeFinalCondition100();
          
          // merge diags
          diagsArea.mergeAfter(*copyOfDiagsArea);
          copyOfDiagsArea->decrRefCount();
          copyOfDiagsArea = NULL;
          
          // select the status of the triggers relevant to this statement
          // and update them in the root_tcb->triggerStatusVector_
          triggerStatusWA.updateTriggerStatusPerTable();
          triggerStatusWA.deallocateStatusArray();
        }
    }
  
#ifdef _DEBUG
  if (getenv("SHOW_ENABLE"))
    {
      char int64Str[128];
      cout << "Trigger Ids in TDB:" << endl;
      cout << "-------------------" << endl;
      for (Int32 i=0; i<triggerStatusWA.getTotalTriggersCount(); i++) 
        {
          convertInt64ToAscii(root_tdb->getTriggersList()[i], int64Str);
          cout << i << " : " << int64Str << endl;
        }
      cout << endl;
      
    }
#endif //_DEBUG

  // we cannot check that status was received for all triggers, since
  // triggers may be dropped/added before similarity check is done...
  // if (triggerStatusWA.getTotalTriggersCount() == root_tdb->getTriggersCount())
  return rc;
  
}

// ++ MV -
// isIudTargetTable returns TRUE if the table is the target of an
// insert/update/delete operation, or if the table does not appear in stoi.
NABoolean Statement::isIudTargetTable(char                *tableName, 
				      SqlTableOpenInfoPtr *stoiList)
{
  NABoolean found = FALSE;
  for (Int32 i=0; root_tcb && i < root_tcb->getTableCount(); i++)
    {
      SqlTableOpenInfo *stoi=stoiList[i];

      if (! strcmp(stoi->ansiName(), tableName))
      {
	found = TRUE;
	if (stoi->getInsertAccess() || 
	    stoi->getUpdateAccess() || 
	    stoi->getDeleteAccess())
	return TRUE;
      }
    }

  if (found)
    return FALSE;
  else
    return TRUE;
}

RETCODE Statement::mvSimilarityCheck(char         *table, 
				     ULng32 siMvBitmap, 
				     ULng32 rcbMvBitmap,
				     NABoolean    &simCheckFailed,
				     ComDiagsArea &diagsArea)
{ 
  ComMvAttributeBitmap	siBitmap;
  ComMvAttributeBitmap	rcbBitmap;
  NABoolean iud = isIudTargetTable(table, root_tdb->stoiStoiList());

  siBitmap.initBitmap((ComSInt32)siMvBitmap);
  rcbBitmap.initBitmap((ComSInt32)rcbMvBitmap);

  // if it is INSERT/UPDATE/DELETE statement and table/MV has initialized 
  // ON STATEMENT MV on it - recompile
  if (iud &&
      rcbBitmap.getInitOnStmtMvOnMe())
  {
    if (returnRecompWarn())
      diagsArea << DgSqlCode(EXE_SIM_CHECK_FAILED)
		<< DgString0("Table has on statement MVs on it."); 
    simCheckFailed = TRUE;
    return SUCCESS;
  }

  // if it is INSERT/UPDATE/DELETE statement and table/MV had initialized 
  // ON STATEMENT MV on it - recompile
  if (iud &&
      siBitmap.getInitOnStmtMvOnMe() != rcbBitmap.getInitOnStmtMvOnMe())
  {
    if (returnRecompWarn())
      diagsArea << DgSqlCode(EXE_SIM_CHECK_FAILED)
		<< DgString0("On statement MVs have been removed."); 
    simCheckFailed = TRUE;
    return SUCCESS;
  }

  // if it is INSERT/UPDATE/DELETE statement and table/MV logging required 
  // bit was changed - recompile
  if (iud && siBitmap.getLoggingRequired() != rcbBitmap.getLoggingRequired())
  {
    if (rcbBitmap.getLoggingRequired())
    {
      if (returnRecompWarn())
	diagsArea << DgSqlCode(EXE_SIM_CHECK_FAILED)
	<< DgString0("Logging is required.");
    }
    else
    {
      if (returnRecompWarn())
	diagsArea << DgSqlCode(EXE_SIM_CHECK_FAILED)
		  << DgString0("Logging is not required any more.");
    }

    simCheckFailed = TRUE;
    return SUCCESS;
  }
  
  // if MV enable rewrite bit was change to disable rewrite - recompile
  if (siBitmap.getIsEnableRewrite()  && !rcbBitmap.getIsEnableRewrite())
  {
    if (returnRecompWarn())
      diagsArea << DgSqlCode(EXE_SIM_CHECK_FAILED)
		<< DgString0("MV rewrite was disabled.");
    simCheckFailed = TRUE;
    return SUCCESS;
  }

  // if MV audit bits were changed, but not between the values 
  // AUDIT <--> AUDITONREFRESH - recompile
  ComMvAuditType siMvAuditType = siBitmap.getMvAuditType();
  ComMvAuditType rcbMvAuditType = rcbBitmap.getMvAuditType();
  if (siMvAuditType != rcbMvAuditType &&
      !((siMvAuditType  == COM_MV_NO_AUDIT_ON_REFRESH && 
         rcbMvAuditType == COM_MV_AUDIT)                ||
        (rcbMvAuditType == COM_MV_NO_AUDIT_ON_REFRESH && 
         siMvAuditType  == COM_MV_AUDIT)))
  {
    if (returnRecompWarn())
      diagsArea << DgSqlCode(EXE_SIM_CHECK_FAILED)
		<< DgString0("MV audit status was changed.");
    simCheckFailed = TRUE;
    return SUCCESS;
  }


  // if table insertlog bit was changed - recompile
  if (iud && siBitmap.getIsInsertLog() != rcbBitmap.getIsInsertLog())
  {
    if (returnRecompWarn())
      diagsArea << DgSqlCode(EXE_SIM_CHECK_FAILED)
		<< DgString0("Table INSERTLOG attribute was changed.");
    simCheckFailed = TRUE;
    return SUCCESS;
  }

  // if statement is INSERT/UPDATE/DELETE on table and logging is required 
  // and range log bits was changed, but not between the values 
  // NO RANGELOG <--> MIX RANGELOG - recompile
  ComRangeLogType siRangeLogType = siBitmap.getRangeLogType();
  ComRangeLogType rcbRangeLogType = rcbBitmap.getRangeLogType();
  if (iud                                            && 
      siBitmap.getLoggingRequired()                  &&
      siRangeLogType != rcbRangeLogType              &&
      !((siRangeLogType  == COM_NO_RANGELOG     && 
         rcbRangeLogType == COM_MIXED_RANGELOG)    ||
	(rcbRangeLogType == COM_NO_RANGELOG     && 
	 siRangeLogType  == COM_MIXED_RANGELOG))
      )
  {
    if (returnRecompWarn())    
      diagsArea << DgSqlCode(EXE_SIM_CHECK_FAILED)
		<< DgString0("Table RANGELOG attribute was changed.");
    simCheckFailed = TRUE;
    return SUCCESS;
  }

  // MV is unavailable 
  if (rcbBitmap.getMvStatus() == COM_MVSTATUS_UNAVAILABLE)
  {
    if (returnRecompWarn())
      diagsArea << DgSqlCode(EXE_SIM_CHECK_FAILED)
		<< DgString0("Materialized view is not available.");
      simCheckFailed = TRUE;
      return SUCCESS;
  }

  simCheckFailed = FALSE;
  return SUCCESS;
}

// Discover whether there is already a transaction active
// so that we can avoid starting one when we call CatMapGetCatalogVisibilty,
// CatMapAnsiNameToGuardianName, or other recursive CLI calls.
NABoolean Statement::implicitTransNeeded(void)
{
  const NABoolean noTransInProgress = 
      (context_->getTransaction()->xnInProgress() == FALSE);
  if (noTransInProgress)
    anyTransWasStartedByMe_ = TRUE;
  return noTransInProgress;
}

// If autocommit is on, disable it, prior to making recursive CLI calls.
// Remember if we disabled autoCommit so we can enable before returning 
// from this method.
void Statement::turnOffAutoCommit(void)
{
  if (context_->getTransaction()->autoCommit())
    {
      autoCommitCleared_ = TRUE;
      context_->getTransaction()->disableAutoCommit();
    }
}


// Turn back on autoCommit if we had turned it off.  Maintain the 
// state variable so the statement can be reexecuted.
void Statement::resetAutoCommit(void)
{
  if (autoCommitCleared_)
  {
    autoCommitCleared_ = FALSE;
    context_->getTransaction()->enableAutoCommit();
  }
}
void Statement::saveTmodeValues(void)
{
  ExTransaction  *runTrans = context_->getTransaction();

  if (runTrans)
    {
      savedRoVal_ = runTrans->getROVal();
      savedRbVal_ = runTrans->getRBVal();
      savedAiVal_ = runTrans->getAIVal();
    }
}

void Statement::resetTmodeValues(void)
{
  ExTransaction * runTrans = context_->getTransaction();

  if (runTrans)
    {
      
      runTrans->updateROVal(savedRoVal_);
      runTrans->updateRBVal(savedRbVal_);
      runTrans->updateAIVal(savedAiVal_);
    }
}

// Commit any transaction that we started.  Turn back on autoCommit if we 
// had turned it off.  Maintain the state variables so the statement can be
// reexecuted.
void Statement::commitImplicitTransAndResetTmodes(void)
{
  if (anyTransWasStartedByMe_)
  {
    anyTransWasStartedByMe_ = FALSE;
    if (context_->getTransaction()->xnInProgress())
    {
      // Don't care about any error -- this was a readonly transaction.
      context_->getTransaction()->commitTransaction();
    }
  }
  resetAutoCommit();
  resetTmodeValues();
}


ExStatisticsArea *Statement::getStatsArea()
{
  if (getGlobals())
    return getGlobals()->getStatsArea();
  return NULL;
}

ExStatisticsArea *Statement::getOrigStatsArea()
{
  if (getGlobals())
    return getGlobals()->getOrigStatsArea();
  return NULL;
}

ExStatisticsArea *Statement::getCompileStatsArea()
{
  ExStatisticsArea *stats;
  if ((stats = getStatsArea()) != NULL)
    return stats;
  if (compileStatsArea_ != NULL)
    return compileStatsArea_;
  if (stmtStats_ == NULL || stmtStats_->getMasterStats() == NULL)
    return NULL;
  compileStatsArea_ = new (&heap_) 
    ExStatisticsArea(&heap_, 0, getRootTdb()->getCollectStatsType(),
      getRootTdb()->getCollectStatsType());
  ExMasterStats *masterStats = new(&heap_) ExMasterStats(&heap_);
  masterStats->copyContents(stmtStats_->getMasterStats());
  masterStats->setCollectStatsType(getRootTdb()->getCollectStatsType());
  compileStatsArea_->setMasterStats(masterStats);
  return compileStatsArea_;
}

void Statement::setStmtStats(NABoolean autoRetry)
{
  StatsGlobals *statsGlobals = NULL;
  int error;
  NABoolean stmtStatsRetained = FALSE;
  StmtStats *stmtStats = NULL;
  if (stmtStats_ != NULL)
  {
    if (getRootTdb())
      assignRootTdb (NULL);
  }
  statsGlobals = cliGlobals_->getStatsGlobals();
  if (statsGlobals != NULL)
  {
    error = statsGlobals->getStatsSemaphore(cliGlobals_->getSemId(),
                  cliGlobals_->myPin());
    if (autoRetry)
    {
      if (getUniqueStmtId() != NULL)
      {
        stmtStats = statsGlobals->getMasterStmtStats(getUniqueStmtId(), getUniqueStmtIdLen(), 
              RtsQueryId::ANY_QUERY_);
        ex_assert(stmtStats, "AQR but missing stmtStats.");
        stmtStatsRetained = TRUE;
      }
    }
    else
    {
      // If the same statement handle is used to prepare the query again
      // stmtStats_ would have been set, remove the query in that case
      if (stmtStats_ != NULL)
      {
        if (stmtStats_->getMasterStats() != NULL)
        {
          stmtStats_->getMasterStats()->setStmtState(Statement::DEALLOCATED_);
	  stmtStats_->getMasterStats()->setEndTimes(! stmtStats_->aqrInProgress());
        }
        // Make a copy of stmtStats_ pointer so that in case it is retained we could use 
        // the same stmtStats-
        stmtStats = stmtStats_;
        stmtStatsRetained = statsGlobals->removeQuery(cliGlobals_->myPin(), stmtStats_);
      }
    }
    if (getUniqueStmtId() != NULL)
    {
      if (! stmtStatsRetained)
      {
        stmtStats_ = statsGlobals->addQuery(cliGlobals_->myPin(), 
              getUniqueStmtId(),
              getUniqueStmtIdLen(), (void *)this, (Lng32)-1,
              source_str, source_length, TRUE);
        ex_assert(stmtStats_, "StmtStats_ is null after addQuery");
      }
      else
      {
        ExStatisticsArea *myStats = stmtStats->getStatsArea();
        stmtStats->reuse((void *)this);
        getGlobals()->setStatsArea(NULL);
        if (myStats != NULL && context_->getStats() == myStats)
          context_->setStatsArea(NULL, FALSE, FALSE, FALSE);
        stmtStats_ = stmtStats;
      }
      // update the parentQid
      char *parentQid = getParentQid();
      char *parentQidSystem = getParentQidSystem();
      ULng32 parentQidSystemLen; 
      if (parentQidSystem != NULL)
         parentQidSystemLen = str_len(parentQidSystem);
      else
         parentQidSystemLen = 0; 
      if (parentQid != NULL)
        stmtStats_->setParentQid(parentQid, str_len(parentQid), parentQidSystem, 
                  parentQidSystemLen, cliGlobals_->myCpu(), (short)cliGlobals_->myNodeNumber());
      else
        stmtStats_->setParentQid(NULL, 0, NULL, 0, cliGlobals_->myCpu(), (short)cliGlobals_->myNodeNumber());
    }
    else
      stmtStats_ = NULL;
    statsGlobals->releaseStatsSemaphore(cliGlobals_->getSemId(), cliGlobals_->myPin());
  }
  else
  {
    if (stmtStats_ != NULL)
    {
      NADELETE(stmtStats_, StmtStats, stmtStats_->getHeap());
      stmtStats_ = NULL;
    }   
    // runtime stats not supported on NT platform or runtime stats
    // subsystem not up and running.
    // Allocate ExMasterStats without going thru StatsGlobals.
    stmtStats_ = StatsGlobals::addStmtStats(stmtHeap(),
					cliGlobals_->myPin(), 
					getUniqueStmtId(),
					getUniqueStmtIdLen(),
                                        source_str, source_length);
  }
}

// VO, Plan Versioning Support.
void Statement::issuePlanVersioningWarnings (ComDiagsArea & diagsArea)
{
  if (returnRecompWarn())
  {
    if (fetchErrorCode_ != VERSION_NO_ERROR)
    {
      // A plan versioning error was detected at fetch time
      diagsArea << DgSqlCode (fetchErrorCode_)
                << DgInt0 (fetchPlanVersion_)
                << DgString0 (fetchNode_)
                << DgInt1 (fetchSupportedVersion_);
    }

    if (mxcmpErrorCode_ != VERSION_NO_ERROR)
    {
      // A plan versioning error was detected at prepare time
      diagsArea << DgSqlCode (mxcmpErrorCode_)
                << DgInt0 (mxcmpStartedVersion_)
                << DgInt1 (COM_VERS_COMPILER_VERSION);
    }
  }

  // Unconditionally clear the saved warning codes, even though we
  // may not have reported them - we don't want them hanging around
  // if we recompile for some other reason.
  fetchErrorCode_ = VERSION_NO_ERROR;
  mxcmpErrorCode_ = VERSION_NO_ERROR;
}
const char *Statement::stmtState(State state) 
{
  switch (state)
  {
    case INITIAL_:       return "INITIAL";
    case OPEN_:          return "OPEN";
    case EOF_:           return "EOF";
    case CLOSE_:         return "CLOSE";
    case DEALLOCATED_:   return "DEALLOCATED";
    case FETCH_:         return "FETCH";
    case CLOSE_TABLES_:  return "CLOSE_TABLES";
    case PREPARE_:       return "PREPARE";
    case PROCESS_ENDED_: return "PROCESS_ENDED";
    case RELEASE_TRANS_: return "RELEASE_TRANS";
    case SUSPENDED_:     return "SUSPENDED";
    case STMT_EXECUTE_:  return "EXECUTE";
    case STMT_FIXUP_:    return "FIXUP";
    default:             return ComRtGetUnknownString((Int32) state);
  }
}

ExRsInfo *Statement::getResultSetInfo() const
{
  if (statementGlobals_)
    return statementGlobals_->getResultSetInfo();
  return NULL;
}

ExRsInfo *Statement::getOrCreateResultSetInfo()
{
  ex_assert(statementGlobals_, "No statement globals available");
  return statementGlobals_->getResultSetInfo(TRUE);
}

// For stored procedure result set proxy statements, return TRUE if
// the current statement source matches the newSource input string.
NABoolean Statement::rsProxyCompare(const char *newSource) const
{
  NABoolean result = FALSE;

  if (newSource != NULL && source_str != NULL &&
      charset_ == SQLCHARSETCODE_ISO88591 &&
      str_cmp_ne(source_str, newSource) == 0)
  {
    result = TRUE;
  }

  return result;
}

// For stored procedure result set proxy statements, see if a
// prepare of proxy syntax is required and if so, do the internal 
// prepare
RETCODE Statement::rsProxyPrepare(ExRsInfo &rsInfo,          // IN
                                  ULng32 rsIndex,     // IN
                                  ComDiagsArea &diagsArea)   // INOUT
{
  StmtDebug3("[BEGIN rsProxyPrepare] %p, rsIndex %u, stmt state %s",
             this, rsIndex, stmtState(getState()));

  RETCODE result = SUCCESS;

  // These variables will be populated below by the call to
  // getRsInfo()
  NABoolean preparedFlag = FALSE;
  Statement *proxyStmt = NULL;
  NABoolean openFlag = FALSE;
  NABoolean closedFlag = FALSE;

  // We have the ability to acquire proxy strings from the
  // environment. The mechanism is currently disabled. See comments in
  // the getProxySyntaxFromEnvironment() function (in this file) for
  // more info.
  const char *proxySyntax = NULL;

  if (proxySyntax)
  {
    StmtDebug0("  *** WILL USE PROXY SYNTAX FROM AN ENV VAR");
  }
  else
  {
    NABoolean found = rsInfo.getRsInfo(rsIndex, proxyStmt, proxySyntax,
                                       openFlag, closedFlag, preparedFlag);
  }

  StmtDebug2("  rsIndex %u, prepared flag %d", rsIndex, (Int32) preparedFlag);
  StmtDebug1("  proxySyntax [%s]", (proxySyntax ? proxySyntax : "(NULL)"));
  
  if (proxySyntax == NULL)
  {
    diagsArea << DgSqlCode(-EXE_UDR_RS_NOT_AVAILABLE)
              << DgInt0((Int32) rsIndex);
    result = ERROR;
  }
  
  if (result != ERROR)
  {
    if (!preparedFlag)
    {
      NABoolean okToReusePlan = FALSE;
      if (stmt_state != INITIAL_ && root_tdb != NULL)
      {
        // This means we currently have a plan. Next step is to decide
        // if it suitable for reuse.
        if (rsProxyCompare(proxySyntax))
          okToReusePlan = TRUE;
      }

      if (!okToReusePlan)
      {
        // $$$$ PROXY RECOMPILE: We can consider returning a new
        // warning condition when a proxy is prepared. This may help
        // CLI callers avoid doing describes on a proxy after every
        // CALL execution.
        result = prepare((char *) proxySyntax, diagsArea, NULL, 0L);
      }

      if (result != ERROR)
      {
        rsInfo.setPrepared(rsIndex);
      }
      else
      {
        // Add a condition to the diags area indicating it was an
        // internal operation that failed unexpectedly
        diagsArea << DgSqlCode(-EXE_UDR_RS_ALLOC_INTERNAL_ERROR);
      }
    }
  }
  
  StmtDebug3("[END rsProxyPrepare] %p, stmt state %s, retcode %s",
             this, stmtState(getState()), RetcodeToString(result));
  
  return result;
}

// Helper function to convert a char string to quoted char string.
// Also, single quote chars will be replaced with two single quote chars.
static
char* toQuotedString(char *src, Lng32 srcLen, NAHeap *heap)
{
  // Allocate a buffer to fix the resultant string.
  char *target = new (heap) char[2 * srcLen + 3];
  char *targetPtr = target;

  *targetPtr++ = '\'';  // beginning quote

  for (Lng32 pos = 0; pos < srcLen; pos++)
  {
    *targetPtr++ = src[pos];

    if (src[pos] == '\'')
      *targetPtr++ = '\'';
  }
  *targetPtr++ = '\'';  // ending quote
  *targetPtr = '\0';  // NULL terminator

  return target;
}

// getProxySyntax generates the text of a SELECT statement that we
// call "proxy syntax". The two uses of these SELECTs are stored
// procedure result sets and parallel extract consumer queries.
//
// The result set proxy syntax is of the form:
// 
//     SELECT * FROM TABLE ( SP_RESULT_SET ( <col-type-spec>,
//                                           <col-type-spec>, ... ) )
//
// where <col-type-spec> is in the format
//  <cat>.<sch>.<table>.<colname> datatype [HEADING '<heading>'] [NOT NULL]
//
// The extract consumer syntax is of the form:
// 
//     SELECT * FROM TABLE ( EXTRACT_SOURCE ( 'ESP', 'esp-process-handle',
//                                            'security-key', 
//                                            <col-type-spec>,
//                                            <col-type-spec>, ... ) )
//
// The getProxySyntax function takes a prefix and suffix as input and
// generates the string:
//
//    <prefix> <col-type-spec>, ... <suffix>
//
//  In addition to generating proxy syntax, this method also computes
//  the size of the proxy syntax string.
//
//  This method first assumes that 'proxy' with 'maxlength' size
//  is sufficient for holding proxy syntax. If it realizes that
//  'proxy' does not have enough space then the copying stops but the
//  function proceeds to compute the required size
//
//  The size of proxy syntax will be returned in spaceRequired.
//
RETCODE Statement::getProxySyntax(char *proxy, Lng32 maxlength,
                                  Lng32 *spaceRequired,
                                  const char *prefix, const char *suffix)
{
  // In the code below, once we set hasEnoughSpace to FALSE,
  // it will never be changed to TRUE again.
  NABoolean hasEnoughSpace = TRUE;

  // If proxy is NULL, we only compute the size of proxy syntax
  // if spaceRequired is provided.
  if (!proxy) hasEnoughSpace = FALSE;

  if (!proxy && ! spaceRequired)
    return SUCCESS;

  InputOutputExpr *expr = getRootTdb()->outputExpr();
  if (expr == NULL)
  {
    if (spaceRequired) *spaceRequired = 0;
    return SUCCESS;
  }

  SQLMODULE_ID mod_id;
  SQLDESC_ID desc_id;

  mod_id.module_name = 0;
  desc_id.name_mode = desc_handle;
  desc_id.identifier = 0;
  desc_id.handle = 0;
  desc_id.module = &mod_id;

  Descriptor *outdesc = new (&heap_) Descriptor(&desc_id,
                                                expr->getNumEntries(),
                                                context_);
  outdesc->dealloc();
  outdesc->alloc(expr->getNumEntries());

  // Describe the OUTPUT expression
  UInt32 flags = 0;
  expr->setIsODBC(flags, root_tdb->odbcQuery());
  expr->setInternalFormatIO(flags, 
			    context_->getSessionDefaults()->
			    getInternalFormatIO());
  expr->setIsDBTR(flags,
		  context_->getSessionDefaults()->getDbtrProcess());
  expr->describeOutput(outdesc, flags);

  // Now generate proxy syntax string
  char *proxyPtr = proxy;
  Lng32 spaceLeft = maxlength;
  Lng32 spaceNeeded = 0;

  if (prefix == NULL)
    prefix = "";
  if (suffix == NULL)
    suffix = "";

  Lng32 prefixLen = str_len(prefix);
  Lng32 suffixLen = str_len(suffix);

  if (spaceLeft < prefixLen) hasEnoughSpace = FALSE;
  spaceNeeded += prefixLen;
  if (hasEnoughSpace)
  {
    str_cpy_all(proxyPtr, prefix, prefixLen);
    proxyPtr += prefixLen;
    spaceLeft -= prefixLen;
  }

  for (Int32 entry = 1; entry <= expr->getNumEntries(); entry++)
  {
    char *name = NULL;
    Lng32 nameLen;

    // get CATALOG attribute
    outdesc->getDescItemPtr(entry, SQLDESC_CATALOG_NAME, &name, &nameLen);
    if (name != NULL)
    {
      char *catName = ToAnsiIdentifier2(name, nameLen, &heap_);
      Lng32 catLen = str_len(catName);

      // Write CATALOG attribute
      if (spaceLeft < catLen + 1) hasEnoughSpace = FALSE;
      spaceNeeded += (catLen + 1);
      if (hasEnoughSpace)
      {
        str_cpy_all(proxyPtr, catName, catLen);
        str_cpy_all(proxyPtr+catLen, ".", 1);
        proxyPtr += (catLen + 1);
        spaceLeft -= (catLen + 1);
      }
      heap_.deallocateMemory(catName);
    }

    // get SCHEMA attribute
    outdesc->getDescItemPtr(entry, SQLDESC_SCHEMA_NAME, &name, &nameLen);
    if (name != NULL)
    {
      char *schName = ToAnsiIdentifier2(name, nameLen, &heap_);
      Lng32 schLen = str_len(schName);

      // Write SCHEMA attribute
      if (spaceLeft < schLen + 1) hasEnoughSpace = FALSE;
      spaceNeeded += (schLen + 1);
      if (hasEnoughSpace)
      {
        str_cpy_all(proxyPtr, schName, schLen);
        str_cpy_all(proxyPtr+schLen, ".", 1);
        proxyPtr += (schLen + 1);
        spaceLeft -= (schLen + 1);
      }
      heap_.deallocateMemory(schName);
    }

    // get TABLE attribute
    outdesc->getDescItemPtr(entry, SQLDESC_TABLE_NAME, &name, &nameLen);
    if (name != NULL)
    {
      char *tabName = ToAnsiIdentifier2(name, nameLen, &heap_);
      Lng32 tabLen = str_len(tabName);

      // Write TABLE attribute
      if (spaceLeft < tabLen + 1) hasEnoughSpace = FALSE;
      spaceNeeded += (tabLen + 1);
      if (hasEnoughSpace)
      {
        str_cpy_all(proxyPtr, tabName, tabLen);
        str_cpy_all(proxyPtr+tabLen, ".", 1);
        proxyPtr += (tabLen + 1);
        spaceLeft -= (tabLen + 1);
      }

      heap_.deallocateMemory(tabName);
    }

    // get COLUMN Name attribute
    outdesc->getDescItemPtr(entry, SQLDESC_NAME, &name, &nameLen);
    if (name != NULL)
    {
      char *colName = ToAnsiIdentifier2(name, nameLen, &heap_);
      Lng32 colLen = str_len(colName);

      // Write COLUMN attribute
      if (spaceLeft < colLen + 1) hasEnoughSpace = FALSE;
      spaceNeeded += (colLen + 1);
      if (hasEnoughSpace)
      {
        str_cpy_all(proxyPtr, colName, colLen);
        str_cpy_all(proxyPtr+colLen, " ", 1);
        proxyPtr += (colLen + 1);
        spaceLeft -= (colLen + 1);
      }

      heap_.deallocateMemory(colName);
    }

    // get Dataype TEXT FORMAT attribute
    outdesc->getDescItemPtr(entry, SQLDESC_TEXT_FORMAT, &name, &nameLen);
    if (name != NULL)
    {
      // Write Datatype attribute
      if (spaceLeft < nameLen + 1) hasEnoughSpace = FALSE;
      spaceNeeded += nameLen + 1;
      if (hasEnoughSpace)
      {
        str_cpy_all(proxyPtr, name, nameLen);
        str_cpy_all(proxyPtr + nameLen, " ", 1);
        proxyPtr += (nameLen + 1);
        spaceLeft -= (nameLen + 1);
      }
    }

    // get HEADING attribute
    outdesc->getDescItemPtr(entry, SQLDESC_HEADING, &name, &nameLen);
    if ((name != NULL) && (str_len(name) != 0))
    {
      // quotedHeading will be quoted string format i.e., the string will be
      // in single quotes and also any quotes in the string are doubled
      char *quotedHeading = toQuotedString(name, nameLen, &heap_);
      Lng32 quotedHeadLen = str_len(quotedHeading);

      // Write HEADING attribute
      if (spaceLeft < quotedHeadLen + 18) hasEnoughSpace = FALSE;
      spaceNeeded += (quotedHeadLen + 18);
      if (hasEnoughSpace)
      {
        str_cpy_all(proxyPtr, "HEADING _ISO88591", 17);
        str_cpy_all(proxyPtr+17, quotedHeading, quotedHeadLen);
        str_cpy_all(proxyPtr+17+quotedHeadLen, " ", 1);
        proxyPtr += (quotedHeadLen + 18);
        spaceLeft -= (quotedHeadLen + 18);
      }

      heap_.deallocateMemory(quotedHeading);
    }

    // Write "NOT NULL" attribute
    Lng32 nullable;
    outdesc->getDescItem(entry, SQLDESC_NULLABLE, &nullable, NULL, 0, NULL, 0);
    if (nullable == 0)
    {
      if (spaceLeft < 8) hasEnoughSpace = FALSE;
      spaceNeeded += 8;
      if (hasEnoughSpace)
      {
        str_cpy_all(proxyPtr, "NOT NULL", 8);
	proxyPtr += 8;
	spaceLeft -= 8;
      }
    }

    if (entry == expr->getNumEntries())
    {
      // This is last entry, so append the suffix
      if (spaceLeft < suffixLen)
        hasEnoughSpace = FALSE;
      spaceNeeded += suffixLen;
      if (hasEnoughSpace)
      {
        str_cpy_all(proxyPtr, suffix, suffixLen);
	proxyPtr += suffixLen;
	spaceLeft -= suffixLen;
      }
    }
    else
    {
      // Add ','
      if (spaceLeft < 2) hasEnoughSpace = FALSE;
      spaceNeeded += 2;
      if (hasEnoughSpace)
      {
        str_cpy_all(proxyPtr, ", ", 2);
        proxyPtr += 2;
        spaceLeft -= 2;
      }
    }
  }

  // Set the required space size if asked.
  if (spaceRequired) *spaceRequired = spaceNeeded;

  // Clean up
  outdesc->dealloc();
  NADELETE(outdesc, Descriptor, &heap_);

  return SUCCESS;
}

RETCODE Statement::getRSProxySyntax(char *proxy, Lng32 maxlength,
                                    Lng32 *spaceRequired)
{
  return getProxySyntax(proxy, maxlength, spaceRequired,
                        "SELECT * FROM TABLE ( SP_RESULT_SET ( ", " ) )");
}

RETCODE Statement::getExtractConsumerSyntax(char *proxy, Lng32 maxlength,
                                            Lng32 *spaceRequired)
{
  const char *prefix =
    "SELECT * FROM TABLE(EXTRACT_SOURCE('ESP', '%s', '%s', ";
  const char *suffix = ") )";
  return getProxySyntax(proxy, maxlength, spaceRequired, prefix, suffix);
}

#ifdef _DEBUG
void Statement::StmtPrintf(const char *formatString, ...) const
{
  if (!stmtDebug_)
    return;

  FILE *f = stdout;
  va_list args;
  va_start(args, formatString);
  fprintf(f, "[STMT] ");
  vfprintf(f, formatString, args);
  fprintf(f, "\n");
  fflush(f);
}
#endif
/******************************************************************************
    Method: Statement::doesUninitializedMvExist

    Description:       
        Any time the statement is executed, check the list to see if
        any mvs are still uninitialized.  If they are initialized, remove
        them from the list.

        If one uninitialized mv is found, return immediately with error
        since this statement cannot be executed.

    Parameters:
        char **pMvName (OUTPUT)
            - this parameter will be set to the name of the uninitialized
              mv if it is found.

        ComDiagsArea &diagsArea                   
            - diags area for error messages              

    Return:
        - return TRUE if an uninitialized mv is found          
                         
******************************************************************************/
NABoolean 
Statement::doesUninitializedMvExist( char **pMvName,
                                     ComDiagsArea &diagsArea )
{  
   NABoolean bUninitializedMvExists = FALSE; // assume none exist   
  
   UninitializedMvName *uninitializedMvList = NULL;
   const short uninitializedMvCount = root_tdb->uninitializedMvCount();

   uninitializedMvList = root_tdb->uninitializedMvList();

   // if the list is NULL, the return value will show that none exist.
   if( uninitializedMvList )
   {
       // for each name in the uninitializedMvList
       for( short i = 0; i < uninitializedMvCount; i++ )
       {           
           UninitializedMvName currentMv = uninitializedMvList[ i ];

           if( isUninitializedMv( currentMv.getPhysicalName(),
                                  currentMv.getAnsiName(), 
                                  diagsArea ) )
           {           
               // point output to name in root_tdb
               (*pMvName) = uninitializedMvList[ i ].getAnsiName(); 
               bUninitializedMvExists = TRUE;
               break; // exit loop since at least one is found
           } 
           
       }    
   }   
   return bUninitializedMvExists;
}
/******************************************************************************
    Method: Statement::isUninitializedMv

    Description:
        Determine whether a table in the statement is an uninitialized mv.  
        This information is gathered from the ExRcb object.

    Parameters:
        char * physicalName
            - table location.  used to get rfork info
            
        const char *ansiName             
            - table ansi name.  used for error reporting

        ComDiagsArea &diagsArea                   
            - diags area for error messages
              
    Return:
        - return TRUE if this mv exists but is uninitialized.             
                                
******************************************************************************/
NABoolean 
Statement::isUninitializedMv( const char * physicalName,
                              const char * ansiName,
                              ComDiagsArea &diagsArea )
{
    return FALSE;
}

void Statement::buildConsumerQueryTemplate()
{
  if (extractConsumerQueryTemplate_ == NULL)
  {
    Lng32 len = 1000;
    NABoolean done = FALSE;
    Lng32 spaceRequired = 0;
    while (!done)
    {


      // add one for NULL terminator
      extractConsumerQueryTemplate_ = (char *)heap_.allocateMemory(len + 1);

      // Now we call a function to generate the consumer syntax string.
      // The function returns a string WITHOUT a null terminator. The
      // number of bytes required for the full string (not including
      // the null terminator) is returned in the output parameter 
      // spaceRequired.
      RETCODE rc = getExtractConsumerSyntax(extractConsumerQueryTemplate_,
                                            len,
                                            &spaceRequired);
      ex_assert(rc == SUCCESS,
                "Unexpected error from getExtractConsumerSyntax");

      if (spaceRequired > len)
      {
        len = spaceRequired;
        heap_.deallocateMemory(extractConsumerQueryTemplate_);
        extractConsumerQueryTemplate_ = NULL;
      }
      else
      {
        extractConsumerQueryTemplate_[spaceRequired] = 0;
        done = TRUE;
      }
    }
  }
}

Lng32 Statement::getConsumerQueryLen(ULng32 index)
{
  // First build the consumer query template
  buildConsumerQueryTemplate();
  
  // Minimum length will include a null terminator so initialize the
  // result to 1
  Lng32 result = 1;

  const char *tmpl = extractConsumerQueryTemplate_;
  const char *phandle = statementGlobals_->getExtractEspPhandleText(index);
  const char *key = statementGlobals_->getExtractSecurityKey();

  if (phandle == NULL)
    phandle = "";
  if (key == NULL)
    key = "";

  Lng32 reqdLen = str_len(tmpl)
    + str_len(phandle)
    + str_len(key)
    - 4  // to account for the "%s" format specifiers
    + 1; // to account for the null terminator
  result = reqdLen;

  return result;
}

void Statement::getConsumerQuery(ULng32 index, char *buf, Lng32 buflen)
{
  if (buflen < 1)
    return;

  // First build the consumer query template
  buildConsumerQueryTemplate();

  buf[0] = 0;

  const char *tmpl = extractConsumerQueryTemplate_;
  const char *phandle = statementGlobals_->getExtractEspPhandleText(index);
  const char *key = statementGlobals_->getExtractSecurityKey();

  if (phandle == NULL)
    phandle = "";
  if (key == NULL)
    key = "";

  Lng32 reqdLen = str_len(tmpl)
    + str_len(phandle)
    + str_len(key)
    - 4  // to account for the "%s" format specifiers
    + 1; // to account for the null terminator
  ex_assert(buflen >= reqdLen, "Consumer query buffer too small");
  str_sprintf(buf, tmpl, phandle, key);
}

Lng32 Statement::getConsumerCpu(ULng32 index)
{
  Lng32 result = -1;
  short cpu = statementGlobals_->getExtractEspCpu(index);
  Lng32 nodeNumber = statementGlobals_->getExtractEspNodeNumber(index);
  if (cpu >= 0 && nodeNumber >= 0)
  {
    result = (nodeNumber << 8);
    result += (cpu & 0x00ff);
  }
  return result;
}

         
Lng32 Statement::setParentQid(char *queryId)
{
  Lng32 len = 0;
  if (queryId != NULL)
  {
    len = str_len(queryId);
    if (len < ComSqlId::MIN_QUERY_ID_LEN)
      return -CLI_INVALID_ATTR_VALUE;
    if (len < 4 || (len > 4 && str_cmp((const char *)queryId, COM_SESSION_ID_PREFIX, 4) != 0))
      return -CLI_INVALID_ATTR_VALUE;
  }
  if (parentQid_)
    NADELETEBASIC(parentQid_, &heap_);
  if (queryId != NULL)
  {
    parentQid_ = new(&heap_) char[len+1];
    str_cpy_all(parentQid_, queryId, len);
    parentQid_[len] = '\0';
  }
  else
  {
    parentQid_ = NULL;
    len = 0;
  }
  if (stmtStats_ && stmtStats_->getMasterStats() != NULL)
    stmtStats_->getMasterStats()->setParentQid(parentQid_, len);
  return 0;
}

void Statement::setParentQidSystem(char *parentQidSystem)
{
  Lng32 len = 0;
  if (parentQidSystem != NULL)
  {
    len = str_len(parentQidSystem);
    str_cpy_all(parentQidSystem_, parentQidSystem, len);
    parentQidSystem_[len] = '\0';
  }
  else
    parentQidSystem_[0] = '\0'; 
  if (stmtStats_ && stmtStats_->getMasterStats() != NULL)
    stmtStats_->getMasterStats()->setParentQidSystem(parentQidSystem_, len);
}

char *Statement::getParentQid()
{
  char *parentQid;
  if (parentQid_ != NULL)
    parentQid = parentQid_;
  else
  {
    if (context_->getSessionDefaults())
      parentQid = context_->getSessionDefaults()->getParentQid();
    else
      parentQid = NULL;
  }
  return parentQid;
}

char *Statement::getParentQidSystem()
{
  char *parentQidSystem;
  if (parentQidSystem_[0] != '\0')
    parentQidSystem = parentQidSystem_;
  else
  {
    if (context_->getSessionDefaults())
      parentQidSystem = context_->getSessionDefaults()->getParentQidSystem();
    else
      parentQidSystem = NULL;
  }
  return parentQidSystem;
}

Int64 Statement::getExeStartTime()
{
  ExStatisticsArea *statsArea;
  ExMasterStats *masterStats;
  statsArea = getStatsArea();
  
  if (statsArea != NULL && (masterStats = statsArea->getMasterStats()) != NULL)
      return masterStats->getExeStartTime();
  else
      return -1;
}

void Statement::setExeStartTime(Int64 exeStartTime)
{
   if (exeStartTime != -1)
      aqrInitialExeStartTime_ = exeStartTime;
} 

Lng32 Statement::initStrTarget(SQLDESC_ID * sql_source,
                               ContextCli &currContext,
                               ComDiagsArea &diags,
                               StrTarget &strTarget)
{
  if (! sql_source)
    return 0;

  if (sql_source->name_mode == string_data)
    {
      CharInfo::CharSet externalCharset =
              CharInfo::getCharSetEnum(sql_source->charset);
      CharInfo::CharSet internalCharset = CharInfo::UTF8;
      ComDiagsArea *diagsPtr = &diags;


      strTarget.init((char*)sql_source->identifier, 
		     sql_source->identifier_len, 
                     CharInfo::getFSTypeFixedChar(externalCharset),
                     externalCharset,
                     internalCharset,
                     currContext.exCollHeap(),
                     diagsPtr);
    }
  else
    {
      Descriptor * desc = currContext.getDescriptor(sql_source);
      
      /* descriptor must exist */
      if (!desc)
	{
	  diags << DgSqlCode(-CLI_DESC_NOT_EXISTS);
	  return -CLI_DESC_NOT_EXISTS;
	}
      
      strTarget.init(desc, 1);
    }
  
  if (!strTarget.getStr())
    {
      diags << DgSqlCode(-CLI_STMT_NOT_PREPARED);
      return -CLI_STMT_NOT_PREPARED;
    }
  copyInSourceStr(strTarget.getStr(), (octetLen(strTarget.getStr(), strTarget.getIntCharSet())), strTarget.getIntCharSet());
  return 0;
}

NABoolean Statement::updateChildQid()
{
  NABoolean parentIsCanceled = FALSE;
  StatsGlobals *statsGlobals = cliGlobals_->getStatsGlobals();
  
  if (statsGlobals != NULL && uniqueStmtId_ != NULL && parentQid_ != NULL &&
      getStatsArea() != NULL && stmtStats_ != NULL && stmtStats_->updateChildQid())
  {
    int error = statsGlobals->getStatsSemaphore(cliGlobals_->getSemId(),
          cliGlobals_->myPin());
    StmtStats *ss = statsGlobals->getMasterStmtStats(parentQid_, str_len(parentQid_), RtsQueryId::ANY_QUERY_);
    if (ss != NULL)
    {
      ExMasterStats *parentMasterStats = ss->getMasterStats();
      if (parentMasterStats)
      {
        parentMasterStats->setChildQid(uniqueStmtId_, uniqueStmtIdLen_);
        if (parentMasterStats->getCanceledTime() != -1)
          parentIsCanceled = TRUE;
      }
    }
    statsGlobals->releaseStatsSemaphore(cliGlobals_->getSemId(),cliGlobals_->myPin());
  }
  return parentIsCanceled;
}
/*
// make the context's stats point to this statement's stats. 
      // Context points to the most recent executed statement's
      // stat area so later a getStatistics CLI call without a
      // statement ID can return it.
*/
void Statement::updateStatsAreaInContext()
{
  ExStatisticsArea *statsArea;
  ComTdb::CollectStatsType statsType;
  ExMasterStats *masterStats;
  statsArea = getStatsArea();
  if (stmtStats_ != NULL && 
      statsArea && 
      ((statsType = statsArea->getCollectStatsType()) != (Int32)SQLCLIDEV_NO_STATS) && 
      stmt_type == Statement::DYNAMIC_STMT)
  {
    if (statsType == (Int32)SQLCLIDEV_ALL_STATS)
    {
      if ((masterStats = statsArea->getMasterStats()) != NULL)
      {
        NADELETE(masterStats, ExMasterStats, masterStats->getHeap());
        statsArea->setMasterStats(NULL);
      }
    }
    if (statsArea->getMasterStats() == NULL)
	{
	  ExMasterStats * ems = new(context_->exHeap())
	    ExMasterStats(context_->exHeap());
	  if (stmtStats_->getMasterStats())
	    ems->copyContents(stmtStats_->getMasterStats());
          ems->setCollectStatsType(getRootTdb()->getCollectStatsType());
	  statsArea->setMasterStats(ems);
	}
    context_->setStatsArea(getStatsArea(), FALSE, (cliGlobals_->getStatsGlobals() != NULL));
  }
}

Lng32 Statement::setChildQueryInfo(ComDiagsArea *diagsArea, char * uniqueQueryId,
        Lng32 uniqueQueryIdLen,
        SQL_QUERY_COST_INFO *query_cost_info,
        SQL_QUERY_COMPILER_STATS_INFO *comp_stats_info)
{
  NAHeap *heap = stmtHeap();
  
  if (uniqueQueryId == NULL || query_cost_info == NULL || comp_stats_info == NULL)
  {
    if (diagsArea != NULL)
     *diagsArea << DgSqlCode(-CLI_INVALID_ATTR_VALUE);
    return ERROR;
  }
  if (childQueryId_ != NULL)
  {
    NADELETEBASIC(childQueryId_, heap);
  }
  childQueryId_ = new (heap) char[uniqueQueryIdLen+1];
  str_cpy_all(childQueryId_, uniqueQueryId, uniqueQueryIdLen);
  childQueryId_[uniqueQueryIdLen] = '\0';
  childQueryIdLen_ = uniqueQueryIdLen;
  if (childQueryCostInfo_ != NULL)
  {
    NADELETEBASIC(childQueryCostInfo_, heap);
  }
  childQueryCostInfo_ = new (heap) SQL_QUERY_COST_INFO;
  str_cpy_all((char *)childQueryCostInfo_, (const char *)query_cost_info, sizeof(SQL_QUERY_COST_INFO));
  if (childQueryCompStatsInfo_ != NULL)
  {
    NADELETEBASIC(childQueryCompStatsInfo_, heap);
  }
  childQueryCompStatsInfo_ = new (heap) SQL_QUERY_COMPILER_STATS_INFO;
  str_cpy_all((char *)childQueryCompStatsInfo_, (const char *)comp_stats_info, sizeof(SQL_QUERY_COMPILER_STATS_INFO));
  return SUCCESS;
}

Lng32 Statement::getChildQueryInfo(ComDiagsArea &diagsArea, char * uniqueQueryId,
     Lng32 uniqueQueryIdMaxLen,
     Lng32 * uniqueQueryIdLen,
     SQL_QUERY_COST_INFO *query_cost_info,
     SQL_QUERY_COMPILER_STATS_INFO *comp_stats_info)
{
  if (childQueryId_ == NULL)
  {
     diagsArea << DgSqlCode(-EXE_RTS_QID_NOT_FOUND);
     return ERROR;
  }
  if (childQueryIdLen_ > uniqueQueryIdMaxLen || uniqueQueryId == NULL ||
      uniqueQueryIdLen == NULL)
  {
     diagsArea << DgSqlCode(-CLI_BUFFER_TOO_SMALL);
     return ERROR;
  }
  str_cpy_all(uniqueQueryId, (const char *)childQueryId_, childQueryIdLen_);
  *uniqueQueryIdLen = childQueryIdLen_;
  if (childQueryCostInfo_ != NULL && query_cost_info != NULL)
    str_cpy_all((char *)query_cost_info, (const char *)childQueryCostInfo_, 
          sizeof(SQL_QUERY_COST_INFO));
  if (childQueryCompStatsInfo_ != NULL && comp_stats_info != NULL)
    str_cpy_all((char *)childQueryCompStatsInfo_, (const char *)comp_stats_info,
            sizeof(SQL_QUERY_COMPILER_STATS_INFO));
  return SUCCESS;
}

