/* -*-C++-*-
// @@@ 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 @@@
 *****************************************************************************
 *
 * File:         Cli.C
 * Description:  CLI procedures body.
 *
 * Created:      7/10/95
 * Language:     C++
 *
 *
 *
 *
 *****************************************************************************
 */

#include "Platform.h"


#include "ComCextdecs.h"
#include "cli_stdh.h"
#include "exp_stdh.h"
#include "ex_transaction.h"
#include "exp_expr.h"
#include "exp_clause_derived.h"
#include "exp_function.h"
#include "ExpLOB.h"
#include "ExpLOBinterface.h"
#include "sql_id.h"
#include "ExStats.h"
#include "ComTdb.h"
#include "ComTdbSplitTop.h"
#include "ex_root.h"
#include "ex_exe_stmt_globals.h"
#include "ex_frag_rt.h"
#include "NLSConversion.h"
#include "ExExeUtil.h"
#include <stdarg.h>

#include "NAString.h"

#include "Cli.h"
#include "ComRtUtils.h"
#include "ComSqlId.h"

#include "ComRegAPI.h"

#include "ExExplain.h"
#include "ExplainTuple.h"

#include "CmpMessage.h"
#include "ExSqlComp.h"

#include "logmxevent.h"

#include <time.h>

#include "fs/feerrors.h"

#include "csconvert.h"

#include "ExRsInfo.h"

#include "seabed/ms.h"

#include "dtm/tm.h"

#include "CmpContext.h"
#include "LmLangManager.h"
#include "LmLangManagerC.h"
#include "LmLangManagerJava.h"
#include "LmRoutine.h"
#include "CmpDDLCatErrorCodes.h"
#include "ExpLOBaccess.h"

#define DISPLAY_DONE_WARNING 1032
extern Lng32 getTotalTcbSpace(char * tdb, char * otherInfo, 
			     char * parentMemory);


StrTarget::StrTarget() :
  heap_(NULL),
  str_(NULL),
  externalCharset_(CharInfo::UnknownCharSet),
  internalCharset_(CharInfo::UnknownCharSet),
  cnvExternalCharset_(cnv_UnknownCharSet),
  cnvInternalCharset_(cnv_UnknownCharSet)
{}
StrTarget::StrTarget(Descriptor *desc, Lng32 entry) :
     heap_(NULL),
     str_(NULL),
     externalCharset_(CharInfo::UnknownCharSet),
     internalCharset_(CharInfo::UnknownCharSet),
     cnvExternalCharset_(cnv_UnknownCharSet),
     cnvInternalCharset_(cnv_UnknownCharSet)
{
  init(desc, entry);
}
void StrTarget::init(Descriptor *desc, Lng32 entry)
{
  Lng32 sourceLen, sourceType, externalCharset, internalCharset;
  CollHeap *heap = desc->getContext()->exCollHeap();
  ComDiagsArea *diagsArea = desc->getContext()->getDiagsArea();
  char * source = desc->getVarData(entry);
  desc->getDescItem(entry, SQLDESC_TYPE_FS, &sourceType, 0, 0, 0, 0);
  desc->getDescItem(entry, SQLDESC_OCTET_LENGTH, &sourceLen, 0, 0, 0, 0);
  desc->getDescItem(1, SQLDESC_CHAR_SET, &externalCharset, 0, 0, 0, 0);
  
  // If ISO_MAPPING is equal to the charset in the descriptor,
  // then process as usual.  Otherwise, convert
  // the string from the input charset to ISO_MAPPING (on NSK platform)
  // -- On SeaQuest platform, always convert to UTF8 (or keep as is if
  // already in UTF8 or UCS2/UTF16).
  if (externalCharset == CharInfo::UCS2)
    internalCharset = CharInfo::UCS2;
  else
    internalCharset = CharInfo::UTF8;

  init(source,
       sourceLen,
       sourceType,
       externalCharset,
       internalCharset,
       heap,
       diagsArea);
}


void StrTarget::init(char  *source,
                     Lng32 sourceLen,
                     Lng32 sourceType,
                     Lng32 externalCharset,
                     Lng32 internalCharset,
                     CollHeap *heap,
                     ComDiagsArea *&diagsArea)
{
  externalCharset_ = externalCharset;
  internalCharset_ = internalCharset;
  heap_ = heap;

  cnvExternalCharset_ = convertCharsetEnum(externalCharset_);
  cnvInternalCharset_ = convertCharsetEnum(internalCharset_);
  
  if (sourceType < REC_MIN_CHARACTER || sourceType > REC_MAX_CHARACTER)
    return;
  
  // How many bytes will we need after conversion?
  // Add one char length for the NULL terminator
  Int32 intStrLen = CharInfo::getMaxConvertedLenInBytes(
                                  (CharInfo::CharSet)externalCharset_,
                                  sourceLen,
                                  (CharInfo::CharSet)internalCharset_) + 
                    CharInfo::minBytesPerChar(
                                  (CharInfo::CharSet)internalCharset_);
  str_ = (char *)heap_->allocateMemory(intStrLen);

  short retCode = convDoIt( source,
                            sourceLen,
                            (short) sourceType,
                            0,
                            externalCharset_,
                            str_,
                            intStrLen,
                            CharInfo::getFSTypeANSIChar((CharInfo::CharSet) internalCharset_),
                            0,
                            internalCharset_,
                            NULL,
                            0,
                            heap_,
                            &diagsArea);
  if (retCode != ex_expr::EXPR_OK)
    {
      heap_->deallocateMemory(str_);
      str_ = NULL;
    }
}

static inline NABoolean isERROR(Lng32 retcode)
{
  return (retcode < 0);
}

static inline NABoolean isWARNING(Lng32 retcode)
{
// 100 is EOF, not WARNING
  return ((retcode > 0) && (retcode != SQL_EOF));
}

static inline NABoolean isSUCCESS(Lng32 retcode)
{
  return (retcode == 0);
}

static inline NABoolean isEOF(Lng32 retcode)
{
  return (retcode == 100);
}

static Lng32 SQLCLI_ReturnCode(ContextCli * context,
			      Lng32 retcode)
{
  return (context != NULL && isERROR(retcode) ?
          context->diags().mainSQLCODE() :
          retcode);
}

// Move this method to Statement class. TBD.
static Lng32 SQLCLI_Prepare_Setup_Pre(
     ContextCli &currContext,
     Statement * stmt,
     ULng32 flags
     )
{

  Int64 compStartTime = NA_JulianTimestamp();
  StmtStats * stmtStats = stmt->getStmtStats();

  if (stmtStats != NULL)
    {
      if (stmtStats->getMasterStats() != NULL)
	{
	  stmtStats->getMasterStats()->setElapsedStartTime(compStartTime);
	  stmtStats->getMasterStats()->setCompStartTime(compStartTime);
	  
	  if (flags & PREPARE_STANDALONE_QUERY) // standalone query
	    stmtStats->getMasterStats()->setIsPrepAndExec(TRUE);
	  else
	    {
	      stmtStats->getMasterStats()->setIsPrepAndExec(FALSE);
	      stmtStats->getMasterStats()->setIsPrepare(TRUE);
	    }
	}
    }   
  
  return 0;
}

static Lng32 SQLCLI_Prepare_Setup_Post(
     ContextCli &currContext,
     Statement * stmt,
     ULng32 flags
     )
{
  StmtStats * stmtStats = stmt->getStmtStats();
  Int64 compEndTime = stmt->getCompileEndTime();
  ExMasterStats *masterStats;
  ex_root_tdb *rootTdb = NULL;
  if (stmtStats != NULL)
  {
     if ((masterStats = stmtStats->getMasterStats()) != NULL)
     {
        masterStats->setCompEndTime(compEndTime);
        rootTdb = (stmt ? stmt->getRootTdb() : NULL);
        if (rootTdb)
            stmtStats->getMasterStats()->setInvalidationKeys(
                 currContext.getCliGlobals(), rootTdb->getSikInfo(),
                 rootTdb->getNumObjectUIDs(), rootTdb->getObjectUIDs());

        if (rootTdb != NULL && rootTdb->getCollectStatsType() != ComTdb::NO_STATS)
	{
           masterStats->setCollectStatsType(rootTdb->getCollectStatsType());
	   if (rootTdb->getQueryCostInfo())
               masterStats->queryCostInfo() =
		  *(rootTdb->getQueryCostInfo());
	   if (rootTdb->getCompilerStatsInfo())
               masterStats->compilerStatsInfo() =
		  *(rootTdb->getCompilerStatsInfo());
	      
	   if (rootTdb->qCacheInfoIsClass() &&
		  rootTdb->qcInfo())
           {
              masterStats->setCompilerCacheHit
		    (rootTdb->qcInfo()->cacheWasHit());
	   }
	   masterStats->setQueryType((Int16)rootTdb->getQueryType(),
                                rootTdb->getSubqueryType());
	      // detect if this query is sequential at top. If
	      // the root doesn't have an ESP exchange as its child,
	      // then it is sequential at top. A FirstN operator could
	      // also be between root and ESP exchange, that is
	      // not considered sequential.
	   UInt32 numOfRootEsps = 0;
	   const ComTdb * st = NULL;
	   if (((rootTdb->getChild(0)->getNodeType() == ComTdb::ex_FIRST_N) &&
		   ((st=rootTdb->getChild(0)->getChild(0))->getNodeType() == ComTdb::ex_SPLIT_TOP) &&
		   (rootTdb->getChild(0)->getChild(0)->getChild(0)->getNodeType() == ComTdb::ex_SEND_TOP)) ||
		  (((st=rootTdb->getChild(0))->getNodeType() == ComTdb::ex_SPLIT_TOP) &&
		   (rootTdb->getChild(0)->getChild(0)->getNodeType() == ComTdb::ex_SEND_TOP)))
           {
              numOfRootEsps = ((ComTdbSplitTop*)st)->getBottomNumParts();
           }

	   masterStats->numOfRootEsps() = numOfRootEsps;
	   if (rootTdb->transactionReqd())
		masterStats->setXnReqd(TRUE);

	   masterStats->setElapsedEndTime(compEndTime);
	   ExStatisticsArea * newStats = new (currContext.exHeap())
           ExStatisticsArea(currContext.exHeap(), 0, 
                  rootTdb->getCollectStatsType(),
                  rootTdb->getCollectStatsType());
           newStats->setStatsEnabled(TRUE);
	   ExMasterStats * ems = new(currContext.exHeap())
	   ExMasterStats(currContext.exHeap());
	   ems->copyContents(masterStats);
           ems->setCollectStatsType(rootTdb->getCollectStatsType());
	   newStats->setMasterStats(ems);
           currContext.setStatsArea(newStats, TRUE, FALSE);
        }
        else
        {
           masterStats->setCollectStatsType(ComTdb::NO_STATS);
           if (rootTdb != NULL)
           {
	      if (rootTdb->getCompilerStatsInfo())
                   masterStats->compilerStatsInfo() =
		       *(rootTdb->getCompilerStatsInfo());
	      masterStats->setQueryType((Int16)rootTdb->getQueryType(),
                                rootTdb->getSubqueryType());
           }
        }
     }
  }
  return 0;
}
  
//
// A helper function to check whether SQL access is currently allowed.
// The UDR server is the only SQL application that disables SQL access
// from time to time. This is done in order to enforce a policy where
// a UDR registered with the NO SQL attribute is not allowed to access
// SQL/MX.
//
static Lng32 CheckNOSQLAccessMode(CliGlobals &cliGlobals)
{
  // rare error condition
  if (!cliGlobals.sqlAccessAllowed())
  {
    cliGlobals.setUdrAccessModeViolation(TRUE);
    ContextCli *context = cliGlobals.currContext();
    if (context)
    {
      ComDiagsArea &diags = context->diags();
      diags << DgSqlCode(- CLI_NO_SQL_ACCESS_MODE_VIOLATION);
    }
    return - CLI_NO_SQL_ACCESS_MODE_VIOLATION;
  }
  return SUCCESS;
}

static Lng32 CliPrologue(CliGlobals   * cliGlobals,
			const SQLMODULE_ID * module)
{
  Lng32 retcode;
  
  ContextCli * context = cliGlobals->currContext();
  ComDiagsArea & diags = context->diags();

  // If this is not a recursive CLI call, inherit the current
  // process transid into this context. (We don't want to
  // inherit the current process transid if this is a recursive
  // CLI call. A recursive CLI call should always be done in
  // the transid of its calling context, and the process transid
  // might be different. This can happen, for example, if we are
  // in a recursive CLI call underneath FILE_COMPLETE_.)
  Lng32 numOfCliCalls = context->getNumOfCliCalls(); 
  if ((numOfCliCalls == 1) ||
      ((numOfCliCalls == 2) && (cliGlobals->isESPProcess())))
    {
      ExTransaction *exTransaction = context->getTransaction();
      if (exTransaction != NULL)
      {
          retcode =  exTransaction->inheritTransaction();
         if (isERROR(retcode))
         {
            diags << DgSqlCode(- CLI_BEGIN_TRANSACTION_ERROR);
            return ERROR;
         }
      }
    }

  if ((context->getVersionOfCompiler() != COM_VERS_COMPILER_VERSION) && (numOfCliCalls >1 ))
    {
      short index = 0;
      cliGlobals->setSavedVersionOfCompiler(context->getVersionOfCompiler());
      context->setOrStartCompiler(COM_VERS_COMPILER_VERSION,NULL, index);
    }

  // Initialize session defaults.
  // if session defaults have not been read from the default table,
  // read them now.
  if (context->getSessionDefaults() == NULL)
    {
      retcode = context->initializeSessionDefaults();
      if (isERROR(retcode))
        return SQLCLI_ReturnCode(cliGlobals->currContext(),retcode);
    }

  return SUCCESS;
}

static Lng32 CliEpilogue(CliGlobals * cliGlobals,
                        SQLSTMT_ID * currentSqlStmt,
			Lng32         inRetcode = 0)
{
  ContextCli * context = cliGlobals->currContext();

  // Validate the current process transid only if this is not
  // a recursive CLI call. (It is legitimate, for example,
  // for the process to not have a transid, or to have a
  // different transid than the current context, if we are
  // in a recursive CLI call inside FILE_COMPLETE_.)

  Lng32 numOfCliCalls = context->getNumOfCliCalls(); 
  if (numOfCliCalls == 1)
    {
      short retcode = context->getTransaction()->validateTransaction();

      if (isERROR(retcode))
        {
          ComDiagsArea & diags = context->diags();
          return diags.mainSQLCODE();
        }
    }
#if 0
  if ((cliGlobals->getSavedVersionOfCompiler() != context->getVersionOfCompiler()) && (numOfCliCalls > 1 ))
    {
      short index;
      cliGlobals->setSavedVersionOfCompiler(context->getVersionOfCompiler());
      context->setOrStartCompiler(cliGlobals->getSavedVersionOfCompiler(),NULL, index);
    }
#endif
  if (inRetcode == SQL_EOF)
    return SQL_EOF;

  if (isERROR(inRetcode)) 
    {
      return SQLCLI_ReturnCode(cliGlobals->currContext(),inRetcode);
    }

  // if there's stuff in diags, it's a warning, and we need to 
  // pass the warning code out
  if (context->diags().getNumber())
    return context->diags().mainSQLCODE();

  return SQLCLI_ReturnCode(context,inRetcode);
}

// Set the pointers for the host variable and its indicator host variable in 
// pairs. Note, we are setting only the addresses for the host variables in
// the first row of the Rowset. The other are implicitely set by the binding
// style.
Lng32 local_SetDescPointers(/*IN*/       Descriptor * desc,
                           /*IN*/             Lng32   starting_entry,
                           /*IN*/             Lng32   num_ptr_pairs,
                           /*IN*/          va_list * ap,
                           /*IN*/ SQLCLI_PTR_PAIRS   ptr_pairs[])
{
  ContextCli *context = desc->getContext();

  if ((!desc) ||
      (num_ptr_pairs < 0) ||
      (starting_entry <= 0) ||
      ((num_ptr_pairs + starting_entry - 1) > desc->getUsedEntryCount()))
    {
      ComDiagsArea & diags = context->diags();

      diags << DgSqlCode(-CLI_INTERNAL_ERROR);
      return SQLCLI_ReturnCode(context, -CLI_INTERNAL_ERROR);
    }

  for (Lng32 entry=starting_entry, i = 0; entry < starting_entry+num_ptr_pairs;
       entry++, i++)
    {
      // need to re-order this to avoid possible problems with not setting
      // the data area (i.e. VAR_PTR) last.
      char * vp, * ip;
      if (*ap) {
        vp = va_arg(*ap, char *);
        ip = va_arg(*ap, char *);
      }
      else {
        vp = (char *)ptr_pairs[i].var_ptr;
        ip = ptr_pairs[i].ind_ptr == (void *)-1 ? 0 : (char *)ptr_pairs[i].ind_ptr;
      }
      
     if(ip && (context->boundsCheckMemory(ip, desc->getIndLength(entry))) ||
        (context->boundsCheckMemory(vp, desc->getVarDataLength(entry))))
       return SQLCLI_ReturnCode(context,-CLI_USER_MEMORY_IN_EXECUTOR_SEGMENT);
       
     desc->setDescItem(entry, SQLDESC_IND_PTR, (Long)ip, 0);
     desc->setDescItem(entry, SQLDESC_VAR_PTR, (Long)vp, 0);
    }
  
  return SUCCESS;
}

// Some CLI calls deal with numeric host variables without there being
// an input/output expression. So far, the CLI assumed those variables
// to be "long" C variables. The methods here are a slight improvement
// but no perfect solution. They handle a few more cases.

// Retrieve information about the pointers and lengths of a numeric host var
// for the first row of the RowSet. To get the addresses for other row sets, 
// the member function, getDescPointers should be used.

static Lng32 getNumericHostVarInfo(Descriptor *desc,
                                  Lng32 desc_entry,
                                  // output parameters
                                  void *&hv_ptr,
                                  Lng32 &hv_length,
                                  Lng32 &hv_type,
                                  void *&ind_ptr,
                                  Lng32 &ind_length,
                                  Lng32 &ind_type)
{
  Lng32 retcode = desc->getDescItem(desc_entry,
				   SQLDESC_VAR_PTR,
				   (Lng32*) &hv_ptr,
				   NULL, 0, NULL, 0);
  if (retcode != 0)
    return SQLCLI_ReturnCode(desc->getContext(),retcode);

  retcode = desc->getDescItem(desc_entry,
			      SQLDESC_LENGTH,
			      (Lng32*) &hv_length,
			      NULL, 0, NULL, 0);
  if (retcode != 0)
    return SQLCLI_ReturnCode(desc->getContext(),retcode);

  retcode = desc->getDescItem(desc_entry,
			      SQLDESC_TYPE_FS,
			      (Lng32*) &hv_type,
			      NULL, 0, NULL, 0);
  if (retcode != 0)
    return SQLCLI_ReturnCode(desc->getContext(),retcode);

  retcode = desc->getDescItem(desc_entry,
			      SQLDESC_IND_PTR,
			      (Lng32*) &ind_ptr,
			      NULL, 0, NULL, 0);
  if (retcode != 0)
    return SQLCLI_ReturnCode(desc->getContext(),retcode);

  // the host variable must have a scale of 0
  Lng32 hv_scale;
  retcode = desc->getDescItem(desc_entry,
			      SQLDESC_SCALE,
			      (Lng32*) &hv_scale,
			      NULL, 0, NULL, 0);
  if (retcode != 0)
    return SQLCLI_ReturnCode(desc->getContext(),retcode);
  // $$$$ Enable this after scale got initialized
  // if (hv_scale != 0)
  //   return -1;

  if (ind_ptr)
    {
      retcode = desc->getDescItem(desc_entry,
                                  SQLDESC_IND_TYPE,
                                  (Lng32*) &ind_type,
                                  NULL, 0, NULL, 0);
      if (retcode != 0)
        return SQLCLI_ReturnCode(desc->getContext(),retcode);

      switch (ind_type)
        {
        case REC_BIN16_SIGNED:
        case REC_BIN16_UNSIGNED:
          ind_length = 2;
          break;
        case REC_BIN32_SIGNED:
        case REC_BIN32_UNSIGNED:
          ind_length = 4;
          break;
        case REC_BIN64_SIGNED:
        case REC_BIN64_UNSIGNED:
          ind_length = 8;
          break;
        default:
          retcode = -1;
        }
    }
  return SQLCLI_ReturnCode(desc->getContext(),retcode);

  /* RS -- to be tested,debugged and re-enabled
  long retcode;
  short nullable;

  retcode = desc->getDescItemMainVarInfo(desc_entry,
                                         nullable,
                                         hv_type,
                                         hv_length,
                                         (void *)&hv_ptr,
                                         ind_type,
                                         ind_length,
                                         (void *)&ind_ptr);
  return SQLCLI_ReturnCode(desc->getContext(),retcode);
  */
}

static Lng32 InputValueFromNumericHostvar(Descriptor *desc,
                                         Lng32 desc_entry,
                                         Lng32 &value)
{
  void *hvPtr;
  Lng32  hvLength;
  Lng32  hvType;
  void *indPtr;
  Lng32  indLength;
  Lng32  indType;
  ex_expr::exp_return_type expRetcode;
  CollHeap * heap;
  ComDiagsArea * diagsArea;

  heap      = desc->getContext()->exCollHeap();
  diagsArea = desc->getContext()->getDiagsArea();

  Lng32 retcode = getNumericHostVarInfo(desc,
                                       desc_entry,
                                       hvPtr,
                                       hvLength,
                                       hvType,
                                       indPtr,
                                       indLength,
                                       indType);
  if (retcode)
    return SQLCLI_ReturnCode(desc->getContext(),retcode);

  expRetcode = convDoIt((char *) hvPtr,
                        hvLength,
                        (short) hvType,
                        0,
                        0,
                        (char *) &value,
                        (Lng32) sizeof(value),
                        REC_BIN32_SIGNED,
                        0,
                        0,
                        NULL,
                        0,
                        heap,
                        &diagsArea);
  if (expRetcode != ex_expr::EXPR_OK)
    return ERROR;
  if (indPtr)
    {
      // values coming in should not be NULL, just make
      // sure nobody passes in a NULL
      Lng32 userIndicatorVal;

      expRetcode = convDoIt((char *) indPtr,
                            indLength,
                            (short) indType,
                            0,
                            0,
                            (char *) &userIndicatorVal,
                            (Lng32) sizeof(userIndicatorVal),
                            REC_BIN32_SIGNED,
                            0,
                            0,
                            NULL,
                            0,
                            heap,
                            &diagsArea);
      
      if (expRetcode != ex_expr::EXPR_OK)
        return ERROR;
      if (userIndicatorVal)
        return ERROR; // user specified NULL or junk
    }

  return (SUCCESS);
}

static Lng32 OutputValueIntoNumericHostvar(Descriptor *desc,
                                          Lng32 desc_entry,
                                          Lng32 value)
{
  void *hvPtr;
  Lng32  hvLength;
  Lng32  hvType;
  void *indPtr;
  Lng32  indLength;
  Lng32  indType;
  ex_expr::exp_return_type expRetcode;
  CollHeap * heap;
  ComDiagsArea * diagsArea;
  ContextCli * context;

  context   = desc->getContext();
  heap      = context->exCollHeap();
  diagsArea = context->getDiagsArea();

  Lng32 retcode = getNumericHostVarInfo(desc,
                                       desc_entry,
                                       hvPtr,
                                       hvLength,
                                       hvType,
                                       indPtr,
                                       indLength,
                                       indType);
  if (retcode)
    return ERROR;

  if (hvType >= REC_MIN_NUMERIC && hvType <= REC_MAX_NUMERIC)
    {
      expRetcode = convDoIt((char *) &value,
                            (Lng32) sizeof(value),
                            REC_BIN32_SIGNED,
                            0,
                            0,
                            (char *) hvPtr,
                            hvLength,
                            (short) hvType,
                            0,
                            0,
                            NULL,
                            0,
                            heap,
                            &diagsArea);

      if (expRetcode != ex_expr::EXPR_OK)
        return ERROR;
    }
  else
    {
      ComDiagsArea & diags = context->diags();

      diags << DgSqlCode(-3164);
      return ERROR;
    }
  if (indPtr)
    {
      // move a zero into the indicator host variable
      Lng32 nonNull = 0;
      expRetcode = convDoIt((char *) &nonNull,
                            (Lng32) sizeof(nonNull),
                            REC_BIN32_SIGNED,
                            0,
                            0,
                            (char *) indPtr,
                            indLength,
                            (short) indType,
                            0,
                            0,
                            NULL,
                            0,
                            heap,
                            &diagsArea);
      if (expRetcode != ex_expr::EXPR_OK)
        return ERROR;
    }

  return SUCCESS;
}

Lng32  SQLCLI_GetDiskMaxSize (
			      /*IN*/ CliGlobals *cliGlobals,
			      /*IN*/ char *volname,
			      /*OUT*/ Int64 *totalCapacity,
			      /*OUT*/ Int64 *totalFreespace)
{

  Lng32 retcode = 0;
  // create initial context, if first call, don't add module because
  // that would cause infinite recursion
  retcode = CliPrologue(cliGlobals,NULL);
  if (isERROR(retcode))
    return retcode;

  ContextCli   & currContext = *(cliGlobals->currContext());
  ComDiagsArea & diags       = currContext.diags();
   return retcode;
  
  
}

Lng32  SQLCLI_GetListOfDisks (
			      /*IN*/ CliGlobals *cliGlobals,
			      /*IN/OUT*/ char *diskBuf,
			      /* OUT */ Int32 *numTSEs,
			      /*OUT */Int32 *maxTSELength,
			      /*IN/OUT */ Int32* diskBufLen
			     )
{

  Lng32 retcode = 0;
  Int32 numPrimaries = 0;
  MS_Mon_Process_Info_Type *tseInfo = NULL;
  // create initial context, if first call, don't add module because
  // that would cause infinite recursion
  retcode = CliPrologue(cliGlobals,NULL);
  if (isERROR(retcode))
    return retcode;

  ContextCli   & currContext = *(cliGlobals->currContext());
  ComDiagsArea & diags       = currContext.diags();
  NAHeap *heap = cliGlobals->currContext()->exHeap();
  *maxTSELength = MS_MON_MAX_PROCESS_NAME;
  
  retcode = msg_mon_get_process_info_type(MS_ProcessType_TSE,
					  numTSEs,
					  0,
					  NULL);
  if (retcode)
    {
      diags << DgSqlCode(-EXE_ERROR_FROM_FS2)
	    << DgNskCode(retcode) 
	    << DgString0("msg_mon_get_process_info_type");
      retcode = -EXE_ERROR_FROM_FS2;
    }
  tseInfo = new (heap) MS_Mon_Process_Info_Type[*numTSEs];
  retcode = msg_mon_get_process_info_type(MS_ProcessType_TSE,
					  numTSEs,
					  *numTSEs,
					  tseInfo);
					  
  if (retcode)
    {
      diags << DgSqlCode(-EXE_ERROR_FROM_FS2)
	    << DgNskCode(retcode) 
	    << DgString0("msg_mon_get_process_info_type");
      retcode = -EXE_ERROR_FROM_FS2;
    }
  
  if ( *diskBufLen < *numTSEs*MS_MON_MAX_PROCESS_NAME)
    {
      diags << DgSqlCode(-CLI_BUFFER_TOO_SMALL);
      retcode = -CLI_BUFFER_TOO_SMALL;
      *diskBufLen = (*numTSEs * MS_MON_MAX_PROCESS_NAME)+MS_MON_MAX_PROCESS_NAME;
    }
  else
    {
  // Fill in the TSE disk name information in the output param.
  str_pad(diskBuf ,*numTSEs*MS_MON_MAX_PROCESS_NAME, ' ');
  for (short j=0,i =0; i < *numTSEs; i++)
    {
      if (!tseInfo[i].backup)
	{
	  str_cpy((char *)&diskBuf[j], tseInfo[i].process_name,MS_MON_MAX_PROCESS_NAME,'\0');
	  numPrimaries++;
	  j += MS_MON_MAX_PROCESS_NAME;
	}
    }
  *numTSEs = numPrimaries; 
    }

  if (isERROR(retcode))
        return SQLCLI_ReturnCode(&currContext,retcode);

   return retcode;  
}

Lng32 SQLCLI_AllocDesc(/*IN*/ CliGlobals * cliGlobals,
		      /*INOUT*/        SQLDESC_ID * desc_id,
                        /*IN  OPTIONAL*/ SQLDESC_ID * input_descriptor)
{
  Lng32 retcode;


  // create initial context, if first call, and add module, if any.
  retcode = CliPrologue(cliGlobals,desc_id->module);
  if (isERROR(retcode))
    return retcode;

  ContextCli   & currContext = *(cliGlobals->currContext());
  ComDiagsArea & diags       = currContext.diags();
  
  Lng32 maxEntries = 0L;

  if (input_descriptor)
    {
      Descriptor * input_desc = currContext.getDescriptor(input_descriptor);

      /* descriptor must exist */
      if (!input_desc)
        {
          diags << DgSqlCode(-CLI_DESC_NOT_EXISTS);
          return SQLCLI_ReturnCode(&currContext,-CLI_DESC_NOT_EXISTS);
        }

      retcode = InputValueFromNumericHostvar(input_desc,
                                             1,
                                             maxEntries);
      if (isERROR(retcode))
        return SQLCLI_ReturnCode(&currContext,retcode);
    }
  else
    {
      // no input descriptor was passed in. Allocate the
      // max entries allowed.
      maxEntries = 500;
    }
  if (maxEntries < 1)
    {
      diags << DgSqlCode(- CLI_DATA_OUTOFRANGE)
            << DgInt0(maxEntries);

      return SQLCLI_ReturnCode(&currContext,-CLI_DATA_OUTOFRANGE);
    }

  /* allocate a new descriptor in the current context.         */
  /* return the descriptor handle in desc_id, if name mode     */
  /* is "desc_handle"                                          */
  retcode = currContext.allocateDesc(desc_id, maxEntries);
  if (isERROR(retcode))
    return SQLCLI_ReturnCode(&currContext,retcode);

  return CliEpilogue(cliGlobals, NULL);
}

#define MULTIPLE_CURSORS_PER_STATEMENT 1
#define KLUGE_CURSOR 1

#if defined(MULTIPLE_CURSORS_PER_STATEMENT) && defined(KLUGE_CURSOR)
#include "ComQueue.h"
#endif

Lng32 SQLCLI_AllocStmt(/*IN*/ CliGlobals * cliGlobals,
		      /*INOUT*/        SQLSTMT_ID * statement_id,
		      /*IN  OPTIONAL*/ SQLSTMT_ID * cloned_statement)
{
  Lng32 retcode;


  // create initial context, if first call, and add module, if any.
  retcode = CliPrologue(cliGlobals,statement_id->module);
  if (isERROR(retcode))
    return retcode;

  ContextCli   & currContext = *(cliGlobals->currContext());
  ComDiagsArea & diags       = currContext.diags();
  
  if (!cloned_statement)
    {
      /* allocate a new statement entry in the current context.    */
      /* return the statement handle in statement_id, if name mode */
      /* is "stmt_handle"                                          */

      retcode = currContext.allocateStmt(statement_id, Statement::DYNAMIC_STMT);
      if (isERROR(retcode))
        return SQLCLI_ReturnCode(&currContext,retcode);
    }
  else
    {
      if (
          // cloned statement must be a statement, not a cursor
          // so it's an error if it's not stmt_name or stmt_handle...
          ((cloned_statement->name_mode != stmt_name  ) &&
           (cloned_statement->name_mode != stmt_handle) &&
           (cloned_statement->name_mode != stmt_via_desc) ) ||
          // new statement, must be a cursor or a stmt handle
          (statement_id->name_mode == stmt_name) ||
          (statement_id->name_mode == stmt_via_desc))
        {
          diags << DgSqlCode(-CLI_INTERNAL_ERROR);
          return SQLCLI_ReturnCode(cliGlobals->currContext(),
				   -CLI_INTERNAL_ERROR);
        }

#if defined(MULTIPLE_CURSORS_PER_STATEMENT)
      retcode = currContext.allocateStmt(statement_id,
                                         Statement::DYNAMIC_STMT,
                                         cloned_statement);
#else
      // kluge!!! this avoids the problem that we don't know how to
      //          allocate cursors which are separate from statements
      //          For beta, the limitation is 1 cursor per statement
      SQLDESC_ID desc;
      desc.module     = statement_id->module;
      desc.identifier = statement_id->identifier;
      desc.name_mode  = desc_name;

      retcode = SQLCLI_SetCursorName(cliGlobals, cloned_statement, &desc);
#endif
      if (isERROR(retcode))
        return SQLCLI_ReturnCode(cliGlobals->currContext(),retcode);
    }
  
  return CliEpilogue(cliGlobals, NULL);
}

Lng32 SQLCLI_AllocStmtForRS(/*IN*/ CliGlobals *cliGlobals,
                           /*IN*/ SQLSTMT_ID *callStmtId,
                           /*IN*/ Lng32 resultSetIndex,
                           /*INOUT*/ SQLSTMT_ID *resultSetStmtId)
{

  Lng32 retcode;

  // create initial context, if first call, and add module, if any.
  retcode = CliPrologue(cliGlobals, callStmtId->module);
  if (isERROR(retcode))
    return retcode;

  ContextCli   & currContext = *(cliGlobals->currContext());
  ComDiagsArea & diags       = currContext.diags();
  
  // The CALL statement must exist
  Statement *callStmt = currContext.getStatement(callStmtId);
  if (!callStmt)
  {
    diags << DgSqlCode(-CLI_STMT_NOT_EXISTS);
    return SQLCLI_ReturnCode(&currContext, -CLI_STMT_NOT_EXISTS);
  }

  // The parent statement must be a CALL. This can be determine 
  // from the root TDB's query type

  NABoolean parentIsCall = FALSE;
  ex_root_tdb *parentRoot = callStmt->getRootTdb();
  if (parentRoot)
  {
    Lng32 queryType = parentRoot->getQueryType();
    if (queryType == SQL_CALL_NO_RESULT_SETS ||
        queryType == SQL_CALL_WITH_RESULT_SETS)
      parentIsCall = TRUE;
  }

  if (!parentIsCall)
  {
    diags << DgSqlCode(-EXE_UDR_RS_ALLOC_STMT_NOT_CALL);
    return SQLCLI_ReturnCode(&currContext, -EXE_UDR_RS_ALLOC_STMT_NOT_CALL);
  }

  // The RS index must not be out of range
  Lng32 maxRS = 0;
  if (parentRoot)
    maxRS = parentRoot->getMaxResultSets();
  if (resultSetIndex < 1 || resultSetIndex > maxRS)
  {
    diags << DgSqlCode(-EXE_UDR_RS_ALLOC_INVALID_INDEX)
          << DgInt0(resultSetIndex)
          << DgInt1(maxRS);
    return SQLCLI_ReturnCode(&currContext, -EXE_UDR_RS_ALLOC_INVALID_INDEX);
  }

  // A result set must not already exist at the specified position
  ExRsInfo *rsInfo = callStmt->getResultSetInfo();
  if (rsInfo && rsInfo->statementExists(resultSetIndex))
  {
    diags << DgSqlCode(-EXE_UDR_RS_ALLOC_ALREADY_EXISTS)
          << DgInt0(resultSetIndex)
          << DgInt1(resultSetIndex);
    return SQLCLI_ReturnCode(&currContext, -EXE_UDR_RS_ALLOC_ALREADY_EXISTS);
  }

  // The RS statement must not exist
  Statement *rs = currContext.getStatement(resultSetStmtId);
  if (rs)
  {
    diags << DgSqlCode(-CLI_DUPLICATE_STMT);
    return SQLCLI_ReturnCode(&currContext, -CLI_DUPLICATE_STMT);
  }

  // Create the new statement
  retcode = SQLCLI_AllocStmt(cliGlobals, resultSetStmtId, NULL);
  if (isERROR(retcode))
    return SQLCLI_ReturnCode(&currContext, retcode);
  
  // Locate the new statement
  rs = currContext.getStatement(resultSetStmtId);
  if (!rs)
  {
    diags << DgSqlCode(-CLI_STMT_NOT_EXISTS);
    return SQLCLI_ReturnCode(&currContext, -CLI_STMT_NOT_EXISTS);
  }
  
  // Bind the new statement to its parent CALL statement
  rsInfo = callStmt->getOrCreateResultSetInfo();
  rsInfo->setNumEntries(maxRS);
  rsInfo->bind(resultSetIndex, rs);
  rs->setParentCall(callStmt);

  return CliEpilogue(cliGlobals, resultSetStmtId);

} // SQLCLI_AllocStmtForRS

Lng32 SQLCLI_AssocFileNumber(/*IN*/    CliGlobals   * cliGlobals,
                            /*IN*/    SQLSTMT_ID * statement_id,
		            /*IN*/    short        file_num)
  {
  return 0;

  }
Lng32 SQLCLI_BreakEnabled(/*IN*/ CliGlobals * cliGlobals,
			 /*IN*/ UInt32 enabled )
{
  if (!cliGlobals)
    {
      return -CLI_NO_CURRENT_CONTEXT;
    }


  cliGlobals->setBreakEnabled (enabled);
  return 0;
}
Lng32 SQLCLI_SPBreakRecvd(/*IN*/ CliGlobals * cliGlobals,
			 /*OUT*/ UInt32 *breakRecvd)
{
  if (!cliGlobals)
    {
      return -CLI_NO_CURRENT_CONTEXT;
    }


  *breakRecvd = cliGlobals->SPBreakReceived();
  cliGlobals->setSPBreakReceived(FALSE);
  return 0;
}

Lng32 SQLCLI_CreateContext(/*IN*/ CliGlobals * cliGlobals,
			  /*OUT*/ SQLCTX_HANDLE *contextHandle,
			  /*IN*/ char * sqlAuthId,
                          /*IN*/ Lng32 mustBeZero /* for future use */)
{  
  Lng32 retcode;


  ContextCli   & currContext = *(cliGlobals->currContext());
  ComDiagsArea & diags       = currContext.diags();
  if (mustBeZero != 0)
  {
    //
    // We constrain "for future use" parameters so that only a
    // particular value (in this case 0) is accepted. Without this
    // restriction things might break should we suddenly give the
    // parameters some semantics.
    //
    diags << DgSqlCode(-CLI_RESERVED_ARGUMENT)
          << DgString0("2")
          << DgString1("SQL_EXEC_CreateContext")
          << DgString2("0");
    return SQLCLI_ReturnCode(&currContext, -CLI_RESERVED_ARGUMENT);
  }
  ContextCli * newContext = NULL;
  retcode = cliGlobals->createContext(newContext);
  if (! newContext)
    {
      diags << DgSqlCode(-CLI_INTERNAL_ERROR);
      return SQLCLI_ReturnCode(&currContext,-CLI_INTERNAL_ERROR);
    }

  if (contextHandle)
    *contextHandle = newContext->getContextHandle();

  return SUCCESS;
}

Lng32 SQLCLI_CurrentContext(/*IN*/ CliGlobals * cliGlobals,
			   /*OUT*/ SQLCTX_HANDLE *contextHandle)
{
  if (!cliGlobals) {

    return -CLI_NO_CURRENT_CONTEXT;
  }


  ContextCli *currentContext = cliGlobals->currContext();

  if (contextHandle)
    *contextHandle = currentContext->getContextHandle();

  return SUCCESS;
}

Lng32 SQLCLI_DeleteContext(/*IN*/  CliGlobals    * cliGlobals,
			  /*IN*/ SQLCTX_HANDLE context_handle)
{
  if (!cliGlobals) {

    return -CLI_NO_CURRENT_CONTEXT; 
            
  }


  return SQLCLI_DropContext(cliGlobals, context_handle);
}

Lng32 SQLCLI_DropModule(/*IN*/ CliGlobals * cliGlobals,
		       /*IN*/ const SQLMODULE_ID * module_id)
{
  return SUCCESS;
}

Lng32 SQLCLI_ResetContext(/*IN*/  CliGlobals    * cliGlobals,
			  /*IN*/ SQLCTX_HANDLE context_handle, 
			  /*IN*/ void *contextMsg)
{
  Lng32 retcode;

  ContextCli *context = cliGlobals->getContext(context_handle);
  ContextCli *defaultContext = cliGlobals->getDefaultContext();
  ComDiagsArea &diags = defaultContext->diags();
  if (context == NULL)
  {
      diags << DgSqlCode(-CLI_CONTEXT_NOT_FOUND);
      return SQLCLI_ReturnCode(defaultContext, -CLI_CONTEXT_NOT_FOUND);
  }
  CLISemaphore *tmpSemaphore = context->getSemaphore(); 
  tmpSemaphore->get();
  try
  {
    retcode =  cliGlobals->resetContext(context, contextMsg);
  }
  catch (...)
  {
     retcode = -CLI_INTERNAL_ERROR;
     tmpSemaphore->release();
  }
  tmpSemaphore->release();
  return SQLCLI_ReturnCode(context, retcode);
}

Lng32 SQLCLI_GetUdrErrorFlags_Internal(/*IN*/ CliGlobals * cliGlobals,
				      /*OUT*/ Lng32 * udrErrorFlags){
  if (!cliGlobals) {

    return -CLI_NO_CURRENT_CONTEXT;
  }


  if (!cliGlobals->getUdrErrorChecksEnabled())
  {
    return -CLI_NOT_CHECK_VIOLATION;
  }
  
  NABoolean sqlViolation = FALSE;
  NABoolean xactViolation = FALSE;
  NABoolean xactWasAborted = FALSE;

  cliGlobals->getUdrErrorFlags(sqlViolation, xactViolation, xactWasAborted);

  *udrErrorFlags = 0;
  
  if (sqlViolation) {
    *udrErrorFlags |= SQLUDR_SQL_VIOL;
  }
  if (xactViolation) {
    *udrErrorFlags |= SQLUDR_XACT_VIOL;
  }
  if (xactWasAborted) {
    *udrErrorFlags |= SQLUDR_XACT_ABORT;
  }

  return SUCCESS;
}  

Lng32 SQLCLI_SetUdrAttributes_Internal(/*IN*/ CliGlobals * cliGlobals,
				      /*IN*/ Lng32 sqlAccessMode,
				      /*IN*/ Lng32 mustBeZero /* for future use */){
  if (!cliGlobals) {

    return -CLI_NO_CURRENT_CONTEXT;
  }


  if (mustBeZero != 0)
  {
    //
    // We constrain "for future use" parameters so that only a
    // particular value (in this case 0) is accepted. Without this
    // restriction things might break should we suddenly give the
    // parameters some semantics.
    //
    ContextCli   & currContext = *(cliGlobals->currContext());
    ComDiagsArea & diags       = currContext.diags();
    diags << DgSqlCode(-CLI_RESERVED_ARGUMENT)
          << DgString0("2")
          << DgString1("SQL_EXEC_SetUdrAttributes_Internal")
          << DgString2("0");
    return SQLCLI_ReturnCode(&currContext, -CLI_RESERVED_ARGUMENT);
  }

  cliGlobals->setUdrErrorChecksEnabled(TRUE);
  cliGlobals->setUdrSQLAccessMode((enum ComRoutineSQLAccess)sqlAccessMode);
  
  return SUCCESS;
}

Lng32 SQLCLI_ResetUdrErrorFlags_Internal(/*IN*/ CliGlobals * cliGlobals){
  if (!cliGlobals) {

    return -CLI_NO_CURRENT_CONTEXT;
  }


  cliGlobals->clearUdrErrorFlags();

  return SUCCESS;
}
// A CLI wrapper around a ContextCli method to dynamically set JVM
// startup options in the UDR server
Lng32 SQLCLI_SetUdrRuntimeOptions_Internal(/*IN*/ CliGlobals *cliGlobals,
                                          /*IN*/ const char *options,
                                          /*IN*/ ULng32 optionsLen,
                                          /*IN*/ const char *delimiters,
                                          /*IN*/ ULng32 delimsLen)
{
  if (!cliGlobals)
  {
    return -CLI_NO_CURRENT_CONTEXT;
  }
  

  ContextCli &currContext = *(cliGlobals->currContext());
  Lng32 retcode = currContext.setUdrRuntimeOptions(options, optionsLen,
                                                  delimiters, delimsLen);

  return SQLCLI_ReturnCode(&currContext, retcode);
}

Lng32 SQLCLI_DeallocDesc(/*IN*/ CliGlobals * cliGlobals,
			/*IN*/ SQLDESC_ID * desc_id)
{

  Lng32 retcode;
  if (!cliGlobals)
    {
      return -CLI_NO_CURRENT_CONTEXT;
    }


  ContextCli   & currContext = *(cliGlobals->currContext());
  ComDiagsArea & diags       = currContext.diags();

  retcode = currContext.deallocDesc(desc_id, FALSE);

  return SQLCLI_ReturnCode(&currContext,retcode);
}

Lng32 SQLCLI_DeallocStmt(/*IN*/ CliGlobals * cliGlobals,
			/*IN*/ SQLSTMT_ID * statement_id)
{
  Lng32 retcode;
  
  if (!cliGlobals)
  {
    return (-CLI_NO_CURRENT_CONTEXT);
  }
  
  retcode = CheckNOSQLAccessMode(*cliGlobals);
  if (isERROR(retcode))
  {
    return retcode;
  }


  retcode = CliPrologue(cliGlobals,NULL);
  if (isERROR(retcode))
    return retcode;

  ContextCli   & currContext = *(cliGlobals->currContext());
  ComDiagsArea & diags       = currContext.diags();

  retcode = currContext.deallocStmt(statement_id, FALSE);

  return SQLCLI_ReturnCode(&currContext,retcode);
}
Lng32 SQLCLI_DefineDesc(/*IN*/ CliGlobals * cliGlobals,
		       /*IN*/ SQLSTMT_ID * statement_id,
                         /* (SQLWHAT_DESC) *IN*/       Lng32   what_descriptor,
                         /*IN*/ SQLDESC_ID * desc_id)
{
  Lng32 retcode;
  

  // create initial context, if first call, and add module, if any.
  retcode = CliPrologue(cliGlobals,statement_id->module);
  if (isERROR(retcode))
    return retcode;

  ContextCli   & currContext = *(cliGlobals->currContext());
  ComDiagsArea & diags       = currContext.diags();
  
  Statement * stmt = currContext.getStatement(statement_id);

  /* stmt must exist */
  if (!stmt)
    {
      diags << DgSqlCode(-CLI_STMT_NOT_EXISTS);
      return SQLCLI_ReturnCode(&currContext,-CLI_STMT_NOT_EXISTS);
    }

  Descriptor * desc = currContext.getDescriptor(desc_id);

  /* descriptor must exist */
  if (!desc)
    {
      diags << DgSqlCode(-CLI_DESC_NOT_EXISTS);
      return SQLCLI_ReturnCode(&currContext,-CLI_DESC_NOT_EXISTS);
    }

  stmt->addDefaultDesc(desc, what_descriptor);

  return SUCCESS;
}
Lng32 SQLCLI_DescribeStmt(/*IN*/ CliGlobals * cliGlobals,
			 /*IN*/           SQLSTMT_ID * statement_id,
			 /*IN  OPTIONAL*/ SQLDESC_ID * input_descriptor,
			 /*IN  OPTIONAL*/ SQLDESC_ID * output_descriptor)
{
  if (!cliGlobals)
    {
      return -CLI_NO_CURRENT_CONTEXT;
    }


  Lng32 retcode;
  
  ContextCli   & currContext = *(cliGlobals->currContext());
  ComDiagsArea & diags       = currContext.diags();

  /* describe the statement */
  Statement * stmt = currContext.getStatement(statement_id);

  /* stmt must exist */
  if (!stmt)
    {
      diags << DgSqlCode(-CLI_STMT_NOT_EXISTS);
      return SQLCLI_ReturnCode(&currContext,-CLI_STMT_NOT_EXISTS);
    }

  /* stmt should be a dynamic statement and must not be in INITIAL state */
  /* if it is in INITIAL state then the statement did not get prepared. */
  /* If it is in PREPARE state, then it is a nowaited prepare which is
     still being prepared. */

  if ((stmt->getState() == Statement::INITIAL_) ||
      (stmt->getState() == Statement::PREPARE_))
  {
    // One special case for CALL statements. A stored procedure result
    // set proxy statement can be described without first being
    // prepared by the CLI caller. The prepare gets done internally
    // inside Statement::describe(). So for this case we do not want
    // to return here with an error just because the statement is not
    // yet prepared.
    NABoolean reportAnError = TRUE;
    if (stmt->getState() == Statement::INITIAL_ && stmt->getParentCall())
      reportAnError = FALSE;

    if (reportAnError)
    {
      diags << DgSqlCode(-CLI_STMT_NOT_PREPARED);
      return SQLCLI_ReturnCode(&currContext,-CLI_STMT_NOT_PREPARED);
    }
  }

  if (input_descriptor)
    {
      Descriptor * input_desc = currContext.getDescriptor(input_descriptor);
      if (!input_desc)
        {
          diags << DgSqlCode(-CLI_DESC_NOT_EXISTS);
          return SQLCLI_ReturnCode(&currContext,-CLI_DESC_NOT_EXISTS);
        }

      retcode = stmt->describe(input_desc,
                               SQLWHAT_INPUT_DESC,
                               diags);
      if (isERROR(retcode))
        return SQLCLI_ReturnCode(&currContext,retcode);
    }

  if (output_descriptor)
    {
      Descriptor * output_desc = currContext.getDescriptor(output_descriptor);

      if (!output_desc)
        {
          diags << DgSqlCode(-CLI_DESC_NOT_EXISTS);
          return SQLCLI_ReturnCode(&currContext,-CLI_DESC_NOT_EXISTS);
        }

      retcode = stmt->describe(output_desc,
                               SQLWHAT_OUTPUT_DESC,
                               diags);
      if (isERROR(retcode))
        return SQLCLI_ReturnCode(&currContext,retcode);
    }

  return CliEpilogue(cliGlobals, statement_id);
}
Lng32 SQLCLI_DisassocFileNumber(/*IN*/          CliGlobals * cliGlobals,
                               /*IN*/          SQLSTMT_ID * statement_id)
  {
  return 0;
  }

Lng32 SQLCLI_DropContext(/*IN*/ CliGlobals * cliGlobals,
			/*IN*/ SQLCTX_HANDLE context_handle )
{


  ContextCli *defaultContext = cliGlobals->getDefaultContext();
  ComDiagsArea & diags       = defaultContext->diags();

  ContextCli * droppedContext = cliGlobals->getContext(context_handle,
                                                       TRUE);

  if (context_handle == cliGlobals->getDefaultContext()->getContextHandle())
  {
      diags << DgSqlCode(-CLI_DEFAULT_CONTEXT_NOT_ALLOWED);
      return SQLCLI_ReturnCode(defaultContext,-CLI_DEFAULT_CONTEXT_NOT_ALLOWED);
  }
  
  if (droppedContext == NULL)
  {
      diags << DgSqlCode(-CLI_CONTEXT_NOT_FOUND);
      return SQLCLI_ReturnCode(defaultContext,-CLI_CONTEXT_NOT_FOUND);
  }
  Lng32 retcode;
  
  try
  {
     retcode = cliGlobals->dropContext(droppedContext);
     if (retcode == -1)
     {
      // $$$ probably should be a different error message
      diags << DgSqlCode(-CLI_NO_CURRENT_CONTEXT);
     }
  }
  catch (...)
  {
     return -CLI_INTERNAL_ERROR;
  }
  return SQLCLI_ReturnCode(defaultContext,retcode);
}

Lng32 SQLCLI_SetRowsetDescPointers(CliGlobals * cliGlobals,
				  SQLDESC_ID  * desc_id, 
				  Lng32    rowset_size,
				  Lng32    *rowset_status_ptr,
				  Lng32    starting_entry,
				  Lng32    num_quadruple_fields,
				  va_list    ap,
				  SQLCLI_QUAD_FIELDS    quad_fields[])
{
  if (!desc_id)
    {
      return -CLI_INTERNAL_ERROR;
    }


  ContextCli   & currContext = *(cliGlobals->currContext());
  ComDiagsArea & diags       = currContext.diags();
  Descriptor   * desc        = currContext.getDescriptor(desc_id);
  
  /* descriptor must exist */
  if (!desc)
    {
      diags << DgSqlCode(-CLI_DESC_NOT_EXISTS);
      return SQLCLI_ReturnCode(&currContext,-CLI_DESC_NOT_EXISTS);
    }

  desc->setDescItem(0, SQLDESC_ROWSET_SIZE, rowset_size, 0);
  desc->setDescItem(0, SQLDESC_ROWSET_STATUS_PTR, (Long)rowset_status_ptr, 0);
  
  if (num_quadruple_fields > 0)
    {
      for (Lng32 entry=starting_entry, i = 0; 
           entry < starting_entry+num_quadruple_fields;
           entry++, i++)
        {
	  if (desc->getUsedEntryCount() < entry) {
	    diags << DgSqlCode(-CLI_INVALID_DESC_ENTRY);
	    return SQLCLI_ReturnCode(&currContext,-CLI_INVALID_DESC_ENTRY);
	  }

          // need to re-order this to avoid possible problems with not setting
          // the data area (i.e. VAR_PTR) last.
          char * var_layout, * var_ptr, * ind_layout, * ind_ptr;
          if (ap) {
            var_layout = va_arg(ap, char *);
            var_ptr    = va_arg(ap, char *);
            ind_layout = va_arg(ap, char *);
            ind_ptr    = va_arg(ap, char *);
          }
          else {
            var_layout = (char *)((long)quad_fields[i].var_layout);
            var_ptr = (char *)quad_fields[i].var_ptr;
            ind_layout = (char *)((long)quad_fields[i].ind_layout);
            ind_ptr = quad_fields[i].ind_ptr == (void *)-1 ? 0 : (char *)quad_fields[i].ind_ptr;
          }
          // setDescItems requires setting the rowset size and layout size items
          // before setting the pointers. Do not change the following order.
          desc->setDescItem(entry, SQLDESC_ROWSET_VAR_LAYOUT_SIZE,
                            (Long)var_layout, 0);
          desc->setDescItem(entry, SQLDESC_ROWSET_IND_LAYOUT_SIZE,
                            (Long)ind_layout, 0);
          desc->setDescItem(entry, SQLDESC_IND_PTR, 
                            (Long)ind_ptr, 0);
          desc->setDescItem(entry, SQLDESC_VAR_PTR,
                            (Long)var_ptr, 0);
        }
      va_end(ap);
    }

  return SUCCESS;
}
Lng32 SQLCLI_GetRowsetNumprocessed(CliGlobals * cliGlobals,
				  SQLDESC_ID * desc_id, 
                                    Lng32 &rowset_nprocessed)
{
  Lng32 retcode = SUCCESS;


  // create initial context, if first call, and add module, if any.
  retcode = CliPrologue(cliGlobals,desc_id->module);
  if (isERROR(retcode))
    return retcode;

  ContextCli   & currContext = *(cliGlobals->currContext());
  ComDiagsArea & diags       = currContext.diags();

  Descriptor * desc = currContext.getDescriptor(desc_id);

  /* descriptor must exist */
  if (!desc)
    {
      diags << DgSqlCode(-CLI_DESC_NOT_EXISTS);
      return SQLCLI_ReturnCode(&currContext,-CLI_DESC_NOT_EXISTS);
    }

  retcode = desc->getDescItem(1,
                              SQLDESC_ROWSET_NUM_PROCESSED, 
                              (Lng32*) &rowset_nprocessed,
                              NULL, 0, NULL,  0);

  retcode = CliEpilogue(cliGlobals, NULL);
  return SQLCLI_ReturnCode(&currContext,retcode);
}
static NABoolean SQLCLI_GetRetryInfo(CliGlobals * cliGlobals,
				     Lng32 retcode,
				     AQRStatementInfo * aqrSI,
				     short afterPrepare, 
				     short afterExec, 
				     short afterFetch,
				     short afterCEFC,
				     Lng32 &retries,
				     Lng32 &delay,
				     Lng32 &type,
				     Lng32 &numCQDs,
				     char* &cqdStr,
				     Lng32 &cmpInfo,
				     ComCondition* &cc)
{
  retries = -1;
  delay = -1;
  type = -1;
  cmpInfo = 0;
  cc = NULL;
  Lng32 intAQR;
  ContextCli * context = cliGlobals->currContext();
  AQRInfo * aqr = context->aqrInfo();
  NABoolean doAqr = FALSE; // auto query retry
  if ((aqr) &&
      (aqrSI) &&
      (aqrSI->getRetryStatementId()) &&
      (aqrSI->getRetrySqlSource()) &&
      (isERROR(retcode)) &&
      (retcode != -EXE_CANCELED) &&
      (context->diags().getNumber(DgSqlCode::ERROR_) > 0) &&
      (context->getNumOfCliCalls() == 1))
    {
      type = AQRInfo::RETRY_NONE;

      for (Int32 i = 1; 
	   ((NOT doAqr) && 
	    (i <= context->diags().getNumber(DgSqlCode::ERROR_))); 
	   i++)
	{
	  ComCondition * lcc = context->diags().getErrorEntry(i);
	  aqr->getAQREntry(lcc->getSQLCODE(), lcc->getNskCode(),
			   retries, delay, type,
			   numCQDs, cqdStr, cmpInfo, intAQR);
	  if ((type >= AQRInfo::RETRY_MIN_VALID_TYPE) &&
	      (type <= AQRInfo::RETRY_MAX_VALID_TYPE))
	    {
	      cc = lcc;
	      
	      doAqr = TRUE;
	    } // if
	}  // for
      
      if ((type != AQRInfo::RETRY_NONE) && 
	  ((afterFetch) && (NOT aqrSI->retryFirstFetch())) &&
	  !(afterExec && aqrSI->retryAfterExec())
	  )

	doAqr = FALSE;
    } // if

  return doAqr;
}

static Lng32 SQLCLI_RetryDeallocStmt(
     /*IN*/ CliGlobals * cliGlobals,
     AQRStatementInfo * aqrSI)
{
  Lng32 retcode = 0;

  ContextCli * currContext = cliGlobals->currContext();

  ComDiagsArea & diags = currContext->diags();
  diags.clear();

  SQLDESC_ID * temp_input_desc_id = NULL;
  SQLDESC_ID * temp_output_desc_id = NULL;
  if (! aqrSI->getRetryInputDesc())
    {
      SQLMODULE_ID * module = new(currContext->exHeap()) SQLMODULE_ID;
      init_SQLMODULE_ID(module);

      temp_input_desc_id = new(currContext->exHeap()) SQLDESC_ID;
      init_SQLDESC_ID(temp_input_desc_id, SQLCLI_CURRENT_VERSION, desc_handle, module);

      retcode = SQLCLI_AllocDescInt(cliGlobals, temp_input_desc_id, 1);
      if (isERROR(retcode))
	return retcode;
    }

  if (! aqrSI->getRetryOutputDesc())
    {
      SQLMODULE_ID * module = new(currContext->exHeap()) SQLMODULE_ID;
      init_SQLMODULE_ID(module);

      temp_output_desc_id = new(currContext->exHeap()) SQLDESC_ID;
      init_SQLDESC_ID(temp_output_desc_id, SQLCLI_CURRENT_VERSION, desc_handle, module);

      retcode = SQLCLI_AllocDescInt(cliGlobals, temp_output_desc_id, 1);
      if (isERROR(retcode))
	return retcode;
    }

  retcode = SQLCLI_DescribeStmt(cliGlobals,
				aqrSI->getRetryStatementId(),
				temp_input_desc_id,
				temp_output_desc_id);
  if (isERROR(retcode) && (retcode != -CLI_STMT_NOT_PREPARED))
    return retcode;
  if (retcode == -CLI_STMT_NOT_PREPARED)
    diags.clear();

  aqrSI->setRetryTempInputDesc(temp_input_desc_id);
  aqrSI->setRetryTempOutputDesc(temp_output_desc_id);
  
  retcode = SQLCLI_DeallocStmt(cliGlobals, 
			       aqrSI->getRetryStatementId());
  
  if (isERROR(retcode))
    return retcode;

  return retcode;
}

// If a query was explicitly prepared and it gets a timestamp mismatch
// or a lost open error during its fixup or execute phase, then AQR
// is not done. This is needed to handle the case where the table shape
// or structure got changed by a ddl operation after the stmt was
// explicitly prepared. And that ddl operation caused the ts mismatch.
// Since this was an explicitly prepared stmt, it cannot be automatically
// re-described during the execute phase. Executing a statement that was
// internally prepared during AQR but not re-described can cause
// inconsistency between the structures/data that is returned or input 
// and the structure that the caller had set up to handle during 
// describe input/output phase of the initial prepare.
// Users need to explicitly reprepare this statement.
// Add an error indicating this condition and return the original 
// error back to user.
static Lng32 SQLCLI_RetryValidateDescs
(/*IN*/ CliGlobals * cliGlobals,
 /*IN*/           SQLSTMT_ID * statement_id,
 /*IN  OPTIONAL*/ SQLDESC_ID * curr_input_desc_id,
 /*IN  OPTIONAL*/ SQLDESC_ID * curr_output_desc_id)
{
  Lng32 retcode = 0;

  ContextCli   & currContext = *(cliGlobals->currContext());
  ComDiagsArea & diags       = currContext.diags();

  
  Statement * stmt = currContext.getStatement(statement_id);
  if ((stmt == NULL) || (stmt->isStandaloneQ()))    
    return retcode;
    
    

  SQLMODULE_ID module;
  init_SQLMODULE_ID(&module);

  SQLDESC_ID new_input_desc_id;
  SQLDESC_ID new_output_desc_id;

  init_SQLDESC_ID(&new_input_desc_id, SQLCLI_CURRENT_VERSION, desc_handle, &module);
  init_SQLDESC_ID(&new_output_desc_id, SQLCLI_CURRENT_VERSION, desc_handle, &module);

  retcode = SQLCLI_AllocDescInt(cliGlobals, &new_input_desc_id, 1);
  if (isERROR(retcode))
    return retcode;

  retcode = SQLCLI_AllocDescInt(cliGlobals, &new_output_desc_id, 1);
  if (isERROR(retcode))
    return retcode;

 

  Descriptor * currInputDesc = currContext.getDescriptor(curr_input_desc_id);
  if (!currInputDesc)
    {
      diags << DgSqlCode(-CLI_DESC_NOT_EXISTS);
      return -CLI_DESC_NOT_EXISTS;
    }

  Descriptor * currOutputDesc = currContext.getDescriptor(curr_output_desc_id);
  if (!currOutputDesc)
    {
      diags << DgSqlCode(-CLI_DESC_NOT_EXISTS);
      return -CLI_DESC_NOT_EXISTS;
    }
  
  Descriptor * newInputDesc = currContext.getDescriptor(&new_input_desc_id);
  if (!newInputDesc)
    {
      diags << DgSqlCode(-CLI_DESC_NOT_EXISTS);
      return -CLI_DESC_NOT_EXISTS;
    }
  Descriptor * newOutputDesc = currContext.getDescriptor(&new_output_desc_id);
  if (!newOutputDesc)
    {
      diags << DgSqlCode(-CLI_DESC_NOT_EXISTS);
      return -CLI_DESC_NOT_EXISTS;
    }
  // Before describing , save the flags from the old descriptors that the user
  // may have set using a setDescItem call
  newOutputDesc->setDescFlags( currOutputDesc->getDescFlags());
  newInputDesc->setDescFlags(currInputDesc->getDescFlags());
  retcode = SQLCLI_DescribeStmt(cliGlobals,
				statement_id,
				&new_input_desc_id,
				&new_output_desc_id);
  if (isERROR(retcode))
    return retcode;
  newInputDesc = currContext.getDescriptor(&new_input_desc_id);
  if (!newInputDesc)
    {
      diags << DgSqlCode(-CLI_DESC_NOT_EXISTS);
      return -CLI_DESC_NOT_EXISTS;
    }
  newOutputDesc = currContext.getDescriptor(&new_output_desc_id);
  if (!newOutputDesc)
    {
      diags << DgSqlCode(-CLI_DESC_NOT_EXISTS);
      return -CLI_DESC_NOT_EXISTS;
    }
  if (NOT (*currInputDesc == *newInputDesc))
    {
      retcode = -EXE_USER_PREPARE_NEEDED;
      goto retError;
    }
    
  if (NOT (*currOutputDesc == *newOutputDesc))
    {
      retcode = -EXE_USER_PREPARE_NEEDED;
      goto retError;
    }
  
  return retcode;

retError:
  diags << DgSqlCode(retcode);
  
  if (stmt)
    stmt->setAqrReprepareNeeded(TRUE);

  return retcode;
}

static Lng32 SQLCLI_RetryQuery(
     /*IN*/ CliGlobals * cliGlobals,
     AQRStatementInfo * aqrSI,
     ULng32 flags,
     short afterPrepare, short afterExec, short afterFetch, short afterCEFC,
     StmtStats *savedStmtStats)
{
  Lng32 retcode = 0;

  ContextCli * currContext = cliGlobals->currContext();
  ComDiagsArea & diags = currContext->diags();

  
  SQL_QUERY_COST_INFO queryCostInfo;
  SQL_QUERY_COMPILER_STATS_INFO queryCompStatsInfo;
  // allocate a new statement which will be used for the retry

  retcode = SQLCLI_AllocStmt(cliGlobals, 
  	      		     aqrSI->getRetryStatementId(), NULL);
  
  // Copy the saved off  statement attributes into the newly created stmt
  Statement *newStmt = currContext->getStatement(aqrSI->getRetryStatementId());
  if (newStmt)
    {
      aqrSI->copyAttributesToStmt(newStmt);
    }
 
  if (isERROR(retcode))
    {
       if (savedStmtStats)
          savedStmtStats->setAqrInProgress(FALSE);
       return retcode;
    }

  // In case of fsth path CLI calls, we need to clear out the statement handle  // that may point to a StatementInfo() struct that no longer is valid.
  if (aqrSI->getRetryStatementId()->name_mode == stmt_name)
    aqrSI->getRetryStatementId()->handle = NULL;
  // pass in the original query id when retrying this query.
  char * uniqueQueryId = aqrSI->getAQRStatementAttributes()->uniqueStmtId_;
  Lng32 uniqueQueryIdLen = aqrSI->getAQRStatementAttributes()->uniqueStmtIdLen_;
  // prepare the statement that has been already allocated earlier
  retcode = SQLCLI_Prepare2(cliGlobals,
			    aqrSI->getRetryStatementId(),
			    aqrSI->getRetrySqlSource(),
			    NULL, 0, NULL,
			    &queryCostInfo,
			    &queryCompStatsInfo,
			    uniqueQueryId,
			    &uniqueQueryIdLen,
			    flags
			    );

  if (isERROR(retcode)) {
      if (savedStmtStats)
          savedStmtStats->setAqrInProgress(FALSE);
      return retcode;
  }
      
  if (afterPrepare) {
     if (savedStmtStats)
        savedStmtStats->setAqrInProgress(FALSE);
    return 0;
  }

  // before executing this statement,
  // validate that the new prepare's input/output descriptors are the same
  // as the original input/output descriptors.
  retcode = SQLCLI_RetryValidateDescs
    (cliGlobals,
     aqrSI->getRetryStatementId(),
     (aqrSI->getRetryInputDesc() ? aqrSI->getRetryInputDesc() :
      aqrSI->getRetryTempInputDesc()),
     (aqrSI->getRetryOutputDesc() ? aqrSI->getRetryOutputDesc() :
      aqrSI->getRetryTempOutputDesc()));
  if (isERROR(retcode))
    return retcode;

  va_list ap ;
  memset(&ap, 0, sizeof(ap)); // 64-bit project

  SQLCLI_PTR_PAIRS   ptr_pairs[1];

  if (afterCEFC)
    {
      // MXCS may pass a nam_mode of stmt_handle for this particular call.
      // So handle tht case also. Reset the statement handle to be NULL. 
      // The StmtInfo() class 
      // would need to be reinitialized with this newly created statement
      if (aqrSI->getRetryStatementId()->name_mode != desc_handle)
	aqrSI->getRetryStatementId()->handle = NULL;
      retcode =
	SQLCLI_ClearExecFetchClose(cliGlobals,
				   aqrSI->getRetryStatementId(), 
				   aqrSI->getRetryInputDesc(),	
			   	   aqrSI->getRetryOutputDesc(),        
			    	   0,
				   0,
				   0,
				   ap,
				   0,
				   0);
      if (isERROR(retcode))
	return retcode;
    }
  else
    {
      retcode = SQLCLI_Exec(cliGlobals,
			    aqrSI->getRetryStatementId(), 
			    aqrSI->getRetryInputDesc(),
			    0, ap, ptr_pairs); 
      if (isERROR(retcode))
	return retcode;
      
      if (afterExec && !afterFetch)
	return 0;
      
      retcode = SQLCLI_Fetch(cliGlobals,
			     aqrSI->getRetryStatementId(), 
			     aqrSI->getRetryOutputDesc(),
			     0, ap, ptr_pairs); 
      if (isERROR(retcode))
	return retcode;
    }
  // If this is a retry of an ExecFetch ,also close the statement because
  // SQCLI_ExecFetch also  internally closes the statement. So we have to do
  // the same when going through AQR
  if (afterExec && afterFetch)
    {
      retcode = SQLCLI_CloseStmt(cliGlobals,aqrSI->getRetryStatementId());
      if (isERROR(retcode))
	return retcode;
    }

  return retcode;
}
  
// When previous attempt of a failed NO ROLLBACK did change
// the target table in ways that it could not undo, then
// do not allow retry, except in case of non-ACID DELETE which
// is configured to continue using AQR.
bool preventAqrWnr(ContextCli *currContext, 
                         Statement *stmt, bool &addWarning8737)
{
  bool preventAqr = true;
  addWarning8737 = false;

  // Get statistics from RMS shared segment via ssmp
  // to guard against scenarios like 2034, where the stats
  // would not flow back to the master due to broken data
  // channels.
  const ExStatisticsArea *constStatsArea = NULL;
  Lng32 cliRc = SQL_EXEC_GetStatisticsArea_Internal(SQLCLI_STATS_REQ_QID,
           stmt->getUniqueStmtId(),
           stmt->getUniqueStmtIdLen(),
           -1, SQLCLI_SAME_STATS, 
           constStatsArea);  

  ExStatisticsArea * statsArea = (ExStatisticsArea *) constStatsArea;

  bool targetIsChanged = false;

  if ((cliRc < 0) || (NULL == statsArea))
   targetIsChanged = true;  // Cannot ascertain, so assume worst
  else if ((NULL == statsArea->getMasterStats()) ||
           (statsArea->getMasterStats()->getStatsErrorCode() != 0))
    targetIsChanged = true; // partial success, e.g., node down.
  else          
  {
    if (statsArea->anyHaveSentMsgIUD())
      targetIsChanged = true;
  }

  if (stmt->getGlobals() && 
      stmt->getGlobals()->getAqrWnrInsertCleanedup())
    targetIsChanged = false;

  if (targetIsChanged)
  {
    // for deletes, if AQR_WNR_DELETE_NO_ROWCOUNT, we may
    // retry even if target has changed.
    ex_root_tdb *rootTdb = stmt->getRootTdb();
    if (((rootTdb->getQueryType() ==
                         ComTdbRoot::SQL_DELETE_UNIQUE) ||
         (rootTdb->getQueryType() ==
                         ComTdbRoot::SQL_DELETE_NON_UNIQUE)) &&
         rootTdb->aqrWnrDeleteContinue())
      {
        preventAqr = false;
        addWarning8737 = true;
      }
  }
  else 
    preventAqr = false;

  return preventAqr;
}
Lng32 SQLCLI_ProcessRetryQuery(
        /*IN*/ CliGlobals * cliGlobals, 
	SQLSTMT_ID * statement_id,
	Lng32 sqlcode,
	short afterPrepare, short afterExec, short afterFetch, 
	short afterCEFC)
{
  Lng32 retcode = sqlcode;
  if (NOT isERROR(retcode))
    return retcode;

  ContextCli * currContext = cliGlobals->currContext();
  ComDiagsArea & diags = currContext->diags();
  AQRInfo * aqr = currContext->aqrInfo();
  ExTransaction * exTransaction = currContext->getTransaction();
  bool addWarning8737 = false;
  bool checkAqrWnr = false;

  Statement * stmt = currContext->getStatement(statement_id);
  if ((stmt == NULL) ||
      (stmt->getStatementType() == Statement::STATIC_STMT) ||
      (stmt->getStmtId() == NULL) ||
      (stmt->getSrcStrSize() <= 0))
      return retcode;

  ex_root_tdb * rootTdb = stmt->getRootTdb();
  if (rootTdb)
    {
      // Of course, there are many other checks to see if AQR can be 
      // attempted. This next check considers the SQLCODE and attributes
      // of the statement which were set by the code generator.
      if (NOT stmt->getRootTdb()->aqrEnabledForSqlcode(sqlcode))
        return retcode;

      // WITH NO ROLLBACK that has sent msgs to IUD cannot be
      // retried
      if (!rootTdb->isPacked() && 
          (rootTdb->getTransMode()->anyNoRollback() ||
           (exTransaction && 
            exTransaction->getTransMode()->anyNoRollback())))
        {
          checkAqrWnr = true;
          if (preventAqrWnr(currContext, stmt, addWarning8737))
            return retcode;
        }

      if ((rootTdb->updDelInsertQuery()) ||
          (rootTdb->ddlQuery()))
        {
          if (rootTdb->transactionReqd() &&
              (NOT exTransaction->xnInProgress()))
            {
	      if (exTransaction->autoCommit())
                {
	          if ((aqr->abortedTransWasImplicit() == FALSE) &&
		      (diags.getNumber(DgSqlCode::ERROR_) > 0) &&
	              diags.containsError(-CLI_VALIDATE_TRANSACTION_ERROR))
		    return retcode;

		  // if aqr was enabled but cant be done at runtime, return.
		  if (aqr->noAQR())
		    return retcode;
                }
              else
                {
                  // Part of the fix for 10-100604-0887.  See statement.cpp
                  // for the other part and for more commentary.
                  return retcode;
                } 
            }
        }

      // if this is a udr/call statement and not a standalone statement, return an error
      //The caller will need to reprepare the query so we have an updated tdb to execute.
      // If it's a standalone statement, the statement will get reprepared and executed. 
      if ((rootTdb->getUdrCount() > 0) && !stmt->isStandaloneQ())
      {
        return retcode;
      }
    }

  AQRStatementInfo * aqrSI = NULL;
  char * stmtId = NULL;
  char * id = NULL;
  char * charset = NULL;
  SQLSTMT_ID sql_stmt;
  SQLDESC_ID sql_src;
  SQLMODULE_ID sql_module;
  if (stmt)
    {
      aqrSI = 
	new(currContext->exHeap()) AQRStatementInfo(currContext->exHeap());
      
      id = new(currContext->exHeap()) char[stmt->getStmtId()->identifier_len + 1];
      str_cpy_all(id, stmt->getStmtId()->identifier, stmt->getStmtId()->identifier_len);
      id[stmt->getStmtId()->identifier_len] = 0;

      init_SQLMODULE_ID(&sql_module);
      init_SQLSTMT_ID(&sql_stmt, SQLCLI_CURRENT_VERSION, 
		      (SQLOBJ_ID_NAME_MODE)stmt->getStmtId()->name_mode, 
		      &sql_module,
		      id, stmt->getStmtId()->handle, stmt->getStmtId()->charset,stmt->getStmtId()->identifier_len);
      aqrSI->setRetryStatementId(&sql_stmt);
     
      charset = NULL;
      charset = new(currContext->exHeap()) char[strlen(SQLCHARSETSTRING_UTF8)+1];
      strcpy(charset, SQLCHARSETSTRING_UTF8);

      init_SQLDESC_ID(&sql_src, SQLCLI_CURRENT_VERSION, string_data,
		      NULL, NULL, 0, charset);
      sql_src.identifier_len = stmt->getSrcStrSize();
      sql_src.identifier = 
	new(currContext->exHeap()) char[sql_src.identifier_len + 2];
      stmt->copyOutSourceStr((char*)sql_src.identifier, sql_src.identifier_len);

      //Int32 isoMapping = SQLCHARSETCODE_ISO_MAPPING; //;
      //if (isoMapping != 0)
      //retcode = SQL_EXEC_SetDescItem(&sql_src, 1, SQLDESC_CHAR_SET,  
      //			       isoMapping,0);

      aqrSI->setRetrySqlSource(&sql_src);

      aqrSI->setRetryInputDesc(stmt->aqrStmtInfo()->getRetryInputDesc());
      aqrSI->setRetryOutputDesc(stmt->aqrStmtInfo()->getRetryOutputDesc());
      aqrSI->setRetryPrepareFlags(stmt->aqrStmtInfo()->getRetryPrepareFlags());
      aqrSI->setRetryFirstFetch(stmt->aqrStmtInfo()->retryFirstFetch());
      aqrSI->setRetryAfterExec(stmt->aqrStmtInfo()->retryAfterExec());

      // Save of any statement attributes or other info from the old
      // statement object into the AQR statement attribute struct
      if(stmt)
	{
	  aqrSI->saveAttributesFromStmt(stmt);
	}
      
      aqrSI->saveStatementHandle(stmt->getStmtId());
      aqr->setAqrStmtInfo(aqrSI);

    }
  else
    return retcode;

  NABoolean done = FALSE;
  Lng32 numRetries = 0;
  Lng32 retries = 0;
  Lng32 delay = 0;
  Lng32 type = 0;
  Lng32 numCQDs = 0;
  char * cqdStr = NULL;
  Lng32 cmpInfo = 0;
  ComCondition * cc = NULL;
  ComCondition * errCond = NULL;
  Lng32 aqrDelay = 0;
  Lng32 aqrCmpInfo = 0;
  
  while (NOT done)
    {
      if (NOT SQLCLI_GetRetryInfo(
	   cliGlobals, retcode, aqrSI,
	   afterPrepare, afterExec, afterFetch, afterCEFC,
	   retries, delay, type,
	   numCQDs, cqdStr,
	   cmpInfo,
	   cc))
	done = TRUE;
      else
      {
        // need to check again if aqr is enabled on root because
        // the previous retry may have disabled AQR
        stmt = currContext->getStatement(statement_id);
        if (stmt && stmt->getRootTdb())
        {
          if (NOT stmt->getRootTdb()->aqrEnabledForSqlcode(sqlcode))
            done = TRUE;
          else if (checkAqrWnr && 
                   preventAqrWnr(currContext, stmt, addWarning8737))
            done = TRUE;
        }
        if (!done)
        {
	  if (numRetries == 0)
	    {
	      // first retry.
	      // Save the error condition which caused this retry.
	      if (cc)
		{
		  errCond = ComCondition::allocate(currContext->exHeap());
		  *errCond = *cc;
		}

	      // set cqds before reprepare
	      if (numCQDs > 0)
		{
		  // set the desired cqds before recompiling the query.
		  retcode = aqr->setCQDs(numCQDs, cqdStr, currContext);
		  if (retcode < 0)
		    {
		      return retcode;
		    }
		}

	      if (cmpInfo == 1)
		{
		  // send relevant information to compiler through a
		  // control session statement.
		  retcode = 
		    aqr->setCompilerInfo(stmt->getUniqueStmtId(),
					 errCond,
					 currContext);
		  if (retcode < 0)
		    {
		      return retcode;
		    }
		  
		}
              aqrDelay = delay;
              aqrCmpInfo = cmpInfo;
	    }

	  if (numRetries < retries)
	    {
	      if (type == AQRInfo::RETRY_WITH_ESP_CLEANUP)
		aqr->setEspCleanup(TRUE);

	      // Before deallocating the statement, set an indication in the 
	      // master stats for this query id to indicate that AQR is being 
	      // done 
              
              // Get the statement again in case if was reallocated in the 
              // previous loop.
              stmt = currContext->getStatement(statement_id);
	      if(stmt && stmt->getStmtStats())
		{
		  stmt->getStmtStats()->setAqrInProgress(TRUE);
		  ExMasterStats *ms = (stmt->getStmtStats())->getMasterStats();
		  if (ms)
		    {		      
		      ms->setAqrLastErrorCode(sqlcode);
		      ms->setNumAqrRetries(numRetries+1);		    
		      ms->setAqrDelayBeforeRetry(delay);
		    }
		}
	      if (afterPrepare && ((type == AQRInfo::RETRY_MXCMP_KILL)))
		{
		  // Kill the current mxcmp. A new one will get started
		  // when  the query is prepared
		  ExeCliInterface *cliInterface = new (currContext->exHeap()) 
		    ExeCliInterface(currContext->exHeap(),
				      SQLCHARSETCODE_UTF8,
				      currContext,
				      NULL);   
                    ComDiagsArea *tmpDiagsArea = &diags;
		  retcode =  cliInterface->
		    executeImmediate( (char *) "SELECT TESTEXIT;", 
				      NULL, NULL, TRUE, NULL, 0, &tmpDiagsArea);
		  //ignore errors from this call.
		  	    
		}
	      else
		// only kill mxcmp if the retry error happened suring a prepare
		// otherwise return it to the user.
		   if (!afterPrepare && ((type == AQRInfo::RETRY_MXCMP_KILL)))
		     {
                       if (stmt->getStmtStats())
                         stmt->getStmtStats()->setAqrInProgress(FALSE);
		       return retcode;
		     }
	      
	      // deallocate the statement before the delay.

              StmtStats *saveStmtStat = NULL;
              if (stmt)
                saveStmtStat = stmt->getStmtStats();

	      // if the original statement_id had its 'handle' field pointed to
	      // StatementInfo struct to do stmt lookup optimization(see method
	      // SQLCLI_PerformTasks for details), reset that field.
	      // The original statement now deallocated and
	      // any reference to it(StatementInfo struct points to it) is invalid.
	      if ( ((statement_id->name_mode != desc_handle) && (afterCEFC))
		   ||(statement_id->name_mode == stmt_name))	      
		statement_id->handle = NULL;
              
	      retcode =
		SQLCLI_RetryDeallocStmt(cliGlobals, aqrSI);

	      if (isERROR(retcode))
		{
		  if (saveStmtStat)
		    {
		      saveStmtStat->setAqrInProgress(FALSE);
		      ExMasterStats *ms = saveStmtStat->getMasterStats();
		      if (ms)
			{
			  ms->setAqrLastErrorCode(0);
			  ms->setNumAqrRetries(0);
			  ms->setAqrDelayBeforeRetry(0);
			}

		    }
		}
	      // delay for the specified 'delay'
	      if (NOT isERROR(retcode) && (delay >= 0))
		{
		  Sleep(delay * 1000);
		}

	      numRetries++;

	      if (NOT isERROR(retcode))
		{
		  ULng32 flags = aqrSI->getRetryPrepareFlags();
		  flags |= PREPARE_AUTO_QUERY_RETRY;

		  if (type == AQRInfo::RETRY_WITH_DECACHE)
		    flags |= PREPARE_WITH_DECACHE;
                   		 
		  // log an ems event, unless disabled or if regressions
		  // are running.
		  char *sqlmxRegr = NULL;
		  sqlmxRegr = getenv("SQLMX_REGRESS");
		  if ((currContext->getSessionDefaults()->getAqrEmsEvent()) &&
		      (sqlmxRegr == NULL))
		    {
		      Lng32 sqlcode = 0;
		      Lng32 nskcode = 0;
		      char * stringParam1 = NULL;
		      Lng32 intParam1 = ComDiags_UnInitialized_Int;
		      char emsText[300];
		      if (errCond)
			{
			  sqlcode = errCond->getSQLCODE();
			  nskcode = errCond->getNskCode();
			  if (errCond->getOptionalStringCharSet(0) == CharInfo::ISO88591)
			    stringParam1 = (char*)errCond->getOptionalString(0);
			  intParam1 = errCond->getOptionalInteger(0);
			  
			  str_sprintf(emsText, "AutoQueryRetry will be attempted for Sqlcode=%d, Nskcode=%d, StringParam=%s, IntParam=%d",
				      sqlcode, nskcode, 
				      (stringParam1 ? stringParam1 : "NULL"),
				      (intParam1 != ComDiags_UnInitialized_Int
				       ? intParam1 : 0));
			}
		      else
			{
			  str_sprintf(emsText, "AutoQueryRetry will be attempted");
			}

		      SQLMXLoggingArea::logExecRtInfo(NULL, 0, emsText, 0);
		    }

		  retcode = 
		    SQLCLI_RetryQuery(
			 cliGlobals, aqrSI, flags,
			 afterPrepare, afterExec, afterFetch, afterCEFC, saveStmtStat);
		}

	      if (type == AQRInfo::RETRY_WITH_ESP_CLEANUP)
		aqr->setEspCleanup(FALSE);
	    }
	  else
	    {
	      done = TRUE;
	    }
	}
      }
    }

  if (numRetries > 0)
    {
      if (numCQDs > 0)
        {
          // reset the desired cqds after recompiling the query.
          Lng32 rc = aqr->resetCQDs(numCQDs, cqdStr, currContext);

          if (rc < 0)
            return rc;
        }
	  
      if (aqrCmpInfo == 1)
        {
          // reset the control session stmt.
          Lng32 rc = aqr->resetCompilerInfo(stmt->getUniqueStmtId(),
                                            errCond,
                                            currContext);
          if (rc < 0)
            return rc;
        }

      // if recomp warnings are to be returned, then add a warning.
      // Also return the error which was previously returned to the caller 
      // causing the retry. 
      if (currContext->getSessionDefaults()->aqrWarnings() != 0)
	{
	  NABoolean add100 = FALSE;
	  if ((NOT isERROR(retcode)) &&
	      (diags.getNumber(DgSqlCode::ERROR_) == 0) &&
	      (diags.mainSQLCODE() == SQL_EOF))
	    {
	      diags.removeFinalCondition100();
	      add100 = TRUE;
	    }

	  diags << DgSqlCode(EXE_RECOMPILE_AUTO_QUERY_RETRY)  // a warning only
		<< DgInt0(numRetries)
		<< DgInt1(aqrDelay)
		<< DgString0("")
		<< (errCond
		    ? DgString1("See next entry for the error that caused this retry.")
		    : DgString1(""));

	  if (errCond)
	    {
	      ComCondition * newCC = diags.makeNewCondition();
	      *newCC = *errCond;
	      if (isERROR(newCC->getSQLCODE()))
		newCC->setSQLCODE(- newCC->getSQLCODE());
	      diags.acceptNewCondition(); 
	    }

          if (NOT isERROR(retcode) && addWarning8737)
            diags << DgSqlCode(CLI_INVALID_ROWS_AFFECTED);

	  if (add100)
	    {
	      retcode = diags.mainSQLCODE();
	      diags << DgSqlCode(SQL_EOF);
	    }

	  if (isSUCCESS(retcode))
	    retcode = EXE_RECOMPILE_AUTO_QUERY_RETRY;
	  else if (isEOF(retcode))
	    {
	      //if (aqrSI->getRetryOutputDesc() == NULL)
	      //retcode = EXE_RECOMPILE_AUTO_QUERY_RETRY;
	    }
	}
    }

  if ((isERROR(retcode)) &&
      (numRetries > 0))
    {
      // close this stmt. Ignore errors, the stmt may already be closed.
      // Rewind diags area to get rid of any errors from SQLCLI_CloseStmt.
      Lng32 oldDiagsAreaMark = diags.mark();
      Lng32 rc = SQLCLI_CloseStmt(cliGlobals, aqrSI->getRetryStatementId());
      diags.rewind(oldDiagsAreaMark, TRUE);
    }

  // Retry done. Clear up any retry related information
  // before returning.
  if (charset)
    currContext->exHeap()->deallocateMemory((void *)charset);
  if (sql_src.identifier)
    currContext->exHeap()->deallocateMemory((void *)sql_src.identifier);
  if (stmtId)
    NADELETEBASIC(stmtId, currContext->exHeap());
  if (id)
    NADELETEBASIC(id, currContext->exHeap());

  Statement *newStmt = currContext->getStatement(aqrSI->getRetryStatementId());
  StmtStats *stmtStats = (newStmt ? newStmt->getStmtStats() : NULL);
  if (stmtStats)
    stmtStats->setAqrInProgress(FALSE);

  aqr->clearRetryInfo();

  if (aqrSI)
    {
      if (aqrSI->getRetryTempInputDesc())
	{
	  SQLCLI_DeallocDesc(cliGlobals, aqrSI->getRetryTempInputDesc());
	  NADELETEBASIC(aqrSI->getRetryTempInputDesc()->module, currContext->exHeap());
	  NADELETEBASIC(aqrSI->getRetryTempInputDesc(), currContext->exHeap());
	  aqrSI->setRetryTempInputDesc(NULL);
	}

      if (aqrSI->getRetryTempOutputDesc())
	{
	  SQLCLI_DeallocDesc(cliGlobals, aqrSI->getRetryTempOutputDesc());
	  NADELETEBASIC(aqrSI->getRetryTempOutputDesc()->module, currContext->exHeap());
	  NADELETEBASIC(aqrSI->getRetryTempOutputDesc(), currContext->exHeap());
	  aqrSI->setRetryTempOutputDesc(NULL);
	}
     
      //aqrSI->clearRetryInfo();
       NADELETE(aqrSI, AQRStatementInfo, currContext->exHeap());
       aqrSI=NULL;
    }

  if (errCond)
    errCond->deAllocate();

  return retcode;
}

////////////////////////////////////////////////////////////////////////
// This method is called by various Exec, Fetch and Close methods. 
// It performs the tasks (see enum CliTasks) that are asked for.
// 
////////////////////////////////////////////////////////////////////////
Lng32 SQLCLI_PerformTasks(
     /*IN*/ CliGlobals * cliGlobals,
     /*IN*/ ULng32 tasks,
     /*IN*/ SQLSTMT_ID * statement_id,
     /*IN  OPTIONAL*/ SQLDESC_ID * input_descriptor,
     /*IN  OPTIONAL*/ SQLDESC_ID * output_descriptor,
     /*IN*/ Lng32 num_input_ptr_pairs,
     /*IN*/ Lng32 num_output_ptr_pairs,
     /*IN*/ va_list ap,
     /*IN*/ SQLCLI_PTR_PAIRS input_ptr_pairs[],
     /*IN*/ SQLCLI_PTR_PAIRS output_ptr_pairs[])
{
  Lng32 retcode = SUCCESS;

  if (!statement_id)
    return -CLI_STMT_NOT_EXISTS;

  ContextCli   & currContext = *(cliGlobals->currContext());
  ComDiagsArea & diags       = currContext.diags();
  
  StatementInfo * stmtInfo = NULL;
  StmtStats *stmtStats = NULL;
  if ((tasks & CLI_PT_OPT_STMT_INFO) && 
      (statement_id->name_mode != desc_handle))
    {
      stmtInfo = (StatementInfo *)(statement_id->handle);
      if (stmtInfo == NULL)
	{
	  // when do we deallocate this heap? Or do we?
	  CollHeap * heap = cliGlobals->currContext()->exCollHeap();
	  stmtInfo = new(heap) StatementInfo();
	  statement_id->handle = stmtInfo;
	}
    }

  // create initial context, if first call, and add module, if any.
  if (tasks & CLI_PT_PROLOGUE)
    {
      retcode = CliPrologue(cliGlobals, 
			    ((stmtInfo && stmtInfo->moduleAdded()) ?
			     NULL : statement_id->module));
      if (isERROR(retcode))
	return retcode;

      if (stmtInfo)
	stmtInfo->setModuleAdded(TRUE);
    }
  else
    {
      // module must have been added
      if ((statement_id->module) &&
	  (statement_id->module->module_name) &&
	  (!currContext.moduleAdded(statement_id->module)))
	{
	  diags << DgSqlCode(-CLI_MODULE_NOT_ADDED);
	  return SQLCLI_ReturnCode(&currContext,
				   -CLI_MODULE_NOT_ADDED);
	}
    }

  if (tasks & CLI_PT_CLEAR_DIAGS)
    {
      // Don't clear diags if this is a recursive call.  Otherwise,
      // warning conditions that have acumulated will be lost.
      if (currContext.getNumOfCliCalls() == 1)
        diags.clear();
    }
  Int64 startTime = NA_JulianTimestamp();

  /* stmt must exist */
  Statement * stmt = NULL;
  if ((stmtInfo) && (stmtInfo->statement()))
    stmt = stmtInfo->statement();
  else
    {
      stmt = currContext.getStatement(statement_id);
      if (!stmt)
	{
	  diags << DgSqlCode(-CLI_STMT_NOT_EXISTS);
	  return SQLCLI_ReturnCode(&currContext,-CLI_STMT_NOT_EXISTS);
	}
     if (stmtInfo)
       {
	 stmtInfo->statement() = stmt;
         stmt->setStmtInfo(stmtInfo);
	 if (tasks & CLI_PT_CLEAREXECFETCHCLOSE)
	   stmt->setOltOpt(TRUE);
       }
    }
  stmt->getGlobals()->setNoNewRequest(FALSE);

  Descriptor * input_desc = NULL;
  Descriptor * output_desc = NULL;

  va_list cpy;

  if (num_input_ptr_pairs || num_output_ptr_pairs)
     va_copy(cpy, ap);

  if (tasks & CLI_PT_GET_INPUT_DESC)
    { 
      NABoolean setPtrs = FALSE;
      if ((stmtInfo) && (stmtInfo->inputDesc()))
	{
	  input_desc = stmtInfo->inputDesc();
	  setPtrs = TRUE;
	  // If this call is made from multiple callers and the stack address
	  // of input pointers are not the same, then this optimization
	  // incorrectly uses the previously set pointers.
	  // It needs to be enhanced so it either validates that the stack
	  // is the same as the previous call or that the pointers are
	  // not stack addresses.
	  // Removing this optimization for now.
	  setPtrs = TRUE;
	}
      else
	{
	  if (!input_descriptor)
	    input_desc = stmt->getDefaultDesc(SQLWHAT_INPUT_DESC);
	  else 
	    input_desc = currContext.getDescriptor(input_descriptor);

	  if (stmtInfo)
	    stmtInfo->inputDesc() = input_desc;

	  setPtrs = TRUE;
	}

      if ((setPtrs) && (num_input_ptr_pairs > 0))
	{
	  /* descriptor must exist */
	  if (!input_desc)
	    {
	      diags << DgSqlCode(-CLI_DESC_NOT_EXISTS);
	      return SQLCLI_ReturnCode(&currContext,-CLI_DESC_NOT_EXISTS);
	    }
	  retcode = local_SetDescPointers(input_desc, 1,
					  num_input_ptr_pairs, &cpy, input_ptr_pairs);
	  if (isERROR(retcode))
	    return SQLCLI_ReturnCode(&currContext,retcode);
	}
    }
  
  if (tasks & CLI_PT_GET_OUTPUT_DESC)
    {
      NABoolean setPtrs = FALSE;
      if ((stmtInfo) && (stmtInfo->outputDesc()))
	{
	  output_desc = stmtInfo->outputDesc();
	  setPtrs = TRUE;
	  // If this call is made from multiple callers and the stack address
	  // of output pointers are not the same, then this optimization
	  // incorrectly uses the previously set pointers.
	  // It needs to be enhanced so it either validates that the stack
	  // is the same as the previous call or that the pointers are
	  // not stack addresses.
	  // Removing this optimization for now.
	  setPtrs = TRUE;
	}
      else
	{
	  if (!output_descriptor)
	    output_desc = stmt->getDefaultDesc(SQLWHAT_OUTPUT_DESC);
	  else
	    output_desc = currContext.getDescriptor(output_descriptor);

	  if (stmtInfo)
	    stmtInfo->outputDesc() = output_desc;      

	  setPtrs = TRUE;
	}

      if ((setPtrs) && (num_output_ptr_pairs > 0))
	{
	  // if we do have something to set... the output descriptor
	  // had better be available by the time we call local_SetDescPointers
	  //
	  if (!output_desc)
	    {
	      diags << DgSqlCode(-CLI_DESC_NOT_EXISTS);
	      return SQLCLI_ReturnCode(&currContext,-CLI_DESC_NOT_EXISTS);
	    }

	  retcode = local_SetDescPointers(output_desc, 1,
					  num_output_ptr_pairs, &cpy, output_ptr_pairs);
	  if (isERROR(retcode))
	    return SQLCLI_ReturnCode(&currContext,retcode);
	}
    }

  va_end(ap);
  stmtStats = stmt->getStmtStats();
  // Execute the statement.
  if (tasks & CLI_PT_EXEC)
    {
      if (tasks & CLI_PT_SET_AQR_INFO)
	{
	  if (stmt->aqrStmtInfo())
	    {
	      stmt->aqrStmtInfo()->setRetryInputDesc(input_descriptor);
	    }
	}

      Lng32 retcode;
      retcode = CheckNOSQLAccessMode(*cliGlobals);
      if(isERROR(retcode)){
	return retcode;
      }
      
      if ((stmt->getRootTdb()) &&
	  (((ComTdb*)stmt->getRootTdb())->getCollectStats()))
	{
	  stmt->getGlobals()->setStatsEnabled(TRUE);
#ifdef _DEBUG
	  if (getenv("DISABLE_STATS"))
	    stmt->getGlobals()->setStatsEnabled(FALSE);
#endif
	}

      if (!stmt->noWaitOpPending())
        stmt->getGlobals()->clearCancelState();

      // if OLT optimization is being done, call our special
      // execute method(doOltExecute).
      // Only done for embedded, waited requests...these requests
      // have their version set to VERSION_1.
      NABoolean doNormalExecute = FALSE;
      NABoolean reExecute = FALSE;

      if ( stmtInfo && stmt->oltOpt() &&
	   ( statement_id->version == SQLCLI_STATEMENT_VERSION_1 ||
	     ( statement_id->version == SQLCLI_STATEMENT_VERSION_2
	       )
	     )
	   )
	{
	  retcode = stmt->doOltExecute(cliGlobals, input_desc,output_desc, diags,
				       doNormalExecute, reExecute);
	  
	  // redrive this query using normal execution, if doNormalExecute
	  // is TRUE. This could happen for certain cases, like timestamp
	  // mismatch or blown away opens. These cases are not handled
	  // by fastpath OLT execution.
	  if (NOT doNormalExecute)
	    {
              if (stmt->getState() != Statement::CLOSE_)
                stmt->close(diags);
 	      return CliEpilogue(cliGlobals,statement_id,retcode);
	    }
	}


      if (input_desc)
	{
	  if (stmt->computeInputDescBulkMoveInfo())
	    {
	      input_desc->reComputeBulkMoveInfo();
	      stmt->setComputeInputDescBulkMoveInfo(FALSE);
	    }
	  else if (NOT input_desc->bulkMoveDisabled())
	    {
	      if (input_desc->bulkMoveStmt() != stmt)
		input_desc->reComputeBulkMoveInfo();
	    }
	}

      Statement::ExecState execute_state =Statement::INITIAL_STATE_;
      if (reExecute)
       execute_state = Statement::RE_EXECUTE_;

      retcode = stmt->execute(cliGlobals, input_desc,diags,
			      execute_state );
      if (isERROR(retcode))
	{
	  if (stmt->aqrStmtInfo())
	    stmt->aqrStmtInfo()->setRetryAfterExec(TRUE);

          // If statement is in a closeable state, then
	  // close on error but return the retcode from execute.
	  if ( 
               (tasks & CLI_PT_CLOSE_ON_ERROR)   &&
               (stmt->getState() == Statement::OPEN_      ||
                stmt->getState() == Statement::FETCH_     ||
                stmt->getState() == Statement::EOF_       ||
                stmt->getState() == Statement::RELEASE_TRANS_ ||
                stmt->getState() == Statement::PREPARE_)
             )
	    stmt->close(diags);
            return CliEpilogue(cliGlobals,statement_id,retcode);
	}

      // if bulk move was done, remember the statement it was done for.
      if ((input_desc) && (NOT input_desc->bulkMoveDisabled()))
	{
	  //if (getenv("BULKMOVEWARN"))
	  //  diags << DgSqlCode(EXE_ERROR_NOT_IN_USE_8350);

	  input_desc->bulkMoveStmt() = stmt;
	}
    }

  // do a fetch to retrieve one row or EOD. 
  if (tasks & CLI_PT_FETCH)
    {
      if (tasks & CLI_PT_SET_AQR_INFO)
	{
	  if (stmt->aqrStmtInfo())
	    {
	      stmt->aqrStmtInfo()->setRetryOutputDesc(output_descriptor);
	    }
	}

      // In case of multiple cursors fetching into the same descriptor,
      // the bulkMove flag in the descriptor applies to the statement/cursor
      // it was computed for. Validate that the current statement is the
      // one bulk move was done for. If not, reset bulk move flag so
      // bulk move compatibility checks could be done again in
      // outputValues.

      // disable rowwise rowset fetch for ExeUtil operator.
      // This is done so status messages could be returned to caller as 
      // soon as they are sent up by executor. With RWRS, returned msgs
      // will be blocked until the output rowset is filled up.
      if (output_desc)
	{
	  if (stmt->computeOutputDescBulkMoveInfo())
	    {
	      output_desc->reComputeBulkMoveInfo();
	      stmt->setComputeOutputDescBulkMoveInfo(FALSE);

	      if ((currContext.getSessionDefaults()->getCliBulkMove() == FALSE) ||
		  ((stmt->getRootTdb()) &&
		   (stmt->getRootTdb()->getQueryType() == ComTdbRoot::SQL_EXE_UTIL) &&
		   (NOT stmt->getRootTdb()->exeUtilRwrs())))
		{
		  output_desc->setBulkMoveDisabled(TRUE);
		  output_desc->setRowwiseRowsetDisabled(TRUE);
		}
	    }
	  else if (NOT output_desc->bulkMoveDisabled())
	    {
	      if ((currContext.getSessionDefaults()->getCliBulkMove() == FALSE) ||
		  ((stmt->getRootTdb()) &&
		   (stmt->getRootTdb()->getQueryType() == ComTdbRoot::SQL_EXE_UTIL) &&
		   (NOT stmt->getRootTdb()->exeUtilRwrs())))
		{
		  output_desc->setBulkMoveDisabled(TRUE);
		  output_desc->setRowwiseRowsetDisabled(TRUE);
		}
	      else if (output_desc->bulkMoveStmt() != stmt)
		{
		  output_desc->reComputeBulkMoveInfo();
		  output_desc->bulkMoveStmt() = stmt;
		}
	    }
	}


      // if this statement is already in FETCH_ state
      if ((stmt->getState() == Statement::INITIAL_) ||
	  (stmt->getState() == Statement::OPEN_))
	{
	  if (stmt->aqrStmtInfo())
	    stmt->aqrStmtInfo()->setRetryFirstFetch(TRUE);
	}
      else
	if (stmt->aqrStmtInfo())
	    stmt->aqrStmtInfo()->setRetryFirstFetch(FALSE);

      retcode = stmt->fetch(cliGlobals, output_desc, diags, TRUE);

      if (isERROR(retcode))
	{
	  return CliEpilogue(cliGlobals,statement_id,retcode);
	}
      else if (retcode == WARNING)
        {
        Lng32 mainSQLcode = diags.mainSQLCODE();
        }

      // if select into query, then make sure that atmost one
      // row is returned by executor. More than one would
      // result in an error.
      if ((stmt->isSelectInto()) &&
          (retcode == SUCCESS))
        {
	  // BertBert VV
	  if (stmt->isEmbeddedUpdateOrDelete() || stmt->isStreamScan())
	    {
	    // For streams and destructive selects, we don't want the above behavior,
	    //  instead, we should just return the first row.
	    }
	  // BertBert ^^
	  else
	    {
	      // select into and a row was returned.
	      // See if we can get one more row.
	      // Do not send in an output desc. We want
	      // to return the first row to application.
	      // This is being consistent with SQL/MP behavior.
	      retcode = stmt->fetch(cliGlobals, 0 /*no output desc*/,diags, TRUE);
	      if (retcode == SUCCESS)
		{
		  diags << DgSqlCode(-CLI_SELECT_INTO_ERROR);
		  stmt->close(diags);
		  return CliEpilogue(cliGlobals,statement_id,-CLI_SELECT_INTO_ERROR);
		}
	      
	      if (retcode == SQL_EOF)
		{
		  // remove warning 100 from diags.
		  diags.removeFinalCondition100();

		  retcode = SUCCESS;
		}
	    }
        }

      if ((output_desc == NULL) && (retcode == SQL_EOF))
	{
	  // remove warning 100 from diags.
	  diags.removeFinalCondition100();
	  
	  retcode = SUCCESS;
	}
    }

  // Close the statement.
  if (tasks & CLI_PT_CLOSE)
    {
      Lng32 tretcode = stmt->close(diags);

      if (isERROR(tretcode))
      {
	return CliEpilogue(cliGlobals,statement_id,tretcode);
      }
    }

  if (tasks & CLI_PT_SPECIAL_END_PROCESS)
    {
      if (stmt->handleUpdDelCurrentOf(diags) == SQL_EOF)
	retcode = SQL_EOF;
    }
      
  if (tasks & CLI_PT_EPILOGUE)
    return CliEpilogue(cliGlobals,statement_id,retcode);
  else
    return SQLCLI_ReturnCode(&currContext,retcode);
}

Lng32 SQLCLI_CloseStmt(/*IN*/ CliGlobals * cliGlobals,
		      /*IN*/ SQLSTMT_ID * statement_id)
{

  ULng32 tasks = CLI_PT_PROLOGUE | CLI_PT_CLOSE | CLI_PT_EPILOGUE |
                        // stmt lookup opt also done for version_2 queries
                        // with stmt_name name mode. Currently only jdbc
                        // could make use of this optimization.
                        (((statement_id->version == SQLCLI_STATEMENT_VERSION_2) &&
			  (statement_id->name_mode == stmt_name))
			 ? CLI_PT_OPT_STMT_INFO : 0);

  return SQLCLI_PerformTasks(cliGlobals, tasks, statement_id,
			     NULL, NULL, 0, 0, NULL, 0, 0);
}

Lng32 SQLCLI_Exec(/*IN*/   CliGlobals * cliGlobals,
         /*IN*/           SQLSTMT_ID * statement_id,
         /*IN  OPTIONAL*/ SQLDESC_ID * input_descriptor,
         /*IN*/                 Lng32   num_ptr_pairs,
         /*IN*/              va_list   ap,
         /*IN*/     SQLCLI_PTR_PAIRS   ptr_pairs[])
{


  ULng32 tasks = CLI_PT_PROLOGUE | CLI_PT_GET_INPUT_DESC | 
                        CLI_PT_EXEC | CLI_PT_SET_AQR_INFO | CLI_PT_EPILOGUE |
                        // stmt lookup opt also done for version_2 queries
                        // with stmt_name name mode. Currently only jdbc
                        // could make use of this optimization.
                        (((statement_id->version == SQLCLI_STATEMENT_VERSION_2) &&
			  (statement_id->name_mode == stmt_name))
			 ? CLI_PT_OPT_STMT_INFO : 0);
  return SQLCLI_PerformTasks(cliGlobals, tasks, statement_id,
			     input_descriptor, NULL,
			     num_ptr_pairs, 0, ap, ptr_pairs, 0);
}

Lng32 SQLCLI_ExecClose(/*IN*/   CliGlobals * cliGlobals,
              /*IN*/           SQLSTMT_ID * statement_id,
              /*IN  OPTIONAL*/ SQLDESC_ID * input_descriptor,
              /*IN*/                 Lng32   num_ptr_pairs,
              /*IN*/              va_list   ap,
              /*IN*/     SQLCLI_PTR_PAIRS   ptr_pairs[])
{


ULng32 tasks = CLI_PT_PROLOGUE | CLI_PT_GET_INPUT_DESC |
                        CLI_PT_EXEC | CLI_PT_CLOSE_ON_ERROR | 
                        CLI_PT_EPILOGUE
                        ;
  return SQLCLI_PerformTasks(cliGlobals, tasks, statement_id,
                 input_descriptor, NULL,
                 num_ptr_pairs, 0, ap, ptr_pairs, 0);
}


/////////////////////////////////////////////////////////////////
// if sql_source->name_mode is string_data, then
// sql_source->identifier points to the sql_source string and
// identifier_len is the length of that string.
/////////////////////////////////////////////////////////////////
Lng32 SQLCLI_ExecDirect(/*IN*/           CliGlobals * cliGlobals,
               /*IN*/           SQLSTMT_ID * statement_id,
               /*IN*/           SQLDESC_ID * sql_source,
               /*IN  OPTIONAL*/ SQLDESC_ID * input_descriptor,
               /*IN*/                 Lng32   num_ptr_pairs,
               /*IN*/              va_list   ap,
               /*IN*/     SQLCLI_PTR_PAIRS   ptr_pairs[])
{
  Lng32 retcode;


  // create initial context, if first call, and add module, if any.
  retcode = CliPrologue(cliGlobals,statement_id->module);
  if (isERROR(retcode))
    return retcode;
  
  ContextCli   & currContext = *(cliGlobals->currContext());
  ComDiagsArea & diags       = currContext.diags();

  /* prepare the statement */

  Statement * stmt = currContext.getStatement(statement_id);
  /* stmt must exist */
  if (!stmt)
    {
      diags << DgSqlCode(-CLI_STMT_NOT_EXISTS);
      return SQLCLI_ReturnCode(&currContext,-CLI_STMT_NOT_EXISTS);
    }
  stmt->getGlobals()->clearCancelState();

  StrTarget strTarget;
  retcode = stmt->initStrTarget(sql_source, currContext, diags, strTarget);
  if (isERROR(retcode))
    return SQLCLI_ReturnCode(&currContext,retcode);
  // CLI callers are not allowed to request PREPARE or EXEC DIRECT
  // operations on stored procedure result sets.
  if (stmt->getParentCall())
  {
    diags << DgSqlCode(-EXE_UDR_RS_PREPARE_NOT_ALLOWED);
    return SQLCLI_ReturnCode(&currContext, -EXE_UDR_RS_PREPARE_NOT_ALLOWED);
  }

  // For ExecDirect, MXOSRVR calls SQL_EXEC_SetStmtAttr(NULL) to set the unique id
  // before calling SQL_EXEC_EXECDirect. So, we need to use them
  if (stmt->getUniqueStmtId() == NULL)
    stmt->setUniqueStmtId(NULL);
  // Set the StmtStats in the shared segment
  stmt->setStmtStats(FALSE);
  SQLCLI_Prepare_Setup_Pre(currContext, stmt, 1);
  UInt32 flags; 
  SessionDefaults *sd = currContext.getSessionDefaults();
  if (sd != NULL && sd->getCallEmbeddedArkcmp())
     flags = PREPARE_USE_EMBEDDED_ARKCMP;
  else 
     flags = 0;
    
  retcode =
   stmt->prepare(strTarget.getStr(), diags, NULL, 0L, 
		 strTarget.getIntCharSet(), TRUE, flags);

  SQLCLI_Prepare_Setup_Post(currContext, stmt, 1);

  if (isERROR(retcode))
    return SQLCLI_ReturnCode(&currContext,retcode);
  
  stmt->issuePlanVersioningWarnings (diags);

  ULng32 tasks = CLI_PT_GET_INPUT_DESC | CLI_PT_EXEC | CLI_PT_FETCH |
                        CLI_PT_CLOSE |CLI_PT_SPECIAL_END_PROCESS | CLI_PT_EPILOGUE;
  return SQLCLI_PerformTasks(cliGlobals, tasks, statement_id,
			     input_descriptor, NULL,
			     num_ptr_pairs, 0, ap, ptr_pairs, 0);
}
/////////////////////////////////////////////////////////////////
// if sql_source->name_mode is string_data, then
// sql_source->identifier points to the sql_source string and
// identifier_len is the length of that string.
/////////////////////////////////////////////////////////////////
Lng32 SQLCLI_ExecDirect2(/*IN*/           CliGlobals * cliGlobals,
               /*IN*/           SQLSTMT_ID * statement_id,
               /*IN*/           SQLDESC_ID * sql_source,
	       /*IN*/           Int32 prepFlags,
               /*IN  OPTIONAL*/ SQLDESC_ID * input_descriptor,
               /*IN*/                 Lng32   num_ptr_pairs,
               /*IN*/              va_list   ap,
	       /*IN*/     SQLCLI_PTR_PAIRS   ptr_pairs[]
	       )
{
  Lng32 retcode;


  // create initial context, if first call, and add module, if any.
  retcode = CliPrologue(cliGlobals,statement_id->module);
  if (isERROR(retcode))
    return retcode;
  
  ContextCli   & currContext = *(cliGlobals->currContext());
  ComDiagsArea & diags       = currContext.diags();

  /* prepare the statement */

  Statement * stmt = currContext.getStatement(statement_id);
  /* stmt must exist */
  if (!stmt)
    {
      diags << DgSqlCode(-CLI_STMT_NOT_EXISTS);
      return SQLCLI_ReturnCode(&currContext,-CLI_STMT_NOT_EXISTS);
    }
  stmt->getGlobals()->clearCancelState();

  StrTarget strTarget;
  retcode = stmt->initStrTarget(sql_source, currContext, diags, strTarget);
  if (isERROR(retcode))
    return SQLCLI_ReturnCode(&currContext,retcode);
  // CLI callers are not allowed to request PREPARE or EXEC DIRECT
  // operations on stored procedure result sets.
  if (stmt->getParentCall())
  {
    diags << DgSqlCode(-EXE_UDR_RS_PREPARE_NOT_ALLOWED);
    return SQLCLI_ReturnCode(&currContext, -EXE_UDR_RS_PREPARE_NOT_ALLOWED);
  }

  // For ExecDirect, MXOSRVR calls SQL_EXEC_SetStmtAttr(NULL) to set the unique id
  // before calling SQL_EXEC_EXECDirect. So, we need to use them
  if (stmt->getUniqueStmtId() == NULL)
    stmt->setUniqueStmtId(NULL);
  // Set the StmtStats in the shared segment
  stmt->setStmtStats(FALSE);
  SQLCLI_Prepare_Setup_Pre(currContext, stmt, 1);
  UInt32 tmpFlags;
  SessionDefaults *sd = currContext.getSessionDefaults();
  if (sd != NULL && sd->getCallEmbeddedArkcmp())
      tmpFlags = prepFlags | PREPARE_USE_EMBEDDED_ARKCMP;
  else
      tmpFlags = prepFlags;
  if (sql_source)
  
  retcode =
   stmt->prepare(strTarget.getStr(), diags, NULL, 0L, 
		  strTarget.getIntCharSet(),TRUE,tmpFlags);

  SQLCLI_Prepare_Setup_Post(currContext, stmt, 1);

  if (isERROR(retcode))
    return SQLCLI_ReturnCode(&currContext,retcode);
  
  stmt->issuePlanVersioningWarnings (diags);

  ULng32 tasks = CLI_PT_GET_INPUT_DESC | CLI_PT_EXEC | CLI_PT_FETCH |
                        CLI_PT_CLOSE |CLI_PT_SPECIAL_END_PROCESS | CLI_PT_EPILOGUE;
  return SQLCLI_PerformTasks(cliGlobals, tasks, statement_id,
			     input_descriptor, NULL,
			     num_ptr_pairs, 0, ap, ptr_pairs, 0);
}


Lng32 SQLCLI_ExecDirectDealloc(  /*IN*/           CliGlobals * cliGlobals,
                                /*IN*/           SQLSTMT_ID * statement_id,
                                /*IN*/           SQLDESC_ID * sql_source,
                                /*IN  OPTIONAL*/ SQLDESC_ID * input_descriptor,
                                /*IN*/                 Lng32   num_ptr_pairs,
                                /*IN*/              va_list   ap,
                                /*IN*/     SQLCLI_PTR_PAIRS   ptr_pairs[])
{
  Lng32 retCode1 = SQLCLI_ExecDirect(cliGlobals,
                    statement_id,
                    sql_source,
                    input_descriptor,
                    num_ptr_pairs,
                    ap,
                    ptr_pairs);

  Lng32 retCode2 = SQLCLI_DeallocStmt(cliGlobals, statement_id);

  if (isERROR(retCode1))
    return(retCode1);

  if (isERROR(retCode2))
    return(retCode2);

  if (isWARNING(retCode1) || isEOF(retCode1))
    return(retCode1);

  return retCode2;
}

Lng32 SQLCLI_ClearExecFetchClose(/*IN*/ CliGlobals * cliGlobals,
                /*IN*/          SQLSTMT_ID * statement_id,
                /*IN OPTIONAL*/ SQLDESC_ID * input_descriptor,
                /*IN OPTIONAL*/ SQLDESC_ID * output_descriptor,
                /*IN*/                Lng32   num_input_ptr_pairs,
                /*IN*/                Lng32   num_output_ptr_pairs,
                /*IN*/                Lng32   num_total_ptr_pairs,
                /*IN*/             va_list   ap,
                /*IN*/    SQLCLI_PTR_PAIRS   input_ptr_pairs[],
                /*IN*/    SQLCLI_PTR_PAIRS   output_ptr_pairs[])
{


  ULng32 tasks = CLI_PT_PROLOGUE | CLI_PT_CLEAR_DIAGS |
                        CLI_PT_GET_INPUT_DESC | CLI_PT_GET_OUTPUT_DESC |
                        CLI_PT_EXEC | CLI_PT_FETCH | CLI_PT_CLOSE |
                        CLI_PT_SET_AQR_INFO |
                        CLI_PT_SPECIAL_END_PROCESS | CLI_PT_EPILOGUE |
			CLI_PT_CLEAREXECFETCHCLOSE |
                        ((statement_id->name_mode == stmt_name)
			 ? CLI_PT_OPT_STMT_INFO : 0);
  return SQLCLI_PerformTasks(cliGlobals, tasks, statement_id, input_descriptor,
                 output_descriptor, num_input_ptr_pairs,
                 num_output_ptr_pairs, ap, input_ptr_pairs, output_ptr_pairs);
}

Lng32 SQLCLI_ExecFetch(  /*IN*/           CliGlobals * cliGlobals,
                        /*IN*/           SQLSTMT_ID * statement_id,
                        /*IN  OPTIONAL*/ SQLDESC_ID * input_descriptor,
                        /*IN*/                 Lng32   num_ptr_pairs,
                        /*IN*/              va_list   ap,
                        /*IN*/     SQLCLI_PTR_PAIRS   ptr_pairs[])
{


  ULng32 tasks = CLI_PT_PROLOGUE | CLI_PT_GET_INPUT_DESC |
                        CLI_PT_SET_AQR_INFO |
                        CLI_PT_EXEC | CLI_PT_FETCH | CLI_PT_CLOSE |
                        CLI_PT_SPECIAL_END_PROCESS | CLI_PT_EPILOGUE |
                        // stmt lookup opt also done for version_2 queries
                        // with stmt_name name mode. Currently only jdbc
                        // could make use of this optimization.
                        (((statement_id->version == SQLCLI_STATEMENT_VERSION_2) &&
			  (statement_id->name_mode == stmt_name))
			 ? CLI_PT_OPT_STMT_INFO : 0);
  return SQLCLI_PerformTasks(cliGlobals, tasks, statement_id,
                 input_descriptor, NULL, num_ptr_pairs, 0, ap, ptr_pairs, 0);
}

Lng32 SQLCLI_Fetch(/*IN*/   CliGlobals * cliGlobals,
          /*IN*/           SQLSTMT_ID * statement_id,
          /*IN  OPTIONAL*/ SQLDESC_ID * output_descriptor,
          /*IN*/                 Lng32   num_ptr_pairs,
          /*IN*/              va_list   ap,
          /*IN*/     SQLCLI_PTR_PAIRS   ptr_pairs[])
{


  ULng32 tasks = CLI_PT_PROLOGUE | CLI_PT_GET_OUTPUT_DESC |
                        CLI_PT_FETCH | CLI_PT_SET_AQR_INFO | CLI_PT_EPILOGUE |
                        // stmt lookup opt also done for version_2 queries
                        // with stmt_name name mode. Currently only jdbc
                        // could make use of this optimization.
                        (((statement_id->version == SQLCLI_STATEMENT_VERSION_2) &&
			  (statement_id->name_mode == stmt_name))
			 ? CLI_PT_OPT_STMT_INFO : 0);
  return SQLCLI_PerformTasks(cliGlobals, tasks, statement_id, NULL,
                 output_descriptor, 0,
                 num_ptr_pairs, ap, 0, ptr_pairs);
}

Lng32 SQLCLI_FetchClose(/*IN*/   CliGlobals * cliGlobals,
               /*IN*/           SQLSTMT_ID * statement_id,
               /*IN  OPTIONAL*/ SQLDESC_ID * output_descriptor,
               /*IN*/                 Lng32   num_ptr_pairs,
               /*IN*/              va_list   ap,
               /*IN*/     SQLCLI_PTR_PAIRS   ptr_pairs[])
{


ULng32 tasks = CLI_PT_GET_OUTPUT_DESC | CLI_PT_FETCH |
                        CLI_PT_CLOSE | CLI_PT_EPILOGUE;
  return SQLCLI_PerformTasks(cliGlobals, tasks, statement_id, NULL,
                 output_descriptor,
                 0, num_ptr_pairs, ap, 0, ptr_pairs);
}

Lng32 SQLCLI_FetchMultiple(/*IN*/ CliGlobals * cliGlobals,
              /*IN*/           SQLSTMT_ID * statement_id,
              /*IN  OPTIONAL*/ SQLDESC_ID * output_descriptor,
              /*IN*/                 Lng32   rowset_size,
              /*IN*/                 Lng32 * rowset_status_ptr,
              /*OUT*/                Lng32 * rowset_nfetched,
              /*IN*/                 Lng32   num_quadruple_fields,
              /*IN*/              va_list   ap,
              /*IN*/   SQLCLI_QUAD_FIELDS   quad_fields[])
{


if (!cliGlobals)
    return -CLI_NO_CURRENT_CONTEXT;

  Lng32 retcode = SQLCLI_SetRowsetDescPointers(cliGlobals,
                          output_descriptor, rowset_size, 
                          rowset_status_ptr, 1, 
                          num_quadruple_fields,
                          ap,
                          quad_fields);

  if (isERROR(retcode))
    return SQLCLI_ReturnCode(cliGlobals->currContext(),retcode);

  retcode = SQLCLI_Fetch(cliGlobals, statement_id, output_descriptor, 0, 0, 0);


  if (isERROR(retcode))
    return SQLCLI_ReturnCode(cliGlobals->currContext(),retcode);

  Lng32 tempRowsetNfetched;
  retcode = SQLCLI_GetRowsetNumprocessed(cliGlobals, output_descriptor,
					 tempRowsetNfetched);
  *rowset_nfetched = tempRowsetNfetched;
  
  return retcode;
}

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

Lng32 SQLCLI_Cancel(/*IN*/ CliGlobals * cliGlobals,
		   /*IN OPTIONAL*/ SQLSTMT_ID * statement_id)
{
  if (!cliGlobals)
      return -CLI_NO_CURRENT_CONTEXT;


  ContextCli &currContext = *(cliGlobals->currContext());
  ComDiagsArea & diags       = currContext.diags();

  // Enter a critical section for this async cancel request.
  ///////////////////////////////////////////////////////////
  currContext.semaphoreLock();
  HashQueue stmtList(TRUE, *(currContext.getStatementList()) );
                       // Copy to make getStatement thread-safe.
  Statement *stmt;
  Lng32 retcode;
  Lng32 error;
                      
  if (statement_id)
    {
      stmt = currContext.getStatement(statement_id, &stmtList);    
      if (!stmt)
	{
	  currContext.semaphoreRelease();
	  return -CLI_STMT_NOT_EXISTS;
	}
      retcode = stmt->cancel();
    }
  else
    { // Cancel all statements on the ContextCli::statementList_.
      retcode = 0;
      error = -CLI_CANCEL_REJECTED;
      NABoolean anyOne = FALSE;

      stmtList.position();
      while (stmt = (Statement *)(stmtList.getNext()))
	{ // Report the least serious error.
          // One success -> success.
          // Otherwise -> -CLI_CANCEL_REJECTED.
	  retcode = stmt->cancel();
	  if (!retcode)
	    {
	      anyOne = TRUE;
	      continue;
	    }
	}
      if (anyOne)
	retcode = 0;
      if (retcode)
	retcode = error;
    }

  currContext.semaphoreRelease();
  ///////////////////////////////////////////////////////////
  // Exit the critical section.

  return retcode;
}
Lng32 SQLCLI_GetDescEntryCount(/*IN*/ CliGlobals * cliGlobals,
			      
                                /*IN*/ SQLDESC_ID * desc_id,
                                /*IN*/ SQLDESC_ID * output_descriptor)
{
  if (!cliGlobals)
    {
      return -CLI_NO_CURRENT_CONTEXT;
    }

  if (!desc_id || !output_descriptor)
    {
      return -CLI_INTERNAL_ERROR;
    }


  ContextCli   & currContext = *(cliGlobals->currContext());
  ComDiagsArea & diags       = currContext.diags();

  Descriptor * desc = currContext.getDescriptor(desc_id);

  /* descriptor must exist */
  if (!desc)
    {
      diags << DgSqlCode(-CLI_DESC_NOT_EXISTS);
      return SQLCLI_ReturnCode(&currContext,-CLI_DESC_NOT_EXISTS);
    }
  Descriptor * output_desc = currContext.getDescriptor(output_descriptor);

  /* descriptor must exist */
  if (!output_desc)
    {
      diags << DgSqlCode(-CLI_DESC_NOT_EXISTS);
      return SQLCLI_ReturnCode(&currContext,-CLI_DESC_NOT_EXISTS);
    }

  Lng32 retcode = OutputValueIntoNumericHostvar(
                                               output_desc,
                                               1,
                                               desc->getUsedEntryCount());

  if (isERROR(retcode))
    return SQLCLI_ReturnCode(&currContext,retcode);

  return SUCCESS;
}

Lng32 SQLCLI_GetDescItems(/*IN*/ CliGlobals * cliGlobals,
			 
                           /*IN*/ SQLDESC_ID * desc_id,
                           /*IN*/ SQLDESC_ITEM desc_items[],
                           /*IN*/ SQLDESC_ID * value_num_descriptor,
                           /*IN*/ SQLDESC_ID * output_descriptor)
{
#if 0
  // sanity check
  if (!desc_id || !value_num_descriptor || !output_descriptor)
    return -CLI_INTERNAL_ERROR;
#endif

  Lng32 retcode;

  CollHeap * heap;
  ComDiagsArea * diagsArea;

  heap = cliGlobals->currContext()->exCollHeap();
  diagsArea = cliGlobals->currContext()->getDiagsArea();


  // create initial context, if first call, and add module, if any.
  retcode = CliPrologue(cliGlobals,desc_id->module);

  if (isERROR(retcode))
    return -CLI_INTERNAL_ERROR;

  ContextCli   & currContext = *(cliGlobals->currContext());
  ComDiagsArea & diags       = currContext.diags();

  Descriptor * desc = currContext.getDescriptor(desc_id);

  /* descriptor must exist */
  if (!desc)
    {
      diags << DgSqlCode(-CLI_DESC_NOT_EXISTS);
      return SQLCLI_ReturnCode(&currContext,-CLI_DESC_NOT_EXISTS);
    }

  Descriptor * value_num_desc = currContext.getDescriptor(value_num_descriptor);

  /* descriptor must exist */
  if (!value_num_desc)
    {
      diags << DgSqlCode(-CLI_DESC_NOT_EXISTS);
      return SQLCLI_ReturnCode(&currContext,-CLI_DESC_NOT_EXISTS);
    }

  Descriptor *output_desc = currContext.getDescriptor(output_descriptor);

  /* descriptor must exist */
  if (!output_desc)
    {
      diags << DgSqlCode(-CLI_DESC_NOT_EXISTS);
      return SQLCLI_ReturnCode(&currContext,-CLI_DESC_NOT_EXISTS);
    }

  Lng32 outputUsedEntryCount = output_desc->getUsedEntryCount();

  for (Lng32 i = 0; i < outputUsedEntryCount; i++) {
    //
    // Get the entry number of the descriptor entry whose item is to be
    // retrieved.
    //
    Lng32 entry;
    retcode = InputValueFromNumericHostvar(
                                           value_num_desc,
                                           desc_items[i].value_num_desc_entry,
                                           entry);

    if (isERROR(retcode))
      return SQLCLI_ReturnCode(&currContext,retcode);

    // check that the item entry is < the max num of occurrences specified
    // when the SQL descriptor area was allocated (must also be > 0)
    if ( (entry < 1) || (entry > desc->getUsedEntryCount()) )
      {
	diags << DgSqlCode(-CLI_ITEM_NUM_OUT_OF_RANGE)
	      << DgInt0(desc->getMaxEntryCount());

	return SQLCLI_ReturnCode(&currContext,-CLI_ITEM_NUM_OUT_OF_RANGE);
      }
    
    Lng32 targetType, targetLen, targetPrecision, targetScale;
    Lng32 sourceLen, sourcePrecision, sourceScale;
    short sourceType;
    char *source;
    Lng32 temp;
    Long  tempPtr;


    //set source, source type, source length, source precision
    //and source scale according to the desciptor item being choosen.
    //get the value of the source into temp if the data type is long
    //else get the address of descItem for char data types by calling
    //Descriptor::getDescItemPtr()
    switch (desc_items[i].item_id)
      {
      case SQLDESC_TYPE:
      case SQLDESC_DATETIME_CODE:
      case SQLDESC_TYPE_FS:
      case SQLDESC_LENGTH:
      case SQLDESC_OCTET_LENGTH:
      case SQLDESC_PRECISION:
      case SQLDESC_SCALE:
      case SQLDESC_INT_LEAD_PREC:
      case SQLDESC_NULLABLE:

      // charset and coll_seq are stored as long. 
      case SQLDESC_CHAR_SET:
      case SQLDESC_COLLATION:

      case SQLDESC_UNNAMED:
      case SQLDESC_IND_TYPE:
      case SQLDESC_IND_LENGTH:

	// case SQLDESC_VAR_PTR:
	//case SQLDESC_IND_PTR:
      case SQLDESC_RET_LEN :
      case SQLDESC_RET_OCTET_LEN :
      case SQLDESC_IND_DATA:
      case SQLDESC_ROWSET_VAR_LAYOUT_SIZE:
      case SQLDESC_ROWSET_IND_LAYOUT_SIZE:
      case SQLDESC_ROWSET_SIZE:

	//case SQLDESC_ROWSET_STATUS_PTR:

      case SQLDESC_ROWSET_NUM_PROCESSED:
      case SQLDESC_ROWSET_HANDLE:
      case SQLDESC_PARAMETER_MODE:
      case SQLDESC_ORDINAL_POSITION:
      case SQLDESC_PARAMETER_INDEX:
      case SQLDESC_DATA_OFFSET:
      case SQLDESC_NULL_IND_OFFSET:
      case SQLDESC_ALIGNED_LENGTH:
        {
          retcode = desc->getDescItem(entry,
                                      desc_items[i].item_id,
                                      &temp,
                                      NULL, 0, NULL, 0);
          if (retcode != 0)
            return SQLCLI_ReturnCode(&currContext,retcode);

          source = (char *) &temp;
          sourceLen = sizeof(Lng32);
          sourceType = REC_BIN32_SIGNED;
          sourcePrecision = 0;
          sourceScale = 0;
        }
        break;

      case SQLDESC_VAR_PTR:
      case SQLDESC_IND_PTR:
      case SQLDESC_ROWSET_STATUS_PTR:
      case SQLDESC_ROWWISE_ROWSET_PTR:
        {
          retcode = desc->getDescItem(entry,
                                      desc_items[i].item_id,
                                      &tempPtr,
                                      NULL, 0, NULL, 0);
          if (retcode != 0)
            return SQLCLI_ReturnCode(&currContext,retcode);



          source = (char *) &tempPtr;
          sourceLen = sizeof(Long);
          sourceType = REC_BIN64_SIGNED;
          sourcePrecision = 0;
          sourceScale = 0;
        }
        break;

      case SQLDESC_VAR_DATA:
      case SQLDESC_CHAR_SET_NAM:
      case SQLDESC_NAME:
      case SQLDESC_HEADING:
      case SQLDESC_TABLE_NAME:
      case SQLDESC_SCHEMA_NAME:
      case SQLDESC_CATALOG_NAME:

      // R2
      // SQLDESC_CHAR_SET_NAM, SQLDESC_CHAR_SET_CAT, 
      // SQLDESC_CHAR_SET_SCH, SQLDESC_COLL_NAM,
      // SQLDESC_COLL_CAT and SQLDESC_COLL_SCH are exposed as 
      // character strings.

      case SQLDESC_CHAR_SET_CAT:
      case SQLDESC_CHAR_SET_SCH:
      case SQLDESC_COLL_NAM:
      case SQLDESC_COLL_CAT:
      case SQLDESC_COLL_SCH:

        {
          retcode = desc->getDescItemPtr(entry,
                                         desc_items[i].item_id,
                                         &source,
                                         &sourceLen);
          if (retcode != 0)
            return SQLCLI_ReturnCode(&currContext,retcode);

          if (desc_items[i].item_id != SQLDESC_VAR_DATA)
            {
              sourceType = REC_BYTE_F_ASCII;
              sourcePrecision = 0;
              sourceScale = 0;
            }
          else
            {
	      Lng32 sType;
              desc->getDescItem(entry,
                                SQLDESC_TYPE_FS,
                                &sType,
                                NULL, 0, NULL, 0);
	      sourceType = (short)sType;

              if ((sourceType >= REC_MIN_INTERVAL) &&
                  (sourceType <= REC_MAX_INTERVAL)) {
                desc->getDescItem(entry, SQLDESC_INT_LEAD_PREC,
                                         &sourcePrecision, 0, 0, 0, 0);
                desc->getDescItem(entry, SQLDESC_PRECISION,
                                         &sourceScale, 0, 0, 0, 0);
              }
              else if (sourceType == REC_DATETIME) {
                desc->getDescItem(entry, SQLDESC_DATETIME_CODE,
                                         &sourcePrecision, 0, 0, 0, 0);
                desc->getDescItem(entry, SQLDESC_PRECISION,
                                         &sourceScale, 0, 0, 0, 0);
              }
              else {
                desc->getDescItem(entry, SQLDESC_PRECISION,
                                         &sourcePrecision, 0, 0, 0, 0);
                desc->getDescItem(entry, SQLDESC_SCALE,
                                         &sourceScale, 0, 0, 0, 0);
              };
            }
        }
        break;

        default:
	  diags << DgSqlCode(-CLI_INVALID_DESC_INFO_REQUEST);
	  return SQLCLI_ReturnCode(&currContext,-CLI_INVALID_DESC_INFO_REQUEST);

          break;
      }

    //
    // Get the address of the target where the item's value is to be stored.
    //
    char * pTarget = 0;
    output_desc->getDescItem(i+1,
                             SQLDESC_VAR_PTR,
                             (Lng32*) &pTarget, // $$$$ hjz: don't assume this is not null hostvar
                             NULL, 0, NULL, 0);

    if (!pTarget)
      return -CLI_INTERNAL_ERROR;

    output_desc->getDescItem(i+1,
                             SQLDESC_TYPE_FS,
                             &targetType,
                             NULL, 0, NULL, 0);

    output_desc->getDescItem(i+1,
                             SQLDESC_OCTET_LENGTH,
                             &targetLen,
                             NULL, 0, NULL, 0);

    if ((targetType >= REC_MIN_INTERVAL) &&
        (targetType <= REC_MAX_INTERVAL))
      {
        output_desc->getDescItem(i+1, SQLDESC_INT_LEAD_PREC,
                                 &targetPrecision, 0, 0, 0, 0);
        output_desc->getDescItem(i+1, SQLDESC_PRECISION,
                               &targetScale, 0, 0, 0, 0);
      }
    else if (targetType == REC_DATETIME)
      {
        output_desc->getDescItem(i+1, SQLDESC_DATETIME_CODE,
                                 &targetPrecision, 0, 0, 0, 0);
        output_desc->getDescItem(i+1, SQLDESC_PRECISION,
                                 &targetScale, 0, 0, 0, 0);
      }
    else
      {
        output_desc->getDescItem(i+1, SQLDESC_PRECISION,
                                 &targetPrecision, 0, 0, 0, 0);
        output_desc->getDescItem(i+1, SQLDESC_SCALE,
                                 &targetScale, 0, 0, 0, 0);
      };

    char * targetVCLen  = NULL;
    short  targetVCLenSize = 0;

    if (DFS2REC::isSQLVarChar(targetType)) {
      targetVCLen = pTarget;
      targetVCLenSize = SQL_VARCHAR_HDR_SIZE;	// user host vars have VCLen 2
      pTarget = &pTarget[targetVCLenSize];
    }
    else
      targetVCLenSize = 0;

    // Check for ansi compatibility of source and target types
    if (NOT (InputOutputExpr::areCompatible(sourceType,(short)targetType)))
	{
	 diags << DgSqlCode(-EXE_CONVERT_NOT_SUPPORTED);
         return SQLCLI_ReturnCode(&currContext,-EXE_CONVERT_NOT_SUPPORTED);  	  
	} 

    // CharSet Phase I work.
    // To check the LHS and RHS character sets for the assignment
    // If the character set for the host var is UCS2, 
    // then any conversion is legitimate;
    // If the character set for the host var is not UCS2, 
    // then the charsets must be the same.
    //
    // The check is performed for VARIABLE_DATA and VARIABLE_POINTER.
    if ( DFS2REC::isAnyCharacter(sourceType) && 
         DFS2REC::isAnyCharacter(targetType) )
    {
      Lng32 csSource, csTarget;
      retcode = output_desc->getDescItem(i+1, 
         				 SQLDESC_CHAR_SET,
					 &csTarget, 
				         NULL, 0, NULL, 0);
      if (retcode != 0)
	return SQLCLI_ReturnCode(&currContext,retcode);
    
      if ( (desc_items[i].item_id == SQLDESC_VAR_DATA ||
            desc_items[i].item_id == SQLDESC_VAR_PTR) )
      {
	retcode = desc->getDescItem(entry,
	                            SQLDESC_CHAR_SET,
	                            &csSource,
	                            NULL, 0, NULL, 0);
	if (retcode != 0)
	  return SQLCLI_ReturnCode(&currContext,retcode);
      
	if ( NOT CharInfo::isAssignmentCompatible((CharInfo::CharSet)csTarget, (CharInfo::CharSet)csSource) ) {
	  // Error 8896: The character set $0~string0 of a host variable does not match $1~string1 of the corresponding descriptor item (entry $2~Int0).
          diags << DgSqlCode(-CLI_CHARSET_MISMATCH)
		<< DgString0(CharInfo::getCharSetName((CharInfo::CharSet)csTarget))
		<< DgString1(CharInfo::getCharSetName((CharInfo::CharSet)csSource))
		<< DgInt0(entry);
	  return SQLCLI_ReturnCode(&currContext,-CLI_CHARSET_MISMATCH);  	  
	}
      }
    }

    if (source)
      {
        // if the target is REC_DECIMAL_LS and the source is NOT
        // REC_DECIMAL_LSE, convert the source to REC_DECIMAL_LSE first.
        char * intermediate = NULL;
        if ((targetType == REC_DECIMAL_LS) &&
            (sourceType != REC_DECIMAL_LSE)) {
          intermediate = new (heap) char[targetLen-1];
          if (convDoIt(source,
                       sourceLen,
                       (short) sourceType,
                       sourcePrecision,
                       sourceScale,
                       intermediate,
                       targetLen-1,
                       REC_DECIMAL_LSE,
                       targetPrecision,
                       targetScale,
                       targetVCLen,
                       targetVCLenSize,
                       heap,
                       &diagsArea) != ex_expr::EXPR_OK) {
              NADELETEBASIC(intermediate, heap);
              retcode  = ERROR;
          }
          if (isERROR(retcode))
            return SQLCLI_ReturnCode(&currContext,retcode);
          source = intermediate;
          sourceLen = targetLen-1;
          sourceType = REC_DECIMAL_LSE;
        }

        if ( (sourceType == REC_NCHAR_F_UNICODE ||
              sourceType == REC_NCHAR_V_UNICODE )
           )
        {
           // Charset can be retrieved as a long INTERNALLY
           // using programatic interface by calling getDescItem(),
	   // and can only be retrieved as a character string EXTERNALLY
	   // using "get descriptor" syntax.
           Lng32 char_set;

           output_desc->getDescItem(
                entry, SQLDESC_CHAR_SET, &char_set,
		NULL, 0, NULL, 0);

           if ( char_set == CharInfo::SJIS )
           {
             switch ( targetType ) {
                case REC_BYTE_F_ASCII:
                   targetType = REC_MBYTE_F_SJIS;
                   break;

                case REC_BYTE_V_ANSI:
                case REC_BYTE_V_ASCII_LONG:
                case REC_BYTE_V_ASCII:
                   targetType = REC_MBYTE_V_SJIS;
                   break;

                default:
                   break;
             }
           }
        }

        //get the size of memory to be bounds checked
        Int32 memorySize = targetLen;
        
        //if varchar, add header size
	if (DFS2REC::isAnyVarChar(targetType)) {
	  if (DFS2REC::isSQLVarChar(targetType))
	    memorySize += SQL_VARCHAR_HDR_SIZE;	// count prefix
	  else if (targetType == REC_BYTE_V_ANSI_DOUBLE)
	    memorySize += SQL_DBCHAR_SIZE;	// double-byte nul terminator
	  else
	    memorySize += 1;			// single-byte nul terminator
	}

	if ((desc_items[i].item_id == SQLDESC_VAR_DATA) &&
	    ((sourceType == REC_DATETIME) ||
	     ((sourceType >= REC_MIN_INTERVAL) &&
	      (sourceType <= REC_MAX_INTERVAL))) &&
	    (sourceType == targetType))
	  {
	    // this is a datetime or interval conversion. The fetched VAR_DATA
	    // value was saved as an ascii string.
	    sourceType = REC_BYTE_F_ASCII;
	    sourceScale = 0;
	    sourcePrecision = 0;
	    targetType = REC_BYTE_F_ASCII;
	    targetScale = 0;
	    targetPrecision = 0;
	  }
	
        //bounds check memory
        if (currContext.boundsCheckMemory(pTarget,memorySize))
          return SQLCLI_ReturnCode(&currContext,
				   -CLI_USER_MEMORY_IN_EXECUTOR_SEGMENT);
        
        retcode = convDoIt(source,
                           sourceLen,
                           (short) sourceType,
                           sourcePrecision,
                           sourceScale,
                           pTarget,
                           targetLen,
                           (short)targetType,
                           targetPrecision,
                           targetScale,
                           targetVCLen,
                           targetVCLenSize,
                           heap,
                           &diagsArea);

        if (retcode != ex_expr::EXPR_OK)
          retcode = ERROR;

        if (retcode == ex_expr::EXPR_OK &&
            targetType >= REC_MIN_NUMERIC &&
            targetType <= REC_MAX_NUMERIC &&
            ::scaleDoIt(pTarget,
                        targetLen,
                        targetType,
                        sourceScale,
                        targetScale,
                        sourceType,
                        heap) != ex_expr::EXPR_OK) {
          retcode = ERROR;
        }

        NADELETEBASIC(intermediate, heap);
        if (isERROR(retcode))
          return SQLCLI_ReturnCode(&currContext,retcode);
      }
  }

  return SUCCESS;
}

Lng32 SQLCLI_GetDescItems2(/*IN*/ CliGlobals * cliGlobals,
			  /*IN*/ SQLDESC_ID * desc_id,
			  /*IN*/ Lng32 no_of_desc_items,
			  /*IN*/ SQLDESC_ITEM desc_items[])
{
  Lng32 retcode;


  // create initial context, if first call, and add module, if any.
  retcode = CliPrologue(cliGlobals,desc_id->module);
  if (isERROR(retcode))
    return retcode;

  ContextCli   & currContext = *(cliGlobals->currContext());
  ComDiagsArea & diags       = currContext.diags();

  Descriptor * desc = currContext.getDescriptor(desc_id);

  /* descriptor must exist */
  if (!desc)
    {
      diags << DgSqlCode(-CLI_DESC_NOT_EXISTS);
      return SQLCLI_ReturnCode(&currContext,-CLI_DESC_NOT_EXISTS);
    }

  for (Lng32 i = 0; i < no_of_desc_items; i++) 
    {
      //
      // Get the entry number of the descriptor entry whose item is to be
      // retrieved.
      //
      Lng32 entry = desc_items[i].entry;
      
      // check that the item entry is < the max num of occurrences specified
      // when the SQL descriptor area was allocated (must also be > 0)
      if ( (entry < 1) || (entry > desc->getUsedEntryCount()) )
	{
	  diags << DgSqlCode(-CLI_ITEM_NUM_OUT_OF_RANGE)
		<< DgInt0(desc->getMaxEntryCount());
	  
	  return SQLCLI_ReturnCode(&currContext,-CLI_ITEM_NUM_OUT_OF_RANGE);
	}
      
      Lng32 sourceLen = 0;
      char *source = NULL;

      Lng32 tmp32BitVal;
      
      switch (desc_items[i].item_id)
	{
        case SQLDESC_TYPE:
        case SQLDESC_DATETIME_CODE:
        case SQLDESC_TYPE_FS:
        case SQLDESC_LENGTH:
        case SQLDESC_OCTET_LENGTH:
        case SQLDESC_PRECISION:
        case SQLDESC_SCALE:
        case SQLDESC_INT_LEAD_PREC:
        case SQLDESC_NULLABLE:
        case SQLDESC_CHAR_SET:
        case SQLDESC_UNNAMED:
        case SQLDESC_IND_TYPE:
        case SQLDESC_IND_LENGTH:

	  //case SQLDESC_VAR_PTR:
	  //case SQLDESC_IND_PTR:

        case SQLDESC_RET_LEN :
        case SQLDESC_RET_OCTET_LEN :
        case SQLDESC_IND_DATA:
        case SQLDESC_ROWSET_VAR_LAYOUT_SIZE:
        case SQLDESC_ROWSET_IND_LAYOUT_SIZE:
        case SQLDESC_ROWSET_SIZE:

	  //case SQLDESC_ROWSET_STATUS_PTR:
        case SQLDESC_ROWSET_NUM_PROCESSED:
        case SQLDESC_ROWSET_HANDLE:
        case SQLDESC_PARAMETER_MODE:
        case SQLDESC_ORDINAL_POSITION:
        case SQLDESC_PARAMETER_INDEX:
        case SQLDESC_VC_IND_LENGTH:
	  {
	    retcode = desc->getDescItem(entry,
					desc_items[i].item_id,
					&tmp32BitVal,
					NULL, 0, NULL, 0);
	    if (retcode != 0)
	      return SQLCLI_ReturnCode(&currContext,retcode);
            else
              desc_items[i].num_val_or_len = tmp32BitVal;
	  }
        break;
        case SQLDESC_VAR_PTR:
        case SQLDESC_IND_PTR:
        case SQLDESC_ROWSET_STATUS_PTR:
        case SQLDESC_ROWWISE_ROWSET_PTR:
	  {
	    retcode = desc->getDescItem(entry,
					desc_items[i].item_id,
					&desc_items[i].num_val_or_len,
					NULL, 0, NULL, 0);
				   
	    if (retcode != 0)
	      return SQLCLI_ReturnCode(&currContext,retcode);
	  }

	  break;
	

        case SQLDESC_VAR_DATA:
	case SQLDESC_NAME:
	case SQLDESC_HEADING:
	case SQLDESC_TABLE_NAME:
	case SQLDESC_SCHEMA_NAME:
	case SQLDESC_CATALOG_NAME:
        case SQLDESC_CHAR_SET_CAT:
        case SQLDESC_CHAR_SET_SCH:
	case SQLDESC_CHAR_SET_NAM:
        case SQLDESC_COLL_CAT:
        case SQLDESC_COLL_SCH:
        case SQLDESC_COLL_NAM:
        case SQLDESC_TEXT_FORMAT:
	  {
	    retcode = desc->getDescItemPtr(entry,
					   desc_items[i].item_id,
					   &source,
					   &sourceLen);
	    if (retcode != 0)
	      return SQLCLI_ReturnCode(&currContext,retcode);
	    
	    if ((sourceLen > desc_items[i].num_val_or_len) ||
		((sourceLen > 0) && (desc_items[i].string_val == NULL)))
	      {
		diags << DgSqlCode(-EXE_STRING_OVERFLOW);
		return SQLCLI_ReturnCode(&currContext,-EXE_STRING_OVERFLOW);
	      } 
	    
	    if (sourceLen > 0)
	      {
		str_cpy_all(desc_items[i].string_val, source, sourceLen);
	      }

	    desc_items[i].num_val_or_len = sourceLen;
	  }
	break;

	default:
	  {
	    diags << DgSqlCode(-CLI_INTERNAL_ERROR);
	    return SQLCLI_ReturnCode(&currContext,-CLI_INTERNAL_ERROR);
	  }
	break;

	} // switch

    } // for

  return SUCCESS;
}

Lng32 SQLCLI_ClearDiagnostics(/*IN*/ CliGlobals * cliGlobals,
			     /*IN OPTIONAL*/SQLSTMT_ID * statement_id)
{


// create initial context, if first call, and add module, if any.
  Lng32 retcode;
  if ( statement_id == NULL )
    retcode = CliPrologue(cliGlobals,0);
  else
    retcode = CliPrologue(cliGlobals,statement_id->module);

  if (isERROR(retcode))
    return retcode;

  cliGlobals->currContext()->diags().clear();

  return SUCCESS;
}

static Lng32 getStmtInfo(
     /*IN*/ CliGlobals * cliGlobals,
     /*IN*/ ComDiagsArea & diags,
     /*IN*/ Statement * stmt,
     /*IN* (SQLDIAG_STMT_INFO_ITEM_ID) */ Lng32 what_to_get,
     /*OUT OPTIONAL*/ void * numeric_value,
     /*OUT OPTIONAL*/ char * string_value,
     /*IN OPTIONAL*/ Lng32 max_string_len,
     /*OUT OPTIONAL*/ Lng32 * len_of_item)
{
  switch (what_to_get) 
    {
    case SQLDIAG_NUMBER:
      *(Lng32*)numeric_value = diags.getNumber();  // actually returns long 
      break;
      
    case SQLDIAG_MORE:
      {
	if (string_value && max_string_len > 0)
	{
	  *string_value = diags.areMore() ? 'Y' : 'N' ;
	  if (len_of_item)
	    *len_of_item = 1;
	}
      }
      break;
      
      // A ComDiagsArea doesn't, itself, currently know the
      // difference between a command and dynamic sql function.
    case SQLDIAG_COMMAND_FUNC:
    case SQLDIAG_DYNAMIC_FUNC:
      *(Int32 *)numeric_value = diags.getFunction();  // returns FunctionEnum type
      break;

    case SQLDIAG_ROW_COUNT:
      {
      Int64 rowCount;
      if (stmt)
	rowCount = stmt->getRowsAffected();  // returns Int64
      else
	rowCount = diags.getRowCount();  // returns ComDiagBigInt 
      if ( rowCount > LONG_MAX)
        return EXE_NUMERIC_OVERFLOW;
      *(Int64*)numeric_value = rowCount;
      break;
      }
     
      case SQLDIAG_ROWSET_ROW_COUNT:
      {
	
	if (!(diags.hasValidRowsetRowCountArray()))
	  return -EXE_ROWSET_ROW_COUNT_ARRAY_NOT_AVAILABLE;
	if (max_string_len < diags.numEntriesInRowsetRowCountArray())
	  return -EXE_ROWSET_ROW_COUNT_ARRAY_WRONG_SIZE;

	Int64 rowCount;
	for(Lng32 i=0;i<diags.numEntriesInRowsetRowCountArray();i++)
	{
	  rowCount = diags.getValueFromRowsetRowCountArray(i);
	  assert ( rowCount != -1 ); // accessing a row count array element that was never set.
	  if ( rowCount > INT_MAX)
	    return EXE_NUMERIC_OVERFLOW;
	  ((Lng32 *)numeric_value)[i] = (Lng32) rowCount;
	}
	if (len_of_item)
	  *len_of_item = diags.numEntriesInRowsetRowCountArray();
      }
      break;
      
    case SQLDIAG_AVERAGE_STREAM_WAIT:
      *(ComDiagBigInt *)numeric_value = diags.getAvgStreamWaitTime();// returns ComDiagBigInt
      break;
    // The SQL/MP extension statement info items that are supported.
    case SQLDIAG_COST:
      {
	double temp_double = diags.getCost();
	if(((double) INT_MAX) <= temp_double)
	  {
	    *(Lng32 *)numeric_value = INT_MAX;
	  }
	else
	  {
	    *(Lng32 *)numeric_value = (Lng32) temp_double;
	  };
      }
    break;
    
    // The SQL/MP extension statement info items aren't currently unsupported.
    // (but should be supported soon! ;-)
    case SQLDIAG_FIRST_FSCODE:
    case SQLDIAG_LAST_FSCODE:
    case SQLDIAG_LAST_SYSKEY:
      *(Lng32 *)numeric_value = 0;
      break;
      
    default: 
      return -CLI_INTERNAL_ERROR;
      break;
    }
  
  return SUCCESS;
}

Lng32 SQLCLI_GetDiagnosticsStmtInfo(/*IN*/ CliGlobals * cliGlobals,
				   /*IN*/       Lng32 * stmt_info_items,
				   /*IN*/ SQLDESC_ID * output_descriptor)
{
  // test to see if our inputs are even valid
  if (!stmt_info_items)
    {
      return -CLI_INTERNAL_ERROR;
    }

  if (!output_descriptor)
    {
      return -CLI_DESC_NOT_EXISTS;
    }


  // go ahead...
  // create initial context, if first call, and add module, if any.
  Lng32 retcode = CliPrologue(cliGlobals,output_descriptor->module);

  if (isERROR(retcode))
    return retcode;

  ContextCli   & currContext = *(cliGlobals->currContext());
  ComDiagsArea & diags       = currContext.diags();
     
  Descriptor * output_desc = currContext.getDescriptor(output_descriptor);

  if (!output_desc)
    {
      return -CLI_DESC_NOT_EXISTS;
    }

  Lng32 outputUsedEntryCount = output_desc->getUsedEntryCount();
  for (Lng32 i = 0; i < outputUsedEntryCount; i++) 
    {
      if ((stmt_info_items[i] == SQLDIAG_ROW_COUNT) ||
	  (stmt_info_items[i] == SQLDIAG_NUMBER) ||
	  (stmt_info_items[i] == SQLDIAG_ROWSET_ROW_COUNT))
        {
          char * target;
          Lng32 targetLen;
          Lng32 targetType;
          Lng32 targetPrecision;
          Lng32 targetScale;
	  Lng32 targetRowsetSize = 1;  // initialized to 1 for ROW_COUNT and NUMBER
	  Lng32 targetRowsetVarLayoutSize;

          retcode = output_desc->getDescItem(i+1,
                SQLDESC_VAR_PTR,
                (Lng32*) &target, 
                NULL, 0, NULL, 0);
          if (isERROR(retcode))
            break;
          
          retcode = output_desc->getDescItem(i+1,
                SQLDESC_TYPE_FS,
                &targetType, 
                NULL, 0, NULL, 0);
          if (isERROR(retcode))
            break;

          retcode = output_desc->getDescItem(i+1,
                SQLDESC_LENGTH,
                &targetLen, 
                NULL, 0, NULL, 0);
          if (isERROR(retcode))
            break;

          retcode = output_desc->getDescItem(i+1,
                SQLDESC_PRECISION,
                &targetPrecision, 
                NULL, 0, NULL, 0);
          if (isERROR(retcode))
            break;

          retcode = output_desc->getDescItem(i+1,
                SQLDESC_SCALE,
                &targetScale, 
                NULL, 0, NULL, 0);
          if (isERROR(retcode))
            break;

          if ((targetType >= REC_MIN_CHARACTER ) &&
              (targetType <= REC_MAX_CHARACTER)) 
            {

              Lng32 temp_char_set;
              output_desc->getDescItem(i+1, SQLDESC_CHAR_SET,
                                      &temp_char_set, 0, 0, 0, 0);
              if ( CharInfo::is_NCHAR_MP((CharInfo::CharSet)temp_char_set))
                {
                  retcode =  -EXE_CONVERT_NOT_SUPPORTED;
                  break;
                }
            }

          Int64 value;
	  if (stmt_info_items[i] == SQLDIAG_ROW_COUNT)
	    value = diags.getRowCount();
	  else if (stmt_info_items[i] == SQLDIAG_NUMBER)
	    {
	      Lng32 number;
	      retcode = 
		getStmtInfo(cliGlobals, diags, NULL, stmt_info_items[i],
			    &number, NULL, 0, NULL);
	      if (isERROR(retcode))
		break;

	      value = number;
	    }
	  else  // SQLDIAG_ROWSET_ROW_COUNT
	  {
	    // retrieve user provided rowset size into targetRowsetSize
	    retcode = output_desc->getDescItem(0,
                SQLDESC_ROWSET_SIZE,
                &targetRowsetSize, 
                NULL, 0, NULL, 0);
	    if (isERROR(retcode))
            break;

	    retcode = output_desc->getDescItem(i+1,
                SQLDESC_ROWSET_VAR_LAYOUT_SIZE,
                &targetRowsetVarLayoutSize, 
                NULL, 0, NULL, 0);
	    if (isERROR(retcode))
            break;

	    if (!(diags.hasValidRowsetRowCountArray())){
	      retcode = -EXE_ROWSET_ROW_COUNT_ARRAY_NOT_AVAILABLE;
	      break;
	    }
	    if (targetRowsetSize < diags.numEntriesInRowsetRowCountArray()) {
	      retcode = -EXE_ROWSET_ROW_COUNT_ARRAY_WRONG_SIZE;
	      break;
	    }
	    else {
	      // reset targetRowsetSize to length of run-time rowset size
	      // i.e. the number of entries in rowCountArray, if this is smaller
	      // than user provided value.
	      targetRowsetSize = diags.numEntriesInRowsetRowCountArray();
	    }
	  }
	  CollHeap * heap = output_desc->getContext()->exCollHeap();
	  ComDiagsArea * diagsArea = output_desc->getContext()->getDiagsArea();
	  Lng32 oldDiagsAreaMark = diagsArea->mark();
	  Lng32 oldLastError = diagsArea->getNumber(DgSqlCode::ERROR_);

	  // we will go through this loop only once for NUMBER and ROW_COUNT
	  for (Lng32 j = 0; j < targetRowsetSize; j++) {

	    if (stmt_info_items[i] == SQLDIAG_ROWSET_ROW_COUNT) {
	      value = diags.getValueFromRowsetRowCountArray(j); 
	      // increment target to point to the next element in the output rowset
	      if (j > 0)
		target += targetRowsetVarLayoutSize;
	    }

	    ex_expr::exp_return_type convDoItRetcode = 
	      convDoIt((char *) &value, 
		  SQL_LARGE_SIZE,
		  (short) REC_BIN64_SIGNED,
		  0, // sourcePrecision
		  0, // sourceScale
		  target,
		  targetLen,
		  (short) targetType,
		  targetPrecision,
		  targetScale,
		  NULL, // varCharLen
		  0,     // varCharLenSize,
		  heap,
		  &diagsArea
		  );

	    if (convDoItRetcode != ex_expr::EXPR_OK)
		retcode = diagsArea->getErrorEntry(oldLastError+1)->getSQLCODE();

	    diagsArea->rewind(oldDiagsAreaMark, TRUE);

	    if (isERROR(retcode))
	      break;
	  }
	  if (isERROR(retcode))
	      break;
        }
	else if (stmt_info_items[i] == SQLDIAG_MORE){ // only string member in stmt info
	  char * more_entry = 0;
	  Lng32 targetLen;

          retcode = output_desc->getDescItem(i+1,
					     SQLDESC_VAR_PTR,
					     (Lng32*) &more_entry, 
					     NULL, 0, NULL, 0);
          if (isERROR(retcode))
            break;

	  retcode = output_desc->getDescItem(i+1,
                SQLDESC_LENGTH,
                &targetLen, 
                NULL, 0, NULL, 0);
          if (isERROR(retcode))
            break;
      
          retcode = 
	    getStmtInfo(cliGlobals, diags, NULL, stmt_info_items[i],
		        NULL, more_entry, targetLen, NULL);

          if (isERROR(retcode))
            break;

	}
      else
        {
          //
          // Get the entry number of the descriptor entry whose item is to be set.
          //
          Lng32 * entry = 0;
      
          // guess we need to get the datatype of the descriptor item
          // and then decide what kind of variable to use...
          // Right now, we assume that it is 'long' numeric type.
          retcode = output_desc->getDescItem(i+1,
					     SQLDESC_VAR_PTR,
					     (Lng32*) &entry, 
					     NULL, 0, NULL, 0);
          if (isERROR(retcode))
            break;
      
          retcode = 
	    getStmtInfo(cliGlobals, diags, NULL, stmt_info_items[i],
		        entry, NULL, 0, NULL);

          if (isERROR(retcode))
            break;
        }
    }

  if (isERROR(retcode))
    return retcode;
  else
    return SUCCESS;
}

Lng32 SQLCLI_GetDiagnosticsStmtInfo2(
     /*IN*/ CliGlobals * cliGlobals,
     /*IN OPTIONAL*/ SQLSTMT_ID * statement_id,
     /*IN* (SQLDIAG_STMT_INFO_ITEM_ID) */ Lng32 what_to_get,
     /*OUT OPTIONAL*/ void * numeric_value,
     /*OUT OPTIONAL*/ char * string_value,
     /*IN OPTIONAL*/ Lng32 max_string_len,
     /*OUT OPTIONAL*/ Lng32 * len_of_item)
{

  // go ahead...
  // create initial context, if first call, and add module, if any.
  Lng32 retcode = CliPrologue(cliGlobals,
			     statement_id ? statement_id->module : NULL);

  if (isERROR(retcode))
    return retcode;

  ContextCli   & currContext = *(cliGlobals->currContext());
  ComDiagsArea & diags       = currContext.diags();

  Statement * stmt = NULL;
  if (statement_id)
    {
      stmt = currContext.getStatement(statement_id);
      
      // stmt must exist.
      // Only rowsAffected supported for now, if statement_id is passed in.

      if ((!stmt) || 
	  ((what_to_get != SQLDIAG_NUMBER) && (what_to_get != SQLDIAG_ROW_COUNT)))
	{
	  return -CLI_STMT_NOT_EXISTS;
	}
    }
  
  retcode = 
    getStmtInfo(cliGlobals, diags, stmt, what_to_get,
		numeric_value, string_value, max_string_len, len_of_item);

  return SQLCLI_ReturnCode(&currContext, retcode);
}

static void copyResultString(char * dest, const char * src, Lng32 destLen,
			     Lng32 * copyLen = NULL)
{
  if (!dest)
    return;

  if (copyLen)
    *copyLen = 0;
  if (src)
    {
      Lng32 len = MINOF(str_len(src)+1, destLen);
      str_cpy_all(dest, src, len);
      if (copyLen)
	*copyLen = len;
    }
  else
    *dest = '\0';
}

Lng32 SQLCLI_GetDiagnosticsCondInfo(/*IN*/ CliGlobals * cliGlobals,
                                     /*IN*/ SQLDIAG_COND_INFO_ITEM * cond_info_items,
                                     /*IN*/             SQLDESC_ID * cond_num_descriptor,
                                     /*IN*/             SQLDESC_ID * output_descriptor,
				     /*OUT*/   IpcMessageBufferPtr   message_buffer_ptr,
				     /*IN*/      IpcMessageObjSize   message_obj_size,
				     /*OUT*/     IpcMessageObjSize * message_obj_size_needed,
				     /*OUT*/     IpcMessageObjType * message_obj_type,
				     /*OUT*/  IpcMessageObjVersion * message_obj_version,
				     /*IN*/                   Lng32   condition_item_count,
				     /*OUT*/                  Lng32 * condition_item_count_needed,
				     /*OUT*/    DiagsConditionItem * condition_item_array,
 		                     /*OUT*/    SQLMXLoggingArea::ExperienceLevel * emsEventEL)
{
  Lng32 i;
  // test to see if our inputs are even valid
  if (!cond_info_items)
    {
      return -CLI_INTERNAL_ERROR;
    }

  if (!cond_num_descriptor || !output_descriptor)
    {
      return -CLI_DESC_NOT_EXISTS;
    }


  // go ahead...
  // create initial context, if first call, and add module, if any.
  Lng32 retcode = CliPrologue(cliGlobals,output_descriptor->module);
  if (isERROR(retcode))
    return retcode;
  ContextCli   & currContext = *(cliGlobals->currContext());
  ComDiagsArea & diags       = currContext.diags();
  // *emsEventEL is assigned the system experience level value
  // passed to the cli through the plan

  if (emsEventEL != NULL)
     *emsEventEL = cliGlobals->getEMSEventExperienceLevel();
#ifdef BOUNDS_CHECK_IN_CLI

#endif

  if (currContext.boundsCheckMemory(message_buffer_ptr, message_obj_size) ||
      currContext.boundsCheckMemory(message_obj_size_needed, sizeof(IpcMessageObjSize)) ||
      currContext.boundsCheckMemory(message_obj_type, sizeof(IpcMessageObjType)) ||
      currContext.boundsCheckMemory(message_obj_version, sizeof(IpcMessageObjVersion)) ||
      currContext.boundsCheckMemory(condition_item_array, condition_item_count * sizeof(DiagsConditionItem)) ||
      currContext.boundsCheckMemory(condition_item_count_needed, sizeof(Lng32)))
    return SQLCLI_ReturnCode(&currContext,
			     -CLI_USER_MEMORY_IN_EXECUTOR_SEGMENT);

  Descriptor * condnum_desc = currContext.getDescriptor(cond_num_descriptor);

  if (!condnum_desc)
    {
      return -CLI_DESC_NOT_EXISTS;
    }

  Descriptor * output_desc = currContext.getDescriptor(output_descriptor);

  if (!output_desc)
    {
      return -CLI_DESC_NOT_EXISTS;
    }

  Lng32 outputUsedEntryCount = output_desc->getUsedEntryCount();

  // the condition number is contained in a single descriptor entry
  if (condnum_desc->getUsedEntryCount() < 1)
    {
      return -CLI_INTERNAL_ERROR;
    }

  *message_obj_size_needed = diags.packedLength();

  *condition_item_count_needed = 0;
  for (i = 0; i < outputUsedEntryCount; i++) {
    switch (cond_info_items[i].item_id) {
    case  SQLDIAG_RET_SQLSTATE:  /* (string ) returned SQLSTATE */
    case  SQLDIAG_CLASS_ORIG:    /* (string ) class origin, e.g. ISO 9075 */
    case  SQLDIAG_SUBCLASS_ORIG: /* (string ) subclass origin, e.g. ISO 9075 */
    case  SQLDIAG_MSG_TEXT:      /* (string ) message text */
    case  SQLDIAG_MSG_LEN:       /* (numeric) message length in characters */
    case  SQLDIAG_MSG_OCTET_LEN: /* (numeric) message length in bytes */
      *condition_item_count_needed += 1;
    }
    if (cond_info_items[i].cond_number_desc_entry < 1
        || (condnum_desc->getUsedEntryCount() > 1
	&& cond_info_items[i].cond_number_desc_entry > condnum_desc->getUsedEntryCount()))
      return -CLI_INTERNAL_ERROR;
  }
  if (*condition_item_count_needed > 0
      && (condition_item_count < *condition_item_count_needed
          || message_obj_size < *message_obj_size_needed))
    return 0; // Caller has to call again with larger array or buffer
  if (*condition_item_count_needed > 0) {
    *condition_item_count_needed = 0;
    if (diags.getNumber(DgSqlCode::ERROR_) > SHRT_MAX)
      return -CLI_INTERNAL_ERROR;
    *message_obj_size_needed = diags.packObjIntoMessage(message_buffer_ptr);
    *message_obj_type = diags.getType();
    *message_obj_version = diags.getVersion();
  }

  CharInfo::CharSet messageCharSet = CharInfo::UnknownCharSet;
  Int32 msgOctLenInd = -1;

  for (i = 0; i < outputUsedEntryCount; i++) {
    //
    // Get the entry number of the descriptor entry whose item is to be set.
    //
    Lng32 *entry = 0;
    retcode = output_desc->getDescItem(i+1,
                                       SQLDESC_VAR_PTR,
                                       (Lng32 *)&entry, // $$$$ hjz: don't assume this is a long hostvar
                                       NULL, 0, NULL, 0);
    if (isERROR(retcode))
      return SQLCLI_ReturnCode(&currContext,retcode);

    if (!entry)
      return -CLI_INTERNAL_ERROR;

    Lng32 theLength = 0L;
    retcode = output_desc->getDescItem(i+1,
                                       SQLDESC_LENGTH,
                                       &theLength,
                                       NULL, 0, NULL, 0);
    if (isERROR(retcode))
      return SQLCLI_ReturnCode(&currContext,retcode);

    Lng32 userIndex = 0L;
    retcode = InputValueFromNumericHostvar(
                                           condnum_desc,
                                           condnum_desc->getUsedEntryCount() > 1 ?
					   cond_info_items[i].cond_number_desc_entry :
					   1, // use 1 for compatibility (used to be this way)
                                           userIndex);
    if (isERROR(retcode))
      return SQLCLI_ReturnCode(&currContext,retcode);

    if (userIndex < 1 || userIndex > diags.getNumber())
      {
        return -CLI_ITEM_NUM_OUT_OF_RANGE;  //index out of range
      }

    ComCondition & condition = diags[userIndex];

    switch (cond_info_items[i].item_id) {
    case SQLDIAG_SQLCODE:        /* (numeric) the SQLCODE */
      retcode = OutputValueIntoNumericHostvar(
                                              output_desc,
                                              i+1,
                                              condition.getSQLCODE());
      break;
      
    case SQLDIAG_COND_NUMBER:    /* (numeric) condition number */
      retcode = OutputValueIntoNumericHostvar(
                                              output_desc,
                                              i+1,
                                              condition.getConditionNumber());
      break;
      
    case SQLDIAG_NSK_CODE:       /* (numeric) NSK/FS/DP2 FE error number */
      retcode = OutputValueIntoNumericHostvar(
                                              output_desc,
                                              i+1,
                                              condition.getNskCode());
      break;

    case  SQLDIAG_MSG_TEXT:      /* (string ) message text */
      condition.incrEMSEventVisits();
    case  SQLDIAG_CLASS_ORIG:    /* (string ) class origin, e.g. ISO 9075 */
    case  SQLDIAG_SUBCLASS_ORIG: /* (string ) subclass origin, e.g. ISO 9075 */
    case  SQLDIAG_MSG_LEN:       /* (numeric) message length in characters */
    case  SQLDIAG_MSG_OCTET_LEN: /* (numeric) message length in bytes */
// UR2: should get the charset specified in the output_desc to 
// condition_item_array so that the right charset can be used to 
// translate the MSG_TEXT and length.
      condition_item_array[*condition_item_count_needed].item_id = cond_info_items[i].item_id;
      condition_item_array[*condition_item_count_needed].var_ptr = (char *)entry;
      condition_item_array[(*condition_item_count_needed)].length = theLength;
      condition_item_array[(*condition_item_count_needed)].output_entry = i;
      condition_item_array[(*condition_item_count_needed)].condition_index = userIndex;

      // The charset for the hostvar that the error message is assigned to 
      // has to be retrived. Use the internal fast SQLDESC_CHAR_SET version.
      if (cond_info_items[i].item_id == SQLDIAG_MSG_TEXT) {

          Lng32 charset;
          retcode = output_desc->getDescItem(i+1,
                                       SQLDESC_CHAR_SET,
                                       &charset,
                                       NULL, 0, NULL, 0);
          if (retcode != 0)
            return SQLCLI_ReturnCode(&currContext,retcode);
          if (charset == (Lng32)CharInfo::ISO88591) // do not know where to set this field
            charset = CharInfo::UTF8;               // so set it here for now.
     
          messageCharSet = (CharInfo::CharSet)charset;

	  // Only ISO88591 and UCS2 can be used to retrieve the diagnostic msg.
          if ( CharInfo::isMsgCharSetSupported(messageCharSet) ) {
	    condition_item_array[(*condition_item_count_needed)].charset = messageCharSet;
	  } else {
	    return SQLCLI_ReturnCode(&currContext,-CLI_MSG_CHAR_SET_NOT_SUPPORTED);
	  }
      } else if (cond_info_items[i].item_id == SQLDIAG_MSG_OCTET_LEN) {
	  // remember the index for SQLDIAG_MSG_OCTET_LEN into 
	  // the condition_item_array.
	  msgOctLenInd = *condition_item_count_needed;
      }
      ++(*condition_item_count_needed);

      break;

    case  SQLDIAG_RET_SQLSTATE:  /* (string ) returned SQLSTATE */
      if(condition.getCustomSQLState() == NULL) {
	condition_item_array[*condition_item_count_needed].item_id = cond_info_items[i].item_id;
	condition_item_array[*condition_item_count_needed].var_ptr = (char *)entry;
	condition_item_array[(*condition_item_count_needed)].length = theLength;
	condition_item_array[(*condition_item_count_needed)].output_entry = i;
	condition_item_array[(*condition_item_count_needed)++].condition_index = userIndex;
      }
      else {
	copyResultString((char *)entry, condition.getCustomSQLState(), theLength);
      }
      break;


    case  SQLDIAG_SERVER_NAME:   /* (string ) SQL server name */
      copyResultString((char *)entry, condition.getServerName(), theLength);
      break;

    case  SQLDIAG_CONNECT_NAME:  /* (string ) connection name */
      copyResultString((char *)entry, condition.getConnectionName(), theLength);
      break;

    case  SQLDIAG_CONSTR_CAT:    /* (string ) constraint catalog name */
      copyResultString((char *)entry, condition.getConstraintCatalog(), theLength);
      break;

    case  SQLDIAG_CONSTR_SCHEMA: /* (string ) constraint schema name */
      copyResultString((char *)entry, condition.getConstraintSchema(), theLength);
      break;

    case  SQLDIAG_CONSTR_NAME:   /* (string ) constraint name */
      copyResultString((char *)entry, condition.getConstraintName(), theLength);
      break;

    case  SQLDIAG_TRIGGER_CAT:    /* (string ) trigger catalog name */
      copyResultString((char *)entry, condition.getTriggerCatalog(), theLength);
      break;

    case  SQLDIAG_TRIGGER_SCHEMA: /* (string ) trigger schema name */
      copyResultString((char *)entry, condition.getTriggerSchema(), theLength);
      break;

    case  SQLDIAG_TRIGGER_NAME:   /* (string ) trigger name */
      copyResultString((char *)entry, condition.getTriggerName(), theLength);
      break;

    case  SQLDIAG_CATALOG_NAME:  /* (string ) catalog name */
      copyResultString((char *)entry, condition.getCatalogName(), theLength);
      break;

    case  SQLDIAG_SCHEMA_NAME:   /* (string ) schema name */
      copyResultString((char *)entry, condition.getSchemaName(), theLength);
      break;

    case  SQLDIAG_TABLE_NAME:    /* (string ) table name */
      copyResultString((char *)entry, condition.getTableName(), theLength);
      break;

    case  SQLDIAG_COLUMN_NAME:   /* (string ) column name */
      copyResultString((char *)entry, condition.getColumnName(), theLength);
      break;

    // CursorName is  not implemented (co-opted for SqlID)
    case  SQLDIAG_CURSOR_NAME:   /* (string ) cursor name */
      copyResultString((char *)entry, "", theLength);
      break;

      /* ODBC -- not implemented currently */
    case  SQLDIAG_COLUMN_NUMBER: /* (numeric) column number     */
    case  SQLDIAG_NATIVE:        /* (numeric) native error code */
      break;

    case  SQLDIAG_ROW_NUMBER:    /* (numeric) row number of input rowset that caused the error  */
      retcode = OutputValueIntoNumericHostvar(
					      output_desc,
					      i+1,
					      condition.getRowNumber());
      break;

      /* SQL/MP -- not implemented yet (except for SQLCODE) */
    case  SQLDIAG_SOURCE_FILE:   /* (string ) source file name            */
    case  SQLDIAG_LINE_NUMBER:   /* (numeric) source code line number     */
    case  SQLDIAG_SUBSYSTEM_ID:  /* (string ) component that issued error */
      break;

    default:
      // do nothing -- no way to report error, so, okay.
      break;
    }
  }  

  // SQLDIAG_MSG_OCT_LEN depends on the message char set.
  // remember the message character set for the entry into 
  // the condition item array for SQLDIAG_MSG_OCT_LEN.
  if (msgOctLenInd != -1) {
    condition_item_array[msgOctLenInd].charset = messageCharSet;
  }

  return retcode;
}
Lng32 SQLCLI_GetPackedDiagnostics(
  /*IN*/             CliGlobals * cliGlobals,
  /*OUT*/   IpcMessageBufferPtr   message_buffer_ptr,
  /*IN*/      IpcMessageObjSize   message_obj_size,
  /*OUT*/     IpcMessageObjSize * message_obj_size_needed,
  /*OUT*/     IpcMessageObjType * message_obj_type,
  /*OUT*/  IpcMessageObjVersion * message_obj_version)
{

  // create initial context, if first call, and add module, if any.
  Lng32 retcode = CliPrologue(cliGlobals, NULL);
  if (isERROR(retcode))
    return retcode;

  ContextCli   & currContext = *(cliGlobals->currContext());
  ComDiagsArea & diags       = currContext.diags();

  *message_obj_size_needed = diags.packedLength();

  if (message_obj_size < *message_obj_size_needed)
    return 0; // Caller has to call again with larger array or buffer

  *message_obj_size_needed = diags.packObjIntoMessage(message_buffer_ptr);
  *message_obj_type = diags.getType();
  *message_obj_version = diags.getVersion();

  return retcode;
}
Lng32 GetDiagnosticsCondInfoSwitchStatement(
     /*IN*/ CliGlobals * cliGlobals,
     /*IN* (SQLDIAG_COND_INFO_ITEM_ID) */ Lng32 what_to_get,
     /*IN*/ Lng32 conditionNum,
     /*OUT OPTIONAL*/ Lng32 * numeric_value,
     /*OUT OPTIONAL*/ char * string_value,
     /*IN OPTIONAL */ Lng32 max_string_len,
     /*OUT OPTIONAL*/ Lng32 * len_of_item)
{
  ContextCli   & currContext = *(cliGlobals->currContext());
  ComDiagsArea & diags       = currContext.diags();
  ComCondition & condition = diags[conditionNum];
  // LPWSTR p = NULL;
  
  switch (what_to_get) 
    {
    case SQLDIAG_SQLCODE:        /* (numeric) the SQLCODE */
      *numeric_value = condition.getSQLCODE();
      break;
    case SQLDIAG_COND_NUMBER:    /* (numeric) condition number */
      *numeric_value = condition.getConditionNumber();
      break;
  
    case SQLDIAG_NSK_CODE:       /* (numeric) NSK/FS/DP2 FE error number */
      *numeric_value = condition.getNskCode();
      break;
      
    case  SQLDIAG_SERVER_NAME:   /* (string ) SQL server name */
      copyResultString(string_value, condition.getServerName(), 
		       max_string_len, len_of_item);
      break;
      
    case  SQLDIAG_CONNECT_NAME:  /* (string ) connection name */
      copyResultString(string_value, condition.getConnectionName(), 
		       max_string_len, len_of_item);
      break;
      
    case  SQLDIAG_CONSTR_CAT:    /* (string ) constraint catalog name */
      copyResultString(string_value, condition.getConstraintCatalog(), 
		       max_string_len, len_of_item);
      break;
      
    case  SQLDIAG_CONSTR_SCHEMA: /* (string ) constraint schema name */
      copyResultString(string_value, condition.getConstraintSchema(), 
		       max_string_len, len_of_item);
      break;
      
    case  SQLDIAG_CONSTR_NAME:   /* (string ) constraint name */
      copyResultString(string_value, condition.getConstraintName(), 
		       max_string_len, len_of_item);
      break;

    case  SQLDIAG_TRIGGER_CAT:    /* (string ) trigger catalog name */
      copyResultString(string_value, condition.getTriggerCatalog(), 
		       max_string_len, len_of_item);
      break;

    case  SQLDIAG_TRIGGER_SCHEMA: /* (string ) trigger schema name */
      copyResultString(string_value, condition.getTriggerSchema(), 
		       max_string_len, len_of_item);
      break;

    case  SQLDIAG_TRIGGER_NAME:   /* (string ) trigger name */
      copyResultString(string_value, condition.getTriggerName(), 
		       max_string_len, len_of_item);
      break;

      
    case  SQLDIAG_CATALOG_NAME:  /* (string ) catalog name */
      copyResultString(string_value, condition.getCatalogName(), 
		       max_string_len, len_of_item);
      break;
      
    case  SQLDIAG_SCHEMA_NAME:   /* (string ) schema name */
      copyResultString(string_value, condition.getSchemaName(), 
		       max_string_len, len_of_item);
      break;
      
    case  SQLDIAG_TABLE_NAME:    /* (string ) table name */
      copyResultString(string_value, condition.getTableName(), 
		       max_string_len, len_of_item);
      break;
      
    case  SQLDIAG_COLUMN_NAME:   /* (string ) column name */
      copyResultString(string_value, condition.getColumnName(), 
		       max_string_len, len_of_item);
      break;
      
    // CursorName is  not implemented (co-opted for SqlID)
    case  SQLDIAG_CURSOR_NAME:   /* (string ) cursor name */
      copyResultString(string_value, "", 
		       max_string_len, len_of_item);
      break;
      
    case  SQLDIAG_CLASS_ORIG:    /* (string ) class origin, e.g. ISO 9075 */
    case  SQLDIAG_SUBCLASS_ORIG: /* (string ) subclass origin, e.g. ISO 9075*/
    case  SQLDIAG_RET_SQLSTATE:  /* (string ) returned SQLSTATE */
    case  SQLDIAG_MSG_TEXT:      /* (string ) message text */
    case  SQLDIAG_MSG_LEN:       /* (numeric) message length in characters */
    case  SQLDIAG_MSG_OCTET_LEN: /* (numeric) message length in bytes */


      {
	// for these cases, call GetDiagnosticsCondInfo().
	// TBD.
      }
    break;
      
      /* ODBC -- not implemented currently */
    case  SQLDIAG_COLUMN_NUMBER: /* (numeric) column number     */
    case  SQLDIAG_NATIVE:        /* (numeric) native error code */
      break ;

    case  SQLDIAG_ROW_NUMBER:    /* (numeric) row number of input rowset that caused the error  */
      *numeric_value = condition.getRowNumber() ;
      break;
      
      /* SQL/MP -- not implemented yet (except for SQLCODE) */
    case  SQLDIAG_SOURCE_FILE:   /* (string ) source file name            */
    case  SQLDIAG_LINE_NUMBER:   /* (numeric) source code line number     */
    case  SQLDIAG_SUBSYSTEM_ID:  /* (string ) component that issued error */
      break;
      
    default:
      // do nothing -- no way to report error, so, okay.
      break;
    }
 return 0;
}

Lng32 SQLCLI_GetDiagnosticsCondInfo2(
     /*IN*/ CliGlobals * cliGlobals,
     /*IN* (SQLDIAG_COND_INFO_ITEM_ID) */ Lng32 what_to_get,
     /*IN*/ Lng32 conditionNum,
     /*OUT OPTIONAL*/ Lng32 * numeric_value,
     /*OUT OPTIONAL*/ char * string_value,
     /*IN OPTIONAL */ Lng32 max_string_len,
     /*OUT OPTIONAL*/ Lng32 * len_of_item)
{

  // go ahead...
  // create initial context, if first call, and add module, if any.
  Lng32 retcode = CliPrologue(cliGlobals,NULL);
  if (isERROR(retcode))
    return retcode;

  retcode = GetDiagnosticsCondInfoSwitchStatement(
	      cliGlobals,
	      what_to_get,
	      conditionNum,
	      numeric_value,
	      string_value,
	      max_string_len,
	      len_of_item);

  return retcode;
}

Lng32 SQLCLI_GetDiagnosticsCondInfo3 (
		/*IN*/ CliGlobals * cliGlobals,
		/*IN*/ Lng32 no_of_condition_items,
		/*IN*/ SQLDIAG_COND_INFO_ITEM_VALUE
			  diag_cond_info_item_values[],
		/*OUT*/ IpcMessageObjSize * message_obj_size_needed)
{

  Lng32 retcode;
  SQLDIAG_COND_INFO_ITEM_VALUE diagItemValues;
  Lng32 max_string_len;
  Lng32 what_to_get;
  NABoolean executePartiallyInNonPriv = FALSE;


  // go ahead...
  // create initial context, if first call, and add module, if any.
  retcode = CliPrologue(cliGlobals,NULL);
  if (isERROR(retcode))
    return retcode;

  ContextCli   & currContext = *(cliGlobals->currContext());
  ComDiagsArea & diags       = currContext.diags();

  for(Int32 i=0; i<no_of_condition_items; i++)
  {
    diagItemValues = diag_cond_info_item_values[i];
    if (diagItemValues.string_val)
      max_string_len = *(diagItemValues.num_val_or_len);
    else
      max_string_len = 0;
    what_to_get = diagItemValues.item_id_and_cond_number.item_id;
    ComCondition & condition = diags[diagItemValues.item_id_and_cond_number.cond_number_desc_entry];
    switch (what_to_get) {
    case  SQLDIAG_MSG_TEXT:      /* (string ) message text */
      condition.incrEMSEventVisits();
    case  SQLDIAG_RET_SQLSTATE:  /* (string ) returned SQLSTATE */
    case  SQLDIAG_CLASS_ORIG:    /* (string ) class origin, e.g. ISO 9075 */
    case  SQLDIAG_SUBCLASS_ORIG: /* (string ) subclass origin, e.g. ISO 9075 */
    case  SQLDIAG_MSG_LEN:       /* (numeric) message length in characters */
    case  SQLDIAG_MSG_OCTET_LEN: /* (numeric) message length in bytes */
      executePartiallyInNonPriv = TRUE;
    }

    retcode = GetDiagnosticsCondInfoSwitchStatement(cliGlobals,
		   what_to_get,
		   diagItemValues.item_id_and_cond_number.cond_number_desc_entry,
		   diagItemValues.num_val_or_len,
		   diagItemValues.string_val,
		   max_string_len,
		   diagItemValues.num_val_or_len) ;

    if (retcode < 0)
      return retcode;
  }

  *message_obj_size_needed = executePartiallyInNonPriv ? diags.packedLength() : 0;

  return retcode;
}

Lng32 SQLCLI_GetDiagnosticsArea(/*IN*/ CliGlobals * cliGlobals,
				/*OUT*/   IpcMessageBufferPtr   message_buffer_ptr,
				/*IN*/      IpcMessageObjSize   message_obj_size,
				/*OUT*/     IpcMessageObjType * message_obj_type,
				/*OUT*/  IpcMessageObjVersion * message_obj_version)
{

  // go ahead...
  // create initial context, if first call, and add module, if any.
  Lng32 retcode = CliPrologue(cliGlobals,NULL);
  if (isERROR(retcode))
    return retcode;
  ContextCli   & currContext = *(cliGlobals->currContext());
  ComDiagsArea & diags       = currContext.diags();
  Lng32 oldDiagsAreaMark = diags.mark();
	  
  if (currContext.boundsCheckMemory(message_buffer_ptr, message_obj_size) ||
      currContext.boundsCheckMemory(message_obj_type, sizeof(IpcMessageObjType)) ||
      currContext.boundsCheckMemory(message_obj_version, sizeof(IpcMessageObjVersion))) 
  {
    diags.rewind(oldDiagsAreaMark, TRUE);
    return -CLI_USER_MEMORY_IN_EXECUTOR_SEGMENT;
  }

    if (diags.getNumber(DgSqlCode::ERROR_) > SHRT_MAX)
      return -CLI_INTERNAL_ERROR;
    if (diags.packedLength() > message_obj_size)
      return -CLI_INTERNAL_ERROR;

    // It is the caller's responsibility to pass in buffer of appropriate size.
    // This method assumes that the buffer is large enough to hold the diagsArea,
    // if not CLI_INTERNAL_ERROR is returned.
    diags.packObjIntoMessage(message_buffer_ptr);
    *message_obj_type = diags.getType();
    *message_obj_version = diags.getVersion();
    return 0;
}

Lng32 SQLCLI_GetSQLCODE(/*IN*/ CliGlobals * cliGlobals,
			/*OUT*/ Lng32 *SQLCODE)
{
  if (!cliGlobals)
      return -CLI_NO_CURRENT_CONTEXT;


  *SQLCODE = cliGlobals->currContext()->diags().mainSQLCODE();


  return SUCCESS; // this call always succeeds, no need to check errors!
}
Lng32 SQLCLI_GetMainSQLSTATE(/*IN*/ CliGlobals * cliGlobals,
                /*IN*/ SQLSTMT_ID * statement_id,
		/*IN*/  Lng32 sqlcode,
		/*OUT*/ char * sqlstate /* assumed to be char[6] */)
{
  return -1;
}

/////////////////////////////////////////////////////////////////
// if sql_source->name_mode is string_data, then
// sql_source->identifier points to the sql_source string and
// identifier_len is the length of that string.
/////////////////////////////////////////////////////////////////
Lng32 SQLCLI_Prepare(/*IN*/ CliGlobals * cliGlobals,
		    /*IN*/ SQLSTMT_ID * statement_id,
		    /*IN*/ SQLDESC_ID * sql_source)
{
  Lng32 retcode;
  

  // create initial context, if first call, and add module, if any.
  retcode = CliPrologue(cliGlobals,statement_id->module);
  if (isERROR(retcode))
    return retcode;

  ContextCli   & currContext = *(cliGlobals->currContext());
  ComDiagsArea & diags       = currContext.diags();

  /* prepare the statement */
  Statement * stmt = currContext.getStatement(statement_id);

  /* stmt must exist */
  if (!stmt)
    {
      diags << DgSqlCode(-CLI_STMT_NOT_EXISTS);
      return SQLCLI_ReturnCode(&currContext,-CLI_STMT_NOT_EXISTS);
    }

  StrTarget strTarget;
  retcode = stmt->initStrTarget(sql_source, currContext, diags, strTarget);
  if (isERROR(retcode))
    return SQLCLI_ReturnCode(&currContext,retcode);


  // CLI callers do not prepare stored procedure result set
  // statements. The prepare is done internally on-demand when the
  // statement is described or executed.
  if (stmt->getParentCall())
  {
    diags << DgSqlCode(-EXE_UDR_RS_PREPARE_NOT_ALLOWED);
    return SQLCLI_ReturnCode(&currContext, -EXE_UDR_RS_PREPARE_NOT_ALLOWED);
  }

  // Set the uniqueStmtId in Statement
  stmt->setUniqueStmtId(NULL);
  // Set the StmtStats in the shared segment
  stmt->setStmtStats(FALSE);

  SQLCLI_Prepare_Setup_Pre(currContext, stmt, 0);
  UInt32 flags; 
  SessionDefaults *sd = currContext.getSessionDefaults();
  if (sd != NULL && sd->getCallEmbeddedArkcmp())
     flags = PREPARE_USE_EMBEDDED_ARKCMP;
  else 
     flags = 0;
  retcode =
    stmt->prepare(strTarget.getStr(), diags, NULL, 0L, strTarget.getIntCharSet(), TRUE, flags);
  
  SQLCLI_Prepare_Setup_Post(currContext, stmt, 1);


  if (isERROR(retcode))
    return SQLCLI_ReturnCode(&currContext,retcode);
  stmt->issuePlanVersioningWarnings (diags);
  return CliEpilogue(cliGlobals,statement_id);
}

Lng32 SQLCLI_Prepare2(/*IN*/ CliGlobals * cliGlobals,
		     /*IN*/ SQLSTMT_ID * statement_id,
		     /*IN*/ SQLDESC_ID * sql_source,
		     /*INOUT*/ char * gencode_ptr,
		     /*IN*/    Lng32   gencode_len,
		     /*INOUT*/ Lng32 * ret_gencode_len,
		     /*INOUT*/ SQL_QUERY_COST_INFO *query_cost_info,
		     /*INOUT*/ SQL_QUERY_COMPILER_STATS_INFO *query_comp_stats_info,
		     /*INOUT*/ char * uniqueStmtId,
		     /*INOUT*/ Lng32 * uniqueStmtIdLen,
		     /*IN*/    ULng32 flags)
{
  Lng32 retcode = 0;

  // create initial context, if first call, and add module, if any.
  retcode = CliPrologue(cliGlobals,statement_id->module);
  if (isERROR(retcode))
    {
      return retcode;
    }

  ContextCli   & currContext = *(cliGlobals->currContext());
  ComDiagsArea & diags       = currContext.diags();

  AQRInfo * aqr = currContext.aqrInfo();

  /* prepare the statement */
  Statement * stmt = currContext.getStatement(statement_id);

  /* stmt must exist */
  if (!stmt)
    {
      diags << DgSqlCode(-CLI_STMT_NOT_EXISTS);
      return SQLCLI_ReturnCode(&currContext,-CLI_STMT_NOT_EXISTS);
    }

  NABoolean retrieveGenCode = FALSE;
  NABoolean reTry = ((flags & PREPARE_AUTO_QUERY_RETRY) != 0);
  UInt32 tmpFlags;
  SessionDefaults *sd = currContext.getSessionDefaults();
  if (sd != NULL && sd->getCallEmbeddedArkcmp())
      tmpFlags = flags | PREPARE_USE_EMBEDDED_ARKCMP;
  else
      tmpFlags = flags;
  if (sql_source)
    {
      StrTarget strTarget;
      retcode = stmt->initStrTarget(sql_source, currContext, diags, strTarget);
      if (isERROR(retcode))
        {
	  return SQLCLI_ReturnCode(&currContext,retcode);
        }
      
      NABoolean standaloneQ = tmpFlags & PREPARE_STANDALONE_QUERY;
      
      
      
      if (reTry)
	{
	  if ((uniqueStmtId == NULL) ||
	      (uniqueStmtIdLen == NULL) ||
	      (*uniqueStmtIdLen <= 0))
	    {
	      // Error
	      diags << DgSqlCode(-CLI_STMT_NOT_EXISTS);
	      return SQLCLI_ReturnCode(&currContext,-CLI_STMT_NOT_EXISTS);
	    }
	  
	  stmt->setUniqueStmtId(uniqueStmtId);
	}

      // if uniqueStmt id buffer passed in contains a valid query id,
      // use that as the query id and it should be same as the one
      // that already exists
      else if ((uniqueStmtId) &&
	  (uniqueStmtIdLen) &&
           (*uniqueStmtIdLen >= (Lng32)strlen(COM_SESSION_ID_PREFIX)) &&
	  (str_cmp(uniqueStmtId, COM_SESSION_ID_PREFIX, strlen(COM_SESSION_ID_PREFIX)) == 0))
	{
          if (stmt->getUniqueStmtId() == NULL ||
            (*uniqueStmtIdLen) != stmt->getUniqueStmtIdLen() || 
            str_cmp(stmt->getUniqueStmtId(), uniqueStmtId, stmt->getUniqueStmtIdLen()) != 0)
          {
            diags << DgSqlCode(- CLI_QID_NOT_MATCHING);
            return SQLCLI_ReturnCode(&currContext,-CLI_QID_NOT_MATCHING);
	  }
	}
      else
	// generate a new query id.
	stmt->setUniqueStmtId(NULL);

      // Set the StmtStats in the shared segment
      stmt->setStmtStats(reTry);
      SQLCLI_Prepare_Setup_Pre(currContext, stmt, tmpFlags);
      if (! reTry)
	{
	  // new prepare. Clear any previously set retry condition.
	  aqr->clearRetryInfo();
	  stmt->aqrStmtInfo()->clearRetryInfo();
	  stmt->aqrStmtInfo()->setRetryPrepareFlags(tmpFlags);
	}

      if (ret_gencode_len == NULL)
	{
	  // assign passed in source str and gen code to 'this'
	  retcode =
	    stmt->prepare(strTarget.getStr(), diags, 
			  gencode_ptr, gencode_len, 
			  strTarget.getIntCharSet(), 
			  TRUE /* unpack tdbs */,
			  tmpFlags);
	  retrieveGenCode = FALSE;
	}
      else
	{
	  // prepare this statement.
	  retcode =
	    stmt->prepare(strTarget.getStr(), diags, 
			  NULL, 0L, 
			  strTarget.getIntCharSet(), 
			  FALSE,  /* do not unpack tdbs */
			  tmpFlags);
	  retrieveGenCode = TRUE;
	}
    }
  else
    retrieveGenCode = TRUE;

  if (uniqueStmtId)
    {
      if ((uniqueStmtIdLen) &&
	  (*uniqueStmtIdLen >= stmt->getUniqueStmtIdLen()))
	{
	  str_cpy_all(uniqueStmtId, stmt->getUniqueStmtId(),
		      stmt->getUniqueStmtIdLen());
	  *uniqueStmtIdLen = stmt->getUniqueStmtIdLen();
	}
    }

  if (isERROR(retcode))
    {
      return SQLCLI_ReturnCode(&currContext,retcode);
    }
  
    if (query_cost_info)
    {
      query_cost_info->cpuTime   = 0;
      query_cost_info->ioTime    = 0;
      query_cost_info->msgTime   = 0;
      query_cost_info->idleTime  = 0;
      query_cost_info->totalTime = 0;
      query_cost_info->cardinality = 0;
      query_cost_info->estimatedTotalMem  = 0;
      query_cost_info->resourceUsage = 0;
      query_cost_info->maxCpuUsage = 0;

      if (stmt->getRootTdb())
	{
	  if (stmt->getRootTdb()->getQueryCostInfo())
	    {
	      stmt->getRootTdb()->getQueryCostInfo()->translateToExternalFormat(query_cost_info);
	    }
	      
	  else
	    query_cost_info->totalTime = stmt->getRootTdb()->getCost();

	}
    }

  if (query_comp_stats_info)
    {
      if (stmt->getRootTdb())
	{
          CompilerStatsInfo *cmpStatsInfo = 
                      stmt->getRootTdb()->getCompilerStatsInfo();

	  if (cmpStatsInfo)
	    {
	      short xnNeeded = (stmt->transactionReqd() ? 1 : 0);
              cmpStatsInfo->translateToExternalFormat(query_comp_stats_info,xnNeeded);
	    }
	      
          // CompilationStatsData. 
	  CompilationStatsData *cmpData = 
	    stmt->getRootTdb()->getCompilationStatsData();


	  SQL_COMPILATION_STATS_DATA *query_cmp_data = 
	    &query_comp_stats_info->compilationStats;
  
	  if( cmpData )
	    {
              StmtStats  *stmtStats = stmt->getStmtStats();
              ExMasterStats *masterStats;
              Int64 cmpStartTime = -1;
              Int64 cmpEndTime = NA_JulianTimestamp();
              if (stmtStats != NULL && (masterStats = stmtStats->getMasterStats()) != NULL)
                 cmpStartTime = masterStats->getCompStartTime();
              
	      cmpData->translateToExternalFormat(query_cmp_data, 
                      cmpStartTime, cmpEndTime);
              stmt->setCompileEndTime(cmpEndTime);
	    }   
	}
	
    }
  

  // A cursor on an embedded INSERT is not supported.
  if (stmt->getRootTdb() && stmt->getRootTdb()->isEmbeddedInsert())
    {

      if (statement_id->identifier &&
    	  strstr ((char *) statement_id->identifier,"SQLCI_PREPSTMT_FOR_CURSOR_") != NULL)
	{
	  diags << DgSqlCode(-3409);
	  return SQLCLI_ReturnCode(&currContext,-3409);
	}
    }

  if (retrieveGenCode)
    {
      if (ret_gencode_len)
	*ret_gencode_len = stmt->getRootTdbSize();
      
      if ((gencode_ptr == NULL) ||
	  (gencode_len < stmt->getRootTdbSize()))
	{
	  diags << DgSqlCode(-CLI_GENCODE_BUFFER_TOO_SMALL);
	  return SQLCLI_ReturnCode(&currContext,-CLI_GENCODE_BUFFER_TOO_SMALL);
	}

      memcpy(gencode_ptr, stmt->getRootTdb(), stmt->getRootTdbSize());

      Lng32 unpackRetcode = stmt->unpackAndInit(diags, -1);
      if (isERROR(unpackRetcode) && !isERROR(retcode))
        retcode = unpackRetcode;

      // root tdb is not unpacked in some cases.
      // See Statement::unpackAndInit for details.
      // For those cases, do not do stats post prepare setup as that will
      // try to access fields in root tdb.
      if (NOT stmt->getRootTdb()->isFromShowplan())
	SQLCLI_Prepare_Setup_Post(currContext, stmt, tmpFlags);
    }
  else
    SQLCLI_Prepare_Setup_Post(currContext, stmt, tmpFlags);
    
  if (cliGlobals->currContext()->diags().getNumber())
    {
      return cliGlobals->currContext()->diags().mainSQLCODE();
    }
  else
    {
      return retcode;
    }
}

Lng32 SQLCLI_GetExplainData(
                            /*IN*/ CliGlobals * cliGlobals,
                            /*IN*/    SQLSTMT_ID * statement_id,
                            /*INOUT*/ char * explain_ptr,
                            /*IN*/    Int32 explain_buf_len,
                            /*INOUT*/ Int32 * ret_explain_len)
{
  Lng32 retcode = 0;

  // create initial context, if first call, and add module, if any.
  retcode = CliPrologue(cliGlobals,statement_id->module);
  if (isERROR(retcode))
    {
      return retcode;
    }

  ContextCli   & currContext = *(cliGlobals->currContext());
  ComDiagsArea & diags       = currContext.diags();

  /* get the statement from context */
  Statement * stmt = currContext.getStatement(statement_id);

  /* stmt must exist */
  if ((!stmt) || (!stmt->getRootTdb()) || (! ret_explain_len))
    {
      diags << DgSqlCode(-CLI_STMT_NOT_EXISTS);
      return SQLCLI_ReturnCode(&currContext,-CLI_STMT_NOT_EXISTS);
    }

  retcode = ExExplainTcb::getExplainData(stmt->getRootTdb(),
                                         explain_ptr, explain_buf_len, ret_explain_len,
                                         &diags, currContext.exCollHeap());
  
  if (diags.getNumber())
    {
      return diags.mainSQLCODE();
    }
  else if (retcode < 0)
    {
      diags << DgSqlCode(retcode);
      return retcode;
    }
  
  return retcode;
}

Lng32 SQLCLI_StoreExplainData(
                              /*IN*/ CliGlobals * cliGlobals,
                              /*IN*/ Int64 * exec_start_utc_ts,
                              /*IN*/    char * query_id,
                              /*INOUT*/ char * explain_ptr,
                              /*IN*/    Int32 explain_buf_len)
{
  Lng32 retcode = 0;

  // create initial context, if first call, and add module, if any.
  retcode = CliPrologue(cliGlobals, NULL);
  if (isERROR(retcode))
    {
      return retcode;
    }

  ContextCli   & currContext = *(cliGlobals->currContext());
  ComDiagsArea & diags       = currContext.diags();

  if ((! explain_ptr) || (explain_buf_len <= 0))
    {
      diags << DgSqlCode(-CLI_GENCODE_BUFFER_TOO_SMALL);
      return SQLCLI_ReturnCode(&currContext,-CLI_GENCODE_BUFFER_TOO_SMALL);
    }

  retcode = 
    ExExplainTcb::storeExplainInRepos(cliGlobals, exec_start_utc_ts,
                                      query_id, strlen(query_id), explain_ptr, explain_buf_len);
  if (retcode < 0)
    {
      if (diags.getNumber())
        {
          return diags.mainSQLCODE();
        }
      else
        {
          diags << DgSqlCode(retcode);
        }

      return retcode;
    }

  return retcode;
}

Lng32 SQLCLI_ResDescName(/*IN*/           CliGlobals * cliGlobals,
			/*INOUT*/        SQLDESC_ID * descriptor_id,
			/*IN  OPTIONAL*/ SQLSTMT_ID * from_statement,
			/* (SQLWHAT_DESC) *IN  OPTIONAL*/ Lng32 what_desc)
{
  Lng32 retcode;
  

  // create initial context, if first call, and add module, if any.
  retcode = CliPrologue(cliGlobals,descriptor_id->module);
  if (isERROR(retcode))
    return retcode;

  ContextCli   & currContext = *(cliGlobals->currContext());
  ComDiagsArea & diags       = currContext.diags();

  Descriptor * desc = 0;

  if (from_statement)
    {
      Statement * stmt = currContext.getStatement(from_statement);

      /* stmt must exist */
      if (!stmt)
        {
          diags << DgSqlCode(-CLI_STMT_NOT_EXISTS);
          return SQLCLI_ReturnCode(&currContext,-CLI_STMT_NOT_EXISTS);
        }

      desc = stmt->getDefaultDesc(what_desc);
    }
  else
    {
      desc = currContext.getDescriptor(descriptor_id);
    }

  /* desc must exist */
  if (!desc)
    {
      diags << DgSqlCode(-CLI_DESC_NOT_EXISTS);
      return SQLCLI_ReturnCode(&currContext,-CLI_DESC_NOT_EXISTS);
    }

  if (descriptor_id->name_mode == desc_handle)
    {
      descriptor_id->handle = desc->getDescHandle();
    }
  else if (descriptor_id->name_mode == desc_name)
    {
      if ((! descriptor_id->identifier) ||
	  (! desc->getDescName()) ||
	  (! desc->getDescName()->identifier))
	{
          diags << DgSqlCode(-CLI_INVALID_DESC_INFO_REQUEST);
          return SQLCLI_ReturnCode(&currContext,
                                   -CLI_INVALID_DESC_INFO_REQUEST);
	}

      // On input, descriptor_id->identifier_len contains the max length of 
      // the buffer where identifier name will be copied.
      // On output, it contains the actual length of the identifier copied.
      // Returned identifier is NOT null terminated as this method could
      // be called from both C and Cobol.
      Int32 lenToCopy = 
	MINOF(descriptor_id->identifier_len, 
	      desc->getDescName()->identifier_len);
      str_cpy_all((char*)descriptor_id->identifier, desc->getDescName()->identifier,
		  lenToCopy);
      descriptor_id->identifier_len = lenToCopy;
    }

  return SUCCESS;
}

Lng32 SQLCLI_ResStmtName(/*IN*/ CliGlobals * cliGlobals,
			/*INOUT*/ SQLSTMT_ID * statement_id)
{
  Lng32 retcode;

  // create initial context, if first call, and add module, if any.
  retcode = CliPrologue(cliGlobals,statement_id->module);
  if (isERROR(retcode))
    return retcode;

  ContextCli   & currContext = *(cliGlobals->currContext());
  ComDiagsArea & diags       = currContext.diags();

  /* get the statement */
  Statement * stmt = currContext.getStatement(statement_id);

  /* stmt must exist */
  if (!stmt)
    {
      diags << DgSqlCode(-CLI_STMT_NOT_EXISTS);
      return SQLCLI_ReturnCode(&currContext,-CLI_STMT_NOT_EXISTS);
    }

  statement_id->name_mode = stmt_handle;
  statement_id->handle = stmt->getStmtHandle();
  
  return SUCCESS;
}
// statement_id must point to an existing statement
// The Descriptor Id  cursor_name must be of name_mode 
// cursor_name or cursor_via_desc   **exception ODBC/JDBC

Lng32 SQLCLI_SetCursorName(/*IN*/ CliGlobals * cliGlobals,
			  /*IN*/ SQLSTMT_ID * statement_id,
                          /*IN*/ SQLSTMT_ID * cursor_id)// must of name_mode cursor_name or cursor_via_desc   **exception ODBC/JDBC
{
  Lng32 retcode;
  SQLDESC_ID *curs_id;

  NAHeap &heap      = *(cliGlobals->currContext()->exHeap());



  // create initial context, if first call, and add module, if any.
  retcode = CliPrologue(cliGlobals,statement_id->module);
  if (isERROR(retcode))
    return retcode;

  ContextCli   & currContext = *(cliGlobals->currContext());
  ComDiagsArea & diags       = currContext.diags();

  Statement * stmt = currContext.getStatement(statement_id);

  /* stmt must exist */
  if (!stmt)
    {
      diags << DgSqlCode(-CLI_STMT_NOT_EXISTS);
      return SQLCLI_ReturnCode(&currContext,-CLI_STMT_NOT_EXISTS);
    }
  else if (!stmt->allocated())
    {
      diags << DgSqlCode(-CLI_NOT_DYNAMIC_STMT)
            << DgString0("set cursor name for");

      return SQLCLI_ReturnCode(&currContext,-CLI_NOT_DYNAMIC_STMT);
    }


   // For the sake of ODBC/JDBC, we will leave this check in here
   // since they do not pass a STMT_ID for cursor_name but a DESC_ID
   // with name mode desc_handle
  if (cursor_id->name_mode == desc_handle)
    {
      Descriptor * desc = currContext.getDescriptor(cursor_id);
      /* descriptor must exist */
      if (!desc)
	{
    	  diags << DgSqlCode(-CLI_DESC_NOT_EXISTS);
          return SQLCLI_ReturnCode(&currContext,-CLI_DESC_NOT_EXISTS);
    	}
      stmt->setCursorName(desc->getVarData(1));
      
      return SUCCESS;
    }
  
  switch(cursor_id->name_mode)
    {
    case cursor_name:
      // Simply set the cursor name as it is passed. Do not parse it
      // Assumption is that the caller is passing it in  valid ansi format
      stmt->setCursorName(cursor_id->identifier);
      break; 
    case curs_via_desc:
      // This is the extended dynamic case. In this case the CLI will
      // convert/check the input to valid ansi format  
      curs_id = Descriptor::GetNameViaDesc((SQLDESC_ID *)cursor_id,&currContext,heap);
      if (curs_id)
    	stmt->setCursorName(curs_id->identifier);
      break;
    default:
      diags << DgSqlCode(-CLI_INVALID_ATTR_VALUE);
      return SQLCLI_ReturnCode(&currContext,-CLI_INVALID_ATTR_VALUE);
      break;
    }
  return SUCCESS;
}

Lng32 SQLCLI_SetStmtAttr( /*IN*/ CliGlobals *cliGlobals,
                         /*IN*/ SQLSTMT_ID *statement_id,
                         /*IN SQLATTR_TYPE */ Lng32 attrName, 
                         /*IN OPTIONAL*/      Lng32   numeric_value,
                         /*IN OPTIONAL*/      char * string_value)
{
  Lng32 retcode = SUCCESS;
  

  // create initial context, if first call, and add module, if any.
  retcode = CliPrologue(cliGlobals,statement_id->module);
  if (isERROR(retcode))
    return retcode;

  ContextCli   & currContext = *(cliGlobals->currContext());
  ComDiagsArea & diags       = currContext.diags();
  
  Statement * stmt = currContext.getStatement(statement_id);
  
  /* stmt must exist */
  if (!stmt)
    {
      diags << DgSqlCode(-CLI_STMT_NOT_EXISTS);
      return SQLCLI_ReturnCode(&currContext,-CLI_STMT_NOT_EXISTS);
    }
  
  if (attrName == SQL_ATTR_CURSOR_HOLDABLE) 
    {
      switch (numeric_value)
	{
	case SQL_NONHOLDABLE:
          retcode = stmt->setHoldable(diags, FALSE);
	  break;
	case SQL_HOLDABLE:
	  retcode = stmt->setHoldable(diags, TRUE);
	  break;
	default:
	  diags << DgSqlCode(-CLI_INVALID_ATTR_VALUE);
	  return SQLCLI_ReturnCode(&currContext,-CLI_INVALID_ATTR_VALUE);
	}
    }
  else if (attrName == SQL_ATTR_INPUT_ARRAY_MAXSIZE)   
    {
      retcode = stmt->setInputArrayMaxsize(diags, numeric_value);
    }
  else if (attrName == SQL_ATTR_ROWSET_ATOMICITY)
  {
    switch (numeric_value)
	{
	case SQL_NOT_SPECIFIED:
	  retcode = stmt->setRowsetAtomicity(diags, Statement::UNSPECIFIED_);
	  break;
	case SQL_ATOMIC:
	  retcode = stmt->setRowsetAtomicity(diags, Statement::ATOMIC_);
	  break;
	case SQL_NOT_ATOMIC:
	  retcode = stmt->setRowsetAtomicity(diags, Statement::NOT_ATOMIC_);
	  break;
	default:
	  diags << DgSqlCode(-CLI_INVALID_ATTR_VALUE);
	  return SQLCLI_ReturnCode(&currContext,-CLI_INVALID_ATTR_VALUE);
	}
    // If stmt is in INITIAL state then the statement did not get prepared.
    // Or if it is in PREPARE state, then it is a nowaited prepare which is
    //  still being prepared. 
    
    if ((stmt->getState() != Statement::INITIAL_) &&
	(stmt->getState() != Statement::PREPARE_))
      {
	diags << DgSqlCode(CLI_STMT_NEEDS_PREPARE);
	return SQLCLI_ReturnCode(&currContext,CLI_STMT_NEEDS_PREPARE);
      }
  }
  else if (attrName == SQL_ATTR_NOT_ATOMIC_FAILURE_LIMIT)   
    {
      if ((numeric_value >= 30)||
	(numeric_value == ComCondition::NO_LIMIT_ON_ERROR_CONDITIONS)) {
	retcode = stmt->setNotAtomicFailureLimit(diags, numeric_value);
      }
      else {
	diags << DgSqlCode(-CLI_INVALID_ATTR_VALUE);
	return SQLCLI_ReturnCode(&currContext,-CLI_INVALID_ATTR_VALUE);
      }
    }
  else if (attrName == SQL_ATTR_UNIQUE_STMT_ID)
    {
      stmt->setUniqueStmtId(string_value);
    }
  else if (attrName == SQL_ATTR_COPY_STMT_ID_TO_DIAGS)
    {
      diags.setAllSqlID(stmt->getUniqueStmtId());
    }
  else if (attrName == SQL_ATTR_PARENT_QID)
    {
      retcode = stmt->setParentQid(string_value);
      if (retcode != 0)
      {
        diags << DgSqlCode(retcode);
      }
    }
  else {
    diags << DgSqlCode(-CLI_INVALID_ATTR_NAME);
    return SQLCLI_ReturnCode(&currContext,-CLI_INVALID_ATTR_NAME);
    
  }

  if (retcode)
    return diags.mainSQLCODE();
  
  return retcode;
}

Lng32 SQLCLI_GetSessionAttr( /*IN*/ CliGlobals *cliGlobals,
			    /*IN SESSIONATTR_TYPE */ Lng32 attrName,
			    /*OUT OPTIONAL*/     Lng32 * numeric_value,
			    /*OUT OPTIONAL*/     char * string_value,
			    /*IN OPTIONAL*/      Lng32   max_string_len,
			    /*OUT OPTIONAL*/     Lng32 * len_of_item)
{
  Lng32 retcode = SUCCESS;


  // create initial context, if first call, and add module, if any.
  retcode = CliPrologue(cliGlobals, NULL);
  if (isERROR(retcode))
    return retcode;

  ContextCli   & currContext = *(cliGlobals->currContext());
  ComDiagsArea & diags       = currContext.diags();
  NABoolean bufferNullOrTooSmall = FALSE;

  switch (attrName)
  {
    case SESSION_ATTR_ID:
    {
      const char *sessionID = currContext.getSessionId();
      Int32 bytesNeeded = (sessionID ? strlen(sessionID) + 1 : 0);
      if (sessionID && string_value && max_string_len >= bytesNeeded)
        strcpy(string_value, sessionID);
      else
        bufferNullOrTooSmall = TRUE;
      if (len_of_item)
        *len_of_item = bytesNeeded;
    }
    break;
    
    case SESSION_PARENT_QID:
    {
      SessionDefaults *sd = currContext.getSessionDefaults();
      const char *queryID = (sd ? sd->getParentQid() : NULL);
      Int32 bytesNeeded = (queryID ? strlen(queryID) + 1 : 0);
      if (queryID && string_value && max_string_len >= bytesNeeded)
        strcpy(string_value, queryID);
      else
        bufferNullOrTooSmall = TRUE;
      if (len_of_item)
        *len_of_item = bytesNeeded;

      if (bufferNullOrTooSmall)
      {
        // Prior to Seaquest we were returning CLI_BUFFER_TOO_SMALL
        // (which is specific to query IDs) when the query ID target
        // buffer is null or too small. We will continue to return
        // that code in case any CLI callers expect it. For other
        // attributes we return a more general error saying the
        // "session attribute" is null or too small.
        diags << DgSqlCode(-CLI_BUFFER_TOO_SMALL);
        return SQLCLI_ReturnCode(&currContext,-CLI_BUFFER_TOO_SMALL);
      }
    }
    break;

    case SESSION_DATABASE_USER_NAME:
    {
      const char *authID = currContext.getDatabaseUserName();
      Int32 bytesNeeded = (authID ? strlen(authID) + 1 : 0);
      if (authID && string_value && max_string_len >= bytesNeeded)
        strcpy(string_value, authID);
      else
        bufferNullOrTooSmall = TRUE;
      if (len_of_item)
        *len_of_item = bytesNeeded;
    }
    break;
    
    case SESSION_DATABASE_USER_ID:
    {
      Int32 *userID = currContext.getDatabaseUserID();
      ex_assert(userID, "Context user ID should never be NULL");
      if (numeric_value)
        *numeric_value = *userID;
      else
        bufferNullOrTooSmall = TRUE;
    }
    break;

    case SESSION_SESSION_USER_ID:
    {
      Int32 *sessionUserID = currContext.getSessionUserID();
      ex_assert(sessionUserID, "Context session user ID should never be NULL");
      if (numeric_value)
        *numeric_value = *sessionUserID;
      else
        bufferNullOrTooSmall = TRUE;
    }
    break;

    case SESSION_EXTERNAL_USER_NAME:
    {
      const char *externalUsername = currContext.getExternalUserName();
      Int32 bytesNeeded = (externalUsername ? strlen(externalUsername) + 1 : 0);
      if (externalUsername && string_value && max_string_len >= bytesNeeded)
        strcpy(string_value, externalUsername);
      else
        bufferNullOrTooSmall = TRUE;
      if (len_of_item)
        *len_of_item = bytesNeeded;
    }
    break;

    default:
    {
      diags << DgSqlCode(-CLI_INVALID_ATTR_NAME);
      return SQLCLI_ReturnCode(&currContext,-CLI_INVALID_ATTR_NAME);
    }
    break;

  } // switch (attrName)

  if (bufferNullOrTooSmall)
  {
    diags << DgSqlCode(-CLI_SESSION_ATTR_BUFFER_TOO_SMALL);
    return SQLCLI_ReturnCode(&currContext,
                             -CLI_SESSION_ATTR_BUFFER_TOO_SMALL);
  }
  
  return SUCCESS;
}


Lng32 SQLCLI_GetAuthID(
   CliGlobals * cliGlobals,
   const char * authName,
   Lng32 & authID)
   
{

Lng32 retcode = 0;

// create initial context, if first call, and add module, if any.
   retcode = CliPrologue(cliGlobals, NULL);
   if (isERROR(retcode))
      return retcode;

ContextCli &currContext = *(cliGlobals->currContext());
ComDiagsArea &diags = currContext.diags();

   retcode = currContext.getAuthIDFromName(authName,authID);

   return CliEpilogue(cliGlobals, NULL, retcode);

}

Lng32 SQLCLI_GetAuthName (
    /*IN*/            CliGlobals *cliGlobals,
    /*IN*/            Lng32       auth_id,
    /*OUT*/           char       *string_value,
    /*IN*/            Lng32       max_string_len,
    /*OUT */          Lng32      &len_of_item)
{
  Lng32 retcode = 0;

  // create initial context, if first call, and add module, if any.
  retcode = CliPrologue(cliGlobals, NULL);
  if (isERROR(retcode))
    return retcode;

  ContextCli &currContext = *(cliGlobals->currContext());
  ComDiagsArea &diags = currContext.diags();

  retcode = currContext.getAuthNameFromID(auth_id,
                                          string_value,
                                          max_string_len,
                                          len_of_item);

  return CliEpilogue(cliGlobals, NULL, retcode);
}

Lng32 SQLCLI_GetDatabaseUserName (
    /*IN*/            CliGlobals *cliGlobals,
    /*IN*/            Lng32       user_id,
    /*OUT*/           char       *string_value,
    /*IN*/            Lng32       max_string_len,
    /*OUT OPTIONAL*/  Lng32      *len_of_item)
{
  Lng32 retcode = 0;


  // create initial context, if first call, and add module, if any.
  retcode = CliPrologue(cliGlobals, NULL);
  if (isERROR(retcode))
    return retcode;

  ContextCli &currContext = *(cliGlobals->currContext());
  ComDiagsArea &diags = currContext.diags();

  retcode = currContext.getAuthNameFromID(user_id,
                                          string_value,
                                          max_string_len,
                                         *len_of_item);

  return CliEpilogue(cliGlobals, NULL, retcode);
}

Lng32 SQLCLI_GetDatabaseUserID (
    /*IN*/            CliGlobals *cliGlobals,
    /*IN*/            char       *string_value,
    /*OUT*/           Lng32      *numeric_value)
{
  Lng32 retcode = 0;


  // create initial context, if first call, and add module, if any.
  retcode = CliPrologue(cliGlobals, NULL);
  if (isERROR(retcode))
    return retcode;

  ContextCli &currContext = *(cliGlobals->currContext());
  ComDiagsArea &diags = currContext.diags();

  retcode = currContext.getAuthIDFromName(string_value,
                                          *numeric_value);

  return CliEpilogue(cliGlobals, NULL, retcode);
}

Int32 SQLCLI_GetAuthState (
    /*IN*/            CliGlobals *cliGlobals,
    /*OUT*/           bool       &authenticationEnabled,
    /*OUT*/           bool       &authorizationEnabled,
    /*OUT*/           bool       &authorizationReady,
    /*OUT*/           bool       &auditingEnabled)
{
  Int32 retcode = 0;


  // create initial context, if first call, and add module, if any.
  retcode = CliPrologue(cliGlobals, NULL);
  if (isERROR(retcode))
    return retcode;

  ContextCli &currContext = *(cliGlobals->currContext());
  ComDiagsArea &diags = currContext.diags();

  currContext.getAuthState(authenticationEnabled,
                           authorizationEnabled,
                           authorizationReady,
                           auditingEnabled);

  return CliEpilogue(cliGlobals, NULL, retcode);
}

Lng32 SQLCLI_GetRoleList(
   CliGlobals * cliGlobals,
   Int32 &numEntries,
   Int32 *& roleIDs,
   Int32 *& granteeIDs)

{
   Lng32 retcode = 0;

   // create initial context, if first call, and add module, if any.
   retcode = CliPrologue(cliGlobals, NULL);
   if (isERROR(retcode))
      return retcode;

   ContextCli &currContext = *(cliGlobals->currContext());
   ComDiagsArea &diags = currContext.diags();

   retcode = currContext.getRoleList(numEntries,roleIDs,granteeIDs);

   return CliEpilogue(cliGlobals, NULL, retcode);

}

Lng32 SQLCLI_ResetRoleList(
   CliGlobals * cliGlobals)

{
   Lng32 retcode = 0;

   // create initial context, if first call, and add module, if any.
   retcode = CliPrologue(cliGlobals, NULL);
   if (isERROR(retcode))
      return retcode;

   ContextCli &currContext = *(cliGlobals->currContext());
   ComDiagsArea &diags = currContext.diags();

   retcode = currContext.resetRoleList();

   return CliEpilogue(cliGlobals, NULL, retcode);

}


Lng32 SQLCLI_SetSessionAttr(/*IN*/ CliGlobals *cliGlobals,
			    /*IN SESSIONATTR_TYPE*/ Lng32 attrName,
			    /*IN OPTIONAL*/         Lng32 numeric_value,
                            /*IN OPTIONAL*/         char *string_value)
{
  Lng32 retcode = SUCCESS;


  // create initial context, if first call, and add module, if any.
  retcode = CliPrologue(cliGlobals, NULL);
  if (isERROR(retcode))
    return retcode;

  ContextCli &currContext = *(cliGlobals->currContext());
  ComDiagsArea &diags = currContext.diags();

  switch (attrName)
  {
    case SESSION_DATABASE_USER_ID:
    {
      retcode = currContext.setDatabaseUserByID(numeric_value);
    }
    break;

    case SESSION_DATABASE_USER_NAME:
    {
      retcode = currContext.setDatabaseUserByName(string_value);
    }
    break;

    case SESSION_DATABASE_USER:
    {
      // The call to setDatabaseUser set values in the Context
      // it does not return any errors
      currContext.setDatabaseUser(numeric_value, string_value);
    }
    break;

    case SESSION_PARENT_QID:
    {
      SessionDefaults *sd = currContext.getSessionDefaults();
      if (sd && string_value)
        sd->setParentQid(string_value, strlen(string_value));
    }
    break;
    default:
    {
      // Other attributes can be supported in time
      diags << DgSqlCode(-CLI_INVALID_ATTR_NAME);
      return SQLCLI_ReturnCode(&currContext,-CLI_INVALID_ATTR_NAME);
    }
    break;
  }

  return CliEpilogue(cliGlobals, NULL);
}

Lng32 SQLCLI_GetUniqueQueryIdAttrs( /*IN*/ CliGlobals *cliGlobals,
				   /*IN*/    char * queryId,
				   /*IN*/    Lng32 queryIdLen,
				   /*IN*/    Lng32 no_of_attrs,
				   /*INOUT*/ UNIQUEQUERYID_ATTR queryid_attrs[])
{
  Lng32 retcode = SUCCESS;


  // create initial context, if first call, and add module, if any.
  retcode = CliPrologue(cliGlobals, NULL);
  if (isERROR(retcode))
    return retcode;

  ContextCli   & currContext = *(cliGlobals->currContext());
  ComDiagsArea & diags       = currContext.diags();

  /* stmt must exist */
  if (!queryId)
    {
      diags << DgSqlCode(-CLI_STMT_NOT_EXISTS);
      return SQLCLI_ReturnCode(&currContext,-CLI_STMT_NOT_EXISTS);
    }

  for (Int32 i = 0; i < no_of_attrs && !retcode; i++)
    {
      Int64 temp_nvol = (Int64)queryid_attrs[i].num_val_or_len;
      retcode = ComSqlId::getSqlQueryIdAttr(queryid_attrs[i].attr_type,
				  queryId, queryIdLen,
				  temp_nvol,
				  queryid_attrs[i].string_val);
      queryid_attrs[i].num_val_or_len = temp_nvol;
    }

  return retcode;
}

// A helper function to copy one statement attribute into the target
// buffer
Lng32 CopyOneStmtAttr (/*IN*/   Statement &stmt,
                      /*IN*/   ContextCli &context,
                      /*OUT*/  ComDiagsArea &diags,
                      /*IN*/   Lng32  attrName,
                      /*IN*/   Lng32  index,
                      /*OUT*/  Lng32 *numeric_value,
                      /*OUT*/  char *string_value,
                      /*IN*/   Lng32  max_string_len,
                      /*OUT*/  Lng32 *len_of_item )
{
  Lng32 retcode = SUCCESS;

  if (attrName == SQL_ATTR_CURSOR_HOLDABLE)
  {    
    if (stmt.isAnsiHoldable() || stmt.isPubsubHoldable())
    {
      *numeric_value = SQL_HOLDABLE;
    }
    else
    {
      *numeric_value = SQL_NONHOLDABLE;
    }
  }
  else if (attrName == SQL_ATTR_INPUT_ARRAY_MAXSIZE)
  {
    *numeric_value = (Lng32) stmt.getInputArrayMaxsize() ;
  }
  else if (attrName == SQL_ATTR_QUERY_TYPE)
  {
    if (!stmt.getRootTdb())
    {
      //for display query e.g. display select ...
      //just return SUCCESS to suppress error message
      if(stmt.isDISPLAY())
        {
          return SQLCLI_ReturnCode(&context, DISPLAY_DONE_WARNING);
        }
      else
        {
          diags << DgSqlCode(-CLI_STMT_NOT_EXISTS);
          return SQLCLI_ReturnCode(&context, -CLI_STMT_NOT_EXISTS);
        }
    }
    *numeric_value = stmt.getRootTdb()->getQueryType();
  }
  else if (attrName == SQL_ATTR_SUBQUERY_TYPE)
  {
    if (!stmt.getRootTdb())
    {
      //for display query e.g. display select ...
      //just return SUCCESS to suppress error message
      if(stmt.isDISPLAY())
        {
          return SQLCLI_ReturnCode(&context, DISPLAY_DONE_WARNING);
        }
      else
        {
          diags << DgSqlCode(-CLI_STMT_NOT_EXISTS);
          return SQLCLI_ReturnCode(&context, -CLI_STMT_NOT_EXISTS);
        }
    }
    *numeric_value = stmt.getRootTdb()->getSubqueryType();
  }
  else if (attrName == SQL_ATTR_MAX_RESULT_SETS)
  {
    if (!stmt.getRootTdb())
    {
      diags << DgSqlCode(-CLI_STMT_NOT_EXISTS);
      return SQLCLI_ReturnCode(&context, -CLI_STMT_NOT_EXISTS);
    }
    *numeric_value = stmt.getRootTdb()->getMaxResultSets();
  }
  else if (attrName == SQL_ATTR_XN_NEEDED)
    {
      *numeric_value = 
      (stmt.getRootTdb()->transactionReqd() ? 1 : 0);
    }
  else if (attrName == SQL_ATTR_UNIQUE_STMT_ID)
    {
    Lng32 actual_len = stmt.getUniqueStmtIdLen();

    if (len_of_item)
      *len_of_item = actual_len;

    if (stmt.getUniqueStmtId())
        {
          if ((max_string_len) && (actual_len > max_string_len))
          {
	    diags << DgSqlCode(-CLI_BUFFER_TOO_SMALL);
            return SQLCLI_ReturnCode(&context,-CLI_BUFFER_TOO_SMALL);
          }

          strncpy(string_value, stmt.getUniqueStmtId(), 
                  stmt.getUniqueStmtIdLen());
        }
    }
  else if (attrName == SQL_ATTR_RS_PROXY_SYNTAX)
  {
    if (!stmt.getRootTdb())
    {
      diags << DgSqlCode(-CLI_STMT_NOT_EXISTS);
      return SQLCLI_ReturnCode(&context, -CLI_STMT_NOT_EXISTS);
    }
    
    stmt.getRSProxySyntax(string_value, max_string_len, len_of_item);
    
    if (!string_value || (len_of_item && (max_string_len < *len_of_item)))
    {
      diags << DgSqlCode(-CLI_RS_PROXY_BUFFER_SMALL_OR_NULL);
      return SQLCLI_ReturnCode(&context,
                               -CLI_RS_PROXY_BUFFER_SMALL_OR_NULL);
    }
  }
  else if (attrName == SQL_ATTR_CONSUMER_QUERY_TEXT)
  {
    Lng32 actual_len = stmt.getConsumerQueryLen(index - 1);
    if (len_of_item)
      *len_of_item = actual_len;
    if (actual_len > 0)
    {
      if (actual_len > max_string_len)
      {
        diags << DgSqlCode(-CLI_CONSUMER_QUERY_BUF_TOO_SMALL)
              << DgInt0(index);
        return SQLCLI_ReturnCode(&context,-CLI_CONSUMER_QUERY_BUF_TOO_SMALL);
      }
      stmt.getConsumerQuery(index - 1,
                            string_value, max_string_len);
    }
  }
  else if (attrName == SQL_ATTR_CONSUMER_CPU)
  {
    *numeric_value = stmt.getConsumerCpu(index - 1);
  }
  else if (attrName == SQL_ATTR_PARENT_QID)
  {
   
    Lng32 actual_len;
    const char *parentQid = stmt.getParentQid();
    if (parentQid)
      actual_len = str_len(parentQid);
    else
      actual_len = 0;
    if (len_of_item)
	*len_of_item = actual_len;
    if (parentQid)
    {
      if ((max_string_len) && (actual_len > max_string_len))
      {
	diags << DgSqlCode(-CLI_BUFFER_TOO_SMALL);
        return SQLCLI_ReturnCode(&context,-CLI_BUFFER_TOO_SMALL);
      }
      strncpy(string_value, parentQid, actual_len);
    }
    
  }
  else if (attrName == SQL_ATTR_CURSOR_UPDATABLE)
  {
    if (stmt.getRootTdb())
    {
      *numeric_value = stmt.getRootTdb()->getCursorType();
    }
    else
    {
       diags << DgSqlCode(-CLI_STMT_NOT_EXISTS);
       return SQLCLI_ReturnCode(&context, -CLI_STMT_NOT_EXISTS);
    }
   
  }
  else
  {
    diags << DgSqlCode(-CLI_INVALID_ATTR_NAME);
    return SQLCLI_ReturnCode(&context,-CLI_INVALID_ATTR_NAME);
  }
  
  return retcode;
}

Lng32 SQLCLI_GetStmtAttr( /*IN*/ CliGlobals *cliGlobals,
                         /*IN*/ SQLSTMT_ID *statement_id,
                         /*IN SQLATTR_TYPE */ Lng32 attrName,
                         /*OUT OPTIONAL*/     Lng32 * numeric_value,
                         /*OUT OPTIONAL*/     char * string_value,
                         /*IN OPTIONAL*/      Lng32   max_string_len,
                         /*OUT OPTIONAL*/     Lng32 * len_of_item)
{
  Lng32 retcode = SUCCESS;


  // create initial context, if first call, and add module, if any.
  retcode = CliPrologue(cliGlobals,statement_id->module);
  if (isERROR(retcode))
    return retcode;

  ContextCli   & currContext = *(cliGlobals->currContext());
  ComDiagsArea & diags       = currContext.diags();

  Statement * stmt = currContext.getStatement(statement_id);
  
  /* stmt must exist */
  if (!stmt)
  {
    diags << DgSqlCode(-CLI_STMT_NOT_EXISTS);
    return SQLCLI_ReturnCode(&currContext,-CLI_STMT_NOT_EXISTS);
  }

  retcode = CopyOneStmtAttr(*stmt, currContext, diags,
                            attrName, 0, numeric_value, string_value,
                            max_string_len, len_of_item);
  return retcode;
}

Lng32 SQLCLI_GetStmtAttrs( /*IN*/ CliGlobals *cliGlobals,
                          /*IN*/ SQLSTMT_ID *statement_id,
                          /*IN*/           Lng32 number_of_attrs,
                          /*INOUT*/        SQLSTMT_ATTR attrs[],
                          /*OUT OPTIONAL*/ Lng32 * num_returned)
{

  Lng32 retcode = SUCCESS;
  *num_returned = 0;

  // create initial context, if first call, and add module, if any.
  retcode = CliPrologue(cliGlobals,statement_id->module);
  if (isERROR(retcode))
    return retcode;

  ContextCli   & currContext = *(cliGlobals->currContext());
  ComDiagsArea & diags       = currContext.diags();

  Statement * stmt = currContext.getStatement(statement_id);
  
  /* stmt must exist */
  if (!stmt)
  {
    diags << DgSqlCode(-CLI_STMT_NOT_EXISTS);
    return SQLCLI_ReturnCode(&currContext,-CLI_STMT_NOT_EXISTS);
  }

  for (Int32 i = 0; i < number_of_attrs && retcode >= 0; i++)
  {
    const SQLSTMT_ATTR &attr = attrs[i];
    retcode = CopyOneStmtAttr(*stmt, currContext, diags,
                              attr.attr_type, attr.index, attr.numeric_value, 
                              attr.string_value, attr.max_string_len,
                              attr.len_of_item);
    if (retcode >= 0)
      (*num_returned)++;
    }
  
  return retcode;
}
Lng32 SQLCLI_SetDescEntryCount(/*IN*/ CliGlobals * cliGlobals,
			      /*IN*/ SQLDESC_ID * desc_id,
                              /*IN*/ SQLDESC_ID * input_descriptor)
{
  Lng32 retcode;

  if (!desc_id)
    return -CLI_INTERNAL_ERROR;


  // create initial context, if first call, and add module, if any.
  retcode = CliPrologue(cliGlobals,desc_id->module);
  if (isERROR(retcode))
    return retcode;

  ContextCli   & currContext = *(cliGlobals->currContext());
  ComDiagsArea & diags       = currContext.diags();

  Descriptor * desc = currContext.getDescriptor(desc_id);

  /* descriptor must exist */
  if (!desc)
    {
      diags << DgSqlCode(-CLI_DESC_NOT_EXISTS);
      return SQLCLI_ReturnCode(&currContext,-CLI_DESC_NOT_EXISTS);
    }

  Descriptor * input_desc = currContext.getDescriptor(input_descriptor);

  /* descriptor must exist */
  if (!input_desc)
    {
      diags << DgSqlCode(-CLI_DESC_NOT_EXISTS);
      return SQLCLI_ReturnCode(&currContext,-CLI_DESC_NOT_EXISTS);
    }

  // JORGE: Why are we doing it this way. It may be better if we call
  //        getUsedEntryCount() on the input descriptor. ??

  Lng32 num_entries = 0L;
  retcode = InputValueFromNumericHostvar(
                                         input_desc,
                                         1,
                                         num_entries);
  if (isERROR(retcode))
    return SQLCLI_ReturnCode(&currContext,retcode);

  desc->setUsedEntryCount(num_entries);
  
  //Now allocate the space for num_entries worth of descriptors.
  desc->addEntry(num_entries);
  
  return SUCCESS;
}
Lng32 SQLCLI_SetDescItems(/*IN*/ CliGlobals * cliGlobals,
			 /*IN*/   SQLDESC_ID * desc_id,
                           /*IN*/ SQLDESC_ITEM   desc_items[],
                           /*IN*/   SQLDESC_ID * value_num_descriptor,
                           /*IN*/   SQLDESC_ID * input_descriptor)
{
  Lng32 retcode;
  Lng32 first_set = SQLDESC_ITEM_ORDER_COUNT, desc_item_entry[SQLDESC_ITEM_ORDER_COUNT];
  const Lng32 not_set = -1;


  // create initial context, if first call, and add module, if any.
  retcode = CliPrologue(cliGlobals,desc_id->module);
  if (isERROR(retcode))
    return retcode;

  ContextCli   & currContext = *(cliGlobals->currContext());
  ComDiagsArea & diags       = currContext.diags();

  Descriptor * desc = currContext.getDescriptor(desc_id);

  /* descriptor must exist */
  if (!desc)
    {
      diags << DgSqlCode(-CLI_DESC_NOT_EXISTS);
      return SQLCLI_ReturnCode(&currContext,-CLI_DESC_NOT_EXISTS);
    }

  Descriptor * value_num_desc = currContext.getDescriptor(value_num_descriptor);

  /* descriptor must exist */
  if (!value_num_desc)
    {
      diags << DgSqlCode(-CLI_DESC_NOT_EXISTS);
      return SQLCLI_ReturnCode(&currContext,-CLI_DESC_NOT_EXISTS);
    }

  Descriptor * input_desc = currContext.getDescriptor(input_descriptor);

  /* descriptor must exist */
  if (!input_desc)
    {
      diags << DgSqlCode(-CLI_DESC_NOT_EXISTS);
      return SQLCLI_ReturnCode(&currContext,-CLI_DESC_NOT_EXISTS);
    }


  Lng32 inputUsedEntryCount = input_desc->getUsedEntryCount();

  Lng32 i = 0;
  for (; i < SQLDESC_ITEM_ORDER_COUNT; i ++)
    desc_item_entry[i] = not_set;
  for (i = 0; i < inputUsedEntryCount; i++)
    if (desc_items[i].item_id <= SQLDESC_ITEM_MAX &&
        SQLDESC_ITEM_ORDER[desc_items[i].item_id-1] >= 0 &&
        desc_item_entry[SQLDESC_ITEM_ORDER[desc_items[i].item_id-1]] == not_set) {
      desc_item_entry[SQLDESC_ITEM_ORDER[desc_items[i].item_id-1]] = i;
      if (SQLDESC_ITEM_ORDER[desc_items[i].item_id-1] < first_set)
        first_set = SQLDESC_ITEM_ORDER[desc_items[i].item_id-1];
    }
    else {
      diags << DgSqlCode(-CLI_INVALID_DESC_ENTRY);
      return diags.mainSQLCODE();
    }

  for (Lng32 j = first_set, count = 0; count < inputUsedEntryCount; j++) {
    if (desc_item_entry[j] != not_set) {
      count += 1;
      i = desc_item_entry[j];
      //
      // Get the entry number of the descriptor entry whose item is to be set.
      //
      Lng32 entry = 0L;
      retcode = InputValueFromNumericHostvar(
           value_num_desc,
           desc_items[i].value_num_desc_entry,
           entry);

      if (isERROR(retcode))
	return SQLCLI_ReturnCode(&currContext,retcode);
      if (entry > desc->getMaxEntryCount())
        {
          diags << DgSqlCode(-CLI_INVALID_DESC_ENTRY);
          return diags.mainSQLCODE();
        }

      if (entry > desc->getUsedEntryCount()) {
        retcode = desc->addEntry(entry);

        if (isERROR(retcode))
          {
            diags << DgSqlCode(-CLI_INTERNAL_ERROR);
            return SQLCLI_ReturnCode(&currContext,-CLI_INTERNAL_ERROR);
          }
      }
      //
      // Get the address of the source where the item's value is stored.
      //
      char *var_ptr = 0;
      retcode = input_desc->getDescItem(i+1,
                                        SQLDESC_VAR_PTR,
                                        (Lng32 *)&var_ptr,
                                        NULL, 0, NULL, 0);
      if (isERROR(retcode))
        return SQLCLI_ReturnCode(&currContext,retcode);

      if (!var_ptr)
        return -CLI_INTERNAL_ERROR;

    // if item to be set is vardata, get input data length.
    // This is needed so that we can make a copy of input data.
    // Do the same for any attribute that need copying of data,
    // like SQLDESC_NAME, etc.
      Lng32 numericInput;
      numericInput = *(Lng32*)var_ptr;
      
      if ((desc_items[i].item_id == SQLDESC_VAR_DATA) ||
      (desc_items[i].item_id == SQLDESC_NAME) ||
      (desc_items[i].item_id == SQLDESC_HEADING))
        {
          Lng32 length;
          retcode = 
            input_desc->getDescItem(i+1, SQLDESC_LENGTH, &length, 0, 0, 0, 0);
          if (isERROR(retcode))
            return SQLCLI_ReturnCode(&currContext,retcode);
          
          numericInput = length;
        }
      
      //get size of memory to be bounds checked
      Int32 memorySize = input_desc->getVarDataLength(i+1);
      
      //if setting indicator variable get length of indicator variable
      if((desc_items[i].item_id == SQLDESC_IND_PTR)||
         (desc_items[i].item_id == SQLDESC_IND_DATA)){
        //since indicator, get length of indicator
        memorySize = input_desc->getIndLength(i+1);
      }
      
      if(currContext.boundsCheckMemory((void*)var_ptr,memorySize))
        return SQLCLI_ReturnCode(&currContext,
				 -CLI_USER_MEMORY_IN_EXECUTOR_SEGMENT);
      //
      // Set the item in the descriptor.
      //
      retcode = desc->setDescItem(entry,
                        desc_items[i].item_id,
                numericInput,
                        var_ptr, input_desc, i);
      if (isERROR(retcode))
        return SQLCLI_ReturnCode(&currContext,retcode);
    }
  }
  return SUCCESS;
}

Lng32 SQLCLI_SetDescItems2(/*IN*/ CliGlobals * cliGlobals,
			  /*IN*/ SQLDESC_ID * desc_id,
			  /*IN*/ Lng32 no_of_desc_items,
			  /*IN*/ SQLDESC_ITEM   desc_items[])
{
  Lng32 retcode;


  // create initial context, if first call, and add module, if any.
  retcode = CliPrologue(cliGlobals,desc_id->module);
  if (isERROR(retcode))
    return retcode;

  ContextCli   & currContext = *(cliGlobals->currContext());
  ComDiagsArea & diags       = currContext.diags();

  Descriptor * desc = currContext.getDescriptor(desc_id);

  /* descriptor must exist */
  if (!desc)
    {
      diags << DgSqlCode(-CLI_DESC_NOT_EXISTS);
      return SQLCLI_ReturnCode(&currContext,-CLI_DESC_NOT_EXISTS);
    }

  for (Lng32 i = 0; i < no_of_desc_items; i++) 
    {
      //
      // Get the entry number of the descriptor entry whose item is to be
      // set.
      //
      Lng32 entry = desc_items[i].entry;

      if (entry > desc->getUsedEntryCount()) 
	{
	  retcode = desc->addEntry(entry);
	  if (isERROR(retcode))
	    {
	      diags << DgSqlCode(-CLI_INTERNAL_ERROR);
	      return SQLCLI_ReturnCode(&currContext,-CLI_INTERNAL_ERROR);
	    }
	}

      // if item to be set is vardata, get input data length.
      // This is needed so that we can make a copy of input data.
      // Do the same for any attribute that need copying of data,
      // like SQLDESC_NAME, etc.
      if ((desc_items[i].item_id == SQLDESC_VAR_DATA) ||
	  (desc_items[i].item_id == SQLDESC_CHAR_SET_NAM) ||
	  (desc_items[i].item_id == SQLDESC_NAME) ||
	  (desc_items[i].item_id == SQLDESC_HEADING))
	{
	  if (currContext.boundsCheckMemory((void*)desc_items[i].string_val,
					    desc_items[i].num_val_or_len))
	    return SQLCLI_ReturnCode(&currContext,
				     -CLI_USER_MEMORY_IN_EXECUTOR_SEGMENT);

	}
      
      //
      // Set the item in the descriptor.
      //
      retcode = desc->setDescItem(desc_items[i].entry,
				  desc_items[i].item_id,
				  desc_items[i].num_val_or_len,
				  desc_items[i].string_val);
      if (isERROR(retcode))
	return SQLCLI_ReturnCode(&currContext,retcode);
    }
  
  return SUCCESS;
}

Lng32 SQLCLI_SetDescPointers(/*IN*/         CliGlobals * cliGlobals,
                              /*IN*/       SQLDESC_ID * desc_id,
                              /*IN*/             Lng32   starting_entry,
                              /*IN*/             Lng32   num_ptr_pairs,
                              /*IN*/          va_list   ap,
                              /*IN*/ SQLCLI_PTR_PAIRS   ptr_pairs[])
{
  Lng32 retcode = SUCCESS;


  // create initial context, if first call, and add module, if any.
  retcode = CliPrologue(cliGlobals,desc_id->module);
  if (isERROR(retcode))
    return retcode;

  ContextCli   & currContext = *(cliGlobals->currContext());
  ComDiagsArea & diags       = currContext.diags();

  Descriptor * desc = currContext.getDescriptor(desc_id);

  /* descriptor must exist */
  if (!desc)
    {
      diags << DgSqlCode(-CLI_DESC_NOT_EXISTS);
      return SQLCLI_ReturnCode(&currContext,-CLI_DESC_NOT_EXISTS);
    }
  
  va_list cpy;
  va_copy(cpy, ap);
  va_end(ap);
  
  retcode = local_SetDescPointers(desc, starting_entry, num_ptr_pairs, &cpy, ptr_pairs);
  va_end(ap);

  return SQLCLI_ReturnCode(&currContext,retcode);
}

Lng32 SQLCLI_SwitchContext(
     /*IN*/ CliGlobals * cliGlobals,
     /*IN*/           SQLCTX_HANDLE   context_handle,
     /*OUT OPTIONAL*/ SQLCTX_HANDLE * prev_context_handle,
     /*IN */    bool allowSwitchBackToDefault )
{
  Lng32 retcode = SUCCESS;

  ContextCli   & currContext = *(cliGlobals->currContext());
  ComDiagsArea & diags       = currContext.diags();

  if (!allowSwitchBackToDefault && (context_handle == cliGlobals->getDefaultContext()->getContextHandle()))
  {
     diags << DgSqlCode(-CLI_DEFAULT_CONTEXT_NOT_ALLOWED);
     return SQLCLI_ReturnCode(&currContext,-CLI_DEFAULT_CONTEXT_NOT_ALLOWED);
  }

  // find the new context 
  ContextCli * newContext = cliGlobals->getContext(context_handle);
  if (! newContext)
  {
     diags << DgSqlCode(-CLI_CONTEXT_NOT_FOUND);
     return SQLCLI_ReturnCode(&currContext,-CLI_CONTEXT_NOT_FOUND);
  }
  try
  {
    if (prev_context_handle)
       *prev_context_handle = currContext.getContextHandle();

  // The CLI sometimes starts transactions during recursive CLI
  // calls (e.g. metadata lookup or resource fork reads during
  // fixup). Such transactions should have been committed before
  // the top-level CLI call returned. Make sure this is true
  // before allowing a switch context; if it is not true, data
  // integrity could be compromised if another context inherits
  // such a transaction.
  ExTransaction * exTransaction = currContext.getTransaction();
  if (exTransaction != NULL && exTransaction->exeStartedXnDuringRecursiveCLICall())
    {
      // abort the transaction so this problem doesn't persist
      exTransaction->rollbackStatement();

      // report the error
      diags << DgSqlCode(-CLI_INTERR_ON_CONTEXT_SWITCH);
      return SQLCLI_ReturnCode(&currContext,-CLI_INTERR_ON_CONTEXT_SWITCH);
    }

  // Recursive calls to the CLI assume that the context is not
  // changed. Therefore, prevent attempts within the CLI to
  // switch contexts.
  if (currContext.getNumOfCliCalls() > 1)
  {
      // Just raise a vanilla internal error; this should never
      // happen.
      //diags << DgSqlCode(-CLI_INTERNAL_ERROR);
      //tmpSemaphore->release();
      //return SQLCLI_ReturnCode(&currContext,-CLI_INTERNAL_ERROR);
  }

  // Do not call CliPrologue which will switch transaction.
  // Wait till next CLI call to do the switching.

    retcode = cliGlobals->switchContext(newContext);
    if (retcode != 0)
    {
      diags << DgSqlCode(-20567)
          << DgInt0(retcode);
      return SQLCLI_ReturnCode(&currContext,-20567);
    }
  }
  catch (...)
  {
     return -CLI_INTERNAL_ERROR;
  }
  return retcode;
}

Lng32 SQLCLI_Xact(/*IN*/ CliGlobals * cliGlobals,
		 /* IN (SQLTRANS_COMMAND) */       Lng32   command,
		 /* OUT OPTIONAL */          SQLDESC_ID * transid_descriptor)
{
  Lng32 retcode;
  

  // create initial context, if first call, and add module, if any.
  retcode = CliPrologue(cliGlobals,0);

  if (isERROR(retcode))
    return retcode;

  ContextCli   & currContext = *(cliGlobals->currContext());
  ComDiagsArea & diags       = currContext.diags();

  switch (command)
    {
    case SQLTRANS_STATUS:
      {
        // returns ERROR, if no transaction has been started.
        // Otherwise returns SUCCESS and (optionally) returns
        // the transaction id.
        if (! currContext.getTransaction()->xnInProgress())
          {
	    // this is used internally for checking, diags area is not set
	    return (-CLI_TRANSACTION_NOT_STARTED);
          }
      }
    break;

    case SQLTRANS_QUIESCE:
      {
	if (currContext.getTransaction()->xnInProgress())
	  {
	    // go through each context that has matched transid, and
	    // release all transactional messages to ESPs,MXCMPs,MXUDR,and DP2.
	    ContextCli * cntxt;
	    cliGlobals->getContextList()->position();
	    while (cntxt = (ContextCli *)cliGlobals->getContextList()->getNext())
	      {
		if ( cntxt->getTransaction()->xnInProgress() && 
		     (currContext.getTransaction()->getExeXnId() == 
		      cntxt->getTransaction()->getExeXnId()) )
		  cntxt->releaseAllTransactionalRequests();
	      }
	  }
      }
    break;
    case SQLTRANS_ROLLBACK_IMPLICIT_XN:
      {
        if ((currContext.getTransaction()->xnInProgress()) &&
            (currContext.getTransaction()->exeStartedXn()) &&
            (currContext.getTransaction()->autoCommit()))
          {            
	    retcode = currContext.getTransaction()->rollbackTransactionWaited();
	    if (retcode)
	      {
		diags.mergeAfter(*(currContext.getTransaction()->getDiagsArea()));
		return -1;
	      }
          }
      }
      break;

    case SQLTRANS_COMMIT:
      {
	if ((currContext.getTransaction()->xnInProgress()) &&
	    (currContext.getTransaction()->exeStartedXn()))
	  {
	    retcode = currContext.getTransaction()->commitTransaction();

            if (retcode)
	      {
                diags.mergeAfter(*(currContext.getTransaction()->getDiagsArea()));
                return -1;
	      }
              
	  
	  }
      }
    break;

    case SQLTRANS_ROLLBACK:
      {
	if ((currContext.getTransaction()->xnInProgress()) &&
	    (currContext.getTransaction()->exeStartedXn()))
	  {
	    retcode= currContext.getTransaction()->rollbackTransaction();
            if (retcode)
	      {
                diags.mergeAfter(*(currContext.getTransaction()->getDiagsArea()));
                return -1;
              }
	  }
      }
    break;

    case SQLTRANS_BEGIN:
      {
	if (! (currContext.getTransaction()->xnInProgress()))
	  {
	    retcode = currContext.getTransaction()->beginTransaction();
            if (retcode)
	      {
		diags.mergeAfter(*(currContext.getTransaction()->getDiagsArea()));
		return -1;
	      }
	  }
      }
    break;

    case SQLTRANS_INHERIT:
      {
	currContext.getTransaction()->resetXnState();
	currContext.getTransaction()->inheritTransaction();
      }
    break;

    case SQLTRANS_SUSPEND:
      {
        currContext.getTransaction()->suspendTransaction();
      }
    break;

    case SQLTRANS_RESUME:
      {
        currContext.getTransaction()->resumeTransaction();
      }
    break;

    default:
      diags << DgSqlCode(-CLI_INVALID_SQLTRANS_COMMAND);
      return SQLCLI_ReturnCode(&currContext,diags.mainSQLCODE());
      
    } // switch command

  // return transid, if transid_descriptor is provided.
  if (transid_descriptor)
    {
      Descriptor * transid_desc =
	currContext.getDescriptor(transid_descriptor);

      // descriptor must exist 
      if (!transid_desc)
        {
          diags << DgSqlCode(-CLI_DESC_NOT_EXISTS);
          return SQLCLI_ReturnCode(&currContext,-CLI_DESC_NOT_EXISTS);
        }

      // return the transaction identifier in the
      // descriptor provided. Note that for commit/rollback
      // requests, this will return a -1 in the transid desc.
      Int64 * pTransid = 0; 
      retcode = transid_desc->getDescItem(1,
                                          SQLDESC_VAR_PTR,
                                          (Lng32*) &pTransid,
                                          NULL, 0, NULL, 0);
      if (isERROR(retcode))
        return SQLCLI_ReturnCode(&currContext,retcode);

      if (!pTransid)
        return -CLI_INTERNAL_ERROR;

      if (currContext.boundsCheckMemory(pTransid, sizeof(Int64)))
	{
	  return SQLCLI_ReturnCode(&currContext,
				   -CLI_USER_MEMORY_IN_EXECUTOR_SEGMENT);
	}
      else
	{
	  *pTransid = currContext.getTransaction()->getExeXnId();
	}
    }

  return SUCCESS;
}


#pragma page "SQLCLI_SetAuthID"
// *****************************************************************************
// *                                                                           *
// * Function: SQLCLI_SetAuthID                                                *
// *                                                                           *
// *    Sets user authentication values in CLI context.                        *
// *                                                                           *
// *****************************************************************************
// *                                                                           *
// *  Parameters:                                                              *
// *                                                                           *
// *  <cliGlobals>                    CliGlobals *                    In       *
// *    is a pointer to CLI globals.                                           *
// *                                                                           *
// *  <externalUsername>              const char *                    In       *
// *    is the external username of the user that was authenticated.           *
// *                                                                           *
// *  <databaseUsername>              const char *                    In       *
// *    is the database username of the user that was authenticated.           *
// *                                                                           *
// *  <authToken>                     const char *                    In       *
// *    is the token generated for this user session.                          *
// *                                                                           *
// *  <authTokenLen>                  Int32                           In       *
// *    is the length of the token in bytes.                                   *
// *                                                                           *
// *  <effectiveUserID>               Int32                           In       *
// *    is the user ID to use in authorization decisions.                      *
// *                                                                           *
// *  <sessionUserID>                 Int32                           In       *
// *    is the user ID to record for accountability.                           *
// *                                                                           *
// *****************************************************************************
Lng32 SQLCLI_SetAuthID(
   CliGlobals * cliGlobals,
   const char * externalUsername,
   const char * databaseUsername,
   const char * authToken,
   Int32        authTokenLen,
   Int32        effectiveUserID,
   Int32        sessionUserID)
   
{
  
  // create initial context, if first call, and add module, if any.
  Lng32 retcode = CliPrologue(cliGlobals,0);
  
  if (isERROR(retcode))
    return retcode;
  
  ContextCli   & currContext = *(cliGlobals->currContext());
  ComDiagsArea & diags       = currContext.diags();
//ACH can this be removed?  Seems to be an artifact of NSK priv boundary check  
  if (currContext.boundsCheckMemory((void *)externalUsername,str_len(externalUsername)))
    return SQLCLI_ReturnCode(&currContext,
                             -CLI_USER_MEMORY_IN_EXECUTOR_SEGMENT);
  
  // This method is a no-op on platforms other than Linux. Only on
  // Linux do we need to update the ContextCli instance.
  retcode = currContext.setAuthID(externalUsername,
                                  databaseUsername,
                                  authToken,
                                  authTokenLen,
                                  effectiveUserID,
                                  sessionUserID);
  
  return SQLCLI_ReturnCode(&currContext,retcode);
  
}
//************************** End of SQLCLI_SetAuthID ***************************

/* temporary functions -- for use by sqlcat simulator only */

Lng32 SQLCLI_AllocDescInt(/*IN*/    CliGlobals * cliGlobals,
			 /*INOUT*/ SQLDESC_ID * desc_id,
			 /*IN*/          Lng32   max_entries)
{
  Lng32 retcode;


  // create initial context, if first call, and add module, if any.
  retcode = CliPrologue(cliGlobals,desc_id->module);
  if (isERROR(retcode))
    return retcode;

  ContextCli   & currContext = *(cliGlobals->currContext());
  ComDiagsArea & diags       = currContext.diags();

  if (max_entries < 0)
    {
      diags << DgSqlCode(-CLI_DATA_OUTOFRANGE) << DgInt0(max_entries);
      return diags.mainSQLCODE();
    }

  /* allocate a new descriptor in the current context.         */
  /* return the descriptor handle in desc_id, if name mode     */
  /* is "desc_handle"                                          */
  retcode = currContext.allocateDesc(desc_id, max_entries);

  return SQLCLI_ReturnCode(&currContext,retcode);
}

Lng32 SQLCLI_GetDescEntryCountInt(/*IN*/  CliGlobals * cliGlobals,
				 /*IN*/  SQLDESC_ID * desc_id,
				 /*OUT*/       Lng32 * num_entries)
{
  if (!cliGlobals || !num_entries)
    {
      return (-CLI_NO_CURRENT_CONTEXT);
    }


  ContextCli   & currContext = *(cliGlobals->currContext());
  ComDiagsArea & diags       = currContext.diags();

  Descriptor * desc = currContext.getDescriptor(desc_id);

  /* descriptor must exist */
  if (!desc)
    {
      diags << DgSqlCode(-CLI_DESC_NOT_EXISTS);
      return SQLCLI_ReturnCode(&currContext,-CLI_DESC_NOT_EXISTS);
    }

  if (currContext.boundsCheckMemory(num_entries,sizeof(num_entries)))
    return SQLCLI_ReturnCode(&currContext,
			     -CLI_USER_MEMORY_IN_EXECUTOR_SEGMENT);

  *num_entries = desc->getUsedEntryCount();
  
  return SUCCESS;
}

Lng32 SQLCLI_GetDescItem(/*IN*/ CliGlobals * cliGlobals,
			/*IN*/      SQLDESC_ID * desc_id,
			/*IN*/            Lng32   entry,
			/* (SQLDESC_ITEM_ID) *IN*/ Lng32   what_to_get,
			/*OUT OPTIONAL*/  void   * numeric_value,
			/*OUT OPTIONAL*/  char * string_value,
			/*IN  OPTIONAL*/  Lng32   max_string_len,
			/*OUT OPTIONAL*/  Lng32 * len_of_item,
			/*IN  OPTIONAL*/  Lng32   start_from_offset)
{
  Lng32 retcode;


  // create initial context, if first call, and add module, if any.
  retcode = CliPrologue(cliGlobals,desc_id->module);
  if (isERROR(retcode))
    return retcode;

  ContextCli   & currContext = *(cliGlobals->currContext());
  ComDiagsArea & diags       = currContext.diags();

  Descriptor * desc = currContext.getDescriptor(desc_id);

  /* descriptor must exist */
  if (!desc)
    {
      diags << DgSqlCode(-CLI_DESC_NOT_EXISTS);
      return SQLCLI_ReturnCode(&currContext,-CLI_DESC_NOT_EXISTS);
    }

  if(numeric_value){
    if(currContext.boundsCheckMemory((void*)numeric_value,4))
      return SQLCLI_ReturnCode(&currContext,
			       -CLI_USER_MEMORY_IN_EXECUTOR_SEGMENT);
  }
  
  if(string_value){
    if(currContext.boundsCheckMemory((void*)string_value,max_string_len))
      return SQLCLI_ReturnCode(&currContext,
			       -CLI_USER_MEMORY_IN_EXECUTOR_SEGMENT);
  }
  retcode = desc->getDescItem(entry, what_to_get, 
                              numeric_value, string_value,
                              max_string_len, len_of_item,
                              start_from_offset);

  return SQLCLI_ReturnCode(&currContext,retcode);
}

Lng32 SQLCLI_SetDescEntryCountInt(/*IN*/ CliGlobals * cliGlobals,
				 /*IN*/ SQLDESC_ID * desc_id,
				 /*IN*/       Lng32   num_entries)
{
  Lng32 retcode;


  // create initial context, if first call, and add module, if any.
  retcode = CliPrologue(cliGlobals,desc_id->module);
  if (isERROR(retcode))
    return retcode;

  ContextCli   & currContext = *(cliGlobals->currContext());
  ComDiagsArea & diags       = currContext.diags();

  Descriptor * desc = currContext.getDescriptor(desc_id);

  /* descriptor must exist */
  if (!desc)
    {
      diags << DgSqlCode(-CLI_DESC_NOT_EXISTS);
      return SQLCLI_ReturnCode(&currContext,-CLI_DESC_NOT_EXISTS);
    }

  desc->setUsedEntryCount(num_entries);
  
  return SUCCESS;
}

Lng32 SQLCLI_SetDescItem(
     /*IN*/                     CliGlobals * cliGlobals,
     /*IN*/                     SQLDESC_ID * desc_id,
     /*IN*/                     Lng32   entry,
     /* (SQLDESC_ITEM_ID) *IN*/ Lng32   what_to_set,
     /*IN  OPTIONAL*/           Long   numeric_value,
     /*IN  OPTIONAL*/           char * string_value)
{
  Lng32 retcode;


  // create initial context, if first call, and add module, if any.
  retcode = CliPrologue(cliGlobals,desc_id->module);
  if (isERROR(retcode))
    return retcode;

  ContextCli   & currContext = *(cliGlobals->currContext());
  ComDiagsArea & diags       = currContext.diags();

  Descriptor * desc = currContext.getDescriptor(desc_id);

  /* descriptor must exist */
  if (!desc)
    {
      diags << DgSqlCode(-CLI_DESC_NOT_EXISTS);
      return SQLCLI_ReturnCode(&currContext,-CLI_DESC_NOT_EXISTS);
    }

  if (entry > desc->getMaxEntryCount())
    {
      diags << DgSqlCode(-CLI_INVALID_DESC_ENTRY);
      return diags.mainSQLCODE();
    }

  if (entry > desc->getUsedEntryCount())
    {
      retcode = desc->addEntry(entry);
      if (isERROR(retcode))
        {
          diags << DgSqlCode(-CLI_INTERNAL_ERROR);
          return SQLCLI_ReturnCode(&currContext,-CLI_INTERNAL_ERROR);
        }
    }

  Lng32 length = 0;

  if(what_to_set==SQLDESC_VAR_PTR){
    length=desc->getVarDataLength(entry);
    if(currContext.boundsCheckMemory((void*)numeric_value,length))
      return SQLCLI_ReturnCode(&currContext,
			       -CLI_USER_MEMORY_IN_EXECUTOR_SEGMENT);
  }
  if(what_to_set==SQLDESC_IND_PTR){
    length=desc->getIndLength(entry);
    if(currContext.boundsCheckMemory((void*)numeric_value,length))
      return SQLCLI_ReturnCode(&currContext,
			       -CLI_USER_MEMORY_IN_EXECUTOR_SEGMENT);
  }
  
  if(string_value){
    //get length from varchar
    length = desc->getVarDataLength(entry);
    if(currContext.boundsCheckMemory(string_value,length))
      return SQLCLI_ReturnCode(&currContext,
			       -CLI_USER_MEMORY_IN_EXECUTOR_SEGMENT);
  }

  retcode = desc->setDescItem(entry, what_to_set, numeric_value, string_value);
  if (isERROR(retcode))
    return SQLCLI_ReturnCode(&currContext, retcode);

  return SUCCESS;
}

// -----------------------------------------------------------------------
// NOTE: this procedure will go away, please use GetDiagnosticsStmtInfo()
// instead!!!
// -----------------------------------------------------------------------
Lng32 SQLCLI_GetRowsAffected(/*IN*/ CliGlobals * cliGlobals,
			    /*IN*/ SQLSTMT_ID * statement_id,
			           Int64 & rowsAffected)
{
  if (!cliGlobals)
      return -CLI_NO_CURRENT_CONTEXT;


  ContextCli   & currContext = *(cliGlobals->currContext());
  ComDiagsArea & diags       = currContext.diags();

  Statement * stmt = currContext.getStatement(statement_id);
 
  if (!stmt)
    {
      diags << DgSqlCode(-CLI_STMT_NOT_EXISTS);
      return SQLCLI_ReturnCode(&currContext,-CLI_STMT_NOT_EXISTS);
    }

  if(currContext.boundsCheckMemory(&rowsAffected,sizeof(rowsAffected)))
    return SQLCLI_ReturnCode(&currContext,
			     -CLI_USER_MEMORY_IN_EXECUTOR_SEGMENT);

  rowsAffected = stmt->getRowsAffected();
  
  return SUCCESS;
}
Lng32 SQLCLI_MergeDiagnostics(/*IN*/ CliGlobals * cliGlobals,
			     /*INOUT*/ ComDiagsArea & newDiags)
{
  if (&newDiags == NULL)
    return ERROR;

  if (!cliGlobals)
    return -CLI_NO_CURRENT_CONTEXT;


  ContextCli   & currContext = *(cliGlobals->currContext());
  ComDiagsArea & diags       = currContext.diags();

  newDiags.mergeAfter(cliGlobals->currContext()->diags());
  return SUCCESS;
}

// For internal use only -- do not document!
static Lng32 GetStatement_Internal(/*IN*/ CliGlobals * cliGlobals,
				  /*INOUT*/ Statement ** statement_ptr,
				  /*IN*/ SQLSTMT_ID * statement_id)
{
  Lng32 retcode;
  Long stmtHandle = (Long)statement_id->handle;

  NABoolean getnext  = ((((statement_id->name_mode != stmt_handle) && 
			  ((stmtHandle & 0x0001) != 0)))
			? TRUE : FALSE);
  NABoolean position = (((stmtHandle & 0x0002) != 0) ? TRUE : FALSE);
  NABoolean advance  = (((stmtHandle & 0x0004) != 0) ? TRUE : FALSE);

  ContextCli   & currContext = *(cliGlobals->currContext());
  ComDiagsArea & diags       = currContext.diags();
  
  if (statement_id->name_mode != stmt_handle)
    {
      NABoolean sequentialAdd = 
	(((stmtHandle & 0x0008) != 0) ? TRUE : FALSE);
      
      currContext.getStatementList()->setSequentialAdd(sequentialAdd);
    }

  Statement * stmt = NULL;

  if (getnext)
    stmt = currContext.getNextStatement(statement_id, position, advance);
  else
    stmt = currContext.getStatement(statement_id);

  /* stmt must exist */
  if (!stmt)
    {
      return SQL_EOF;
    }

  *statement_ptr = stmt;

  return SUCCESS;
}

//Function to get the length of the desc_items array
//returns the length if no error occurs, if error_occurred
//is 1 on return then return value indicates error
Lng32 GetDescItemsEntryCount(
                /*IN*/ CliGlobals * cliGlobals,
                /*IN*/ SQLDESC_ID * desc_id,
                /*IN*/ SQLDESC_ITEM desc_items[],
                /*IN*/ SQLDESC_ID * value_num_descriptor,
                /*IN*/ SQLDESC_ID * descriptor,
                /*Out*/Int32 & error_occurred)
{
  error_occurred = 0;
#if 0
  // sanity check
  if (!desc_id || !value_num_descriptor || !output_descriptor){
     error_occurred = 1;
     return -CLI_INTERNAL_ERROR;
  }
#endif

  Lng32 retcode;


  // create initial context, if first call, and add module, if any.
  retcode = CliPrologue(cliGlobals,desc_id->module);

  if (isERROR(retcode)){
     error_occurred = 1;
     return -CLI_INTERNAL_ERROR;
  }

  ContextCli   & currContext = *(cliGlobals->currContext());
  ComDiagsArea & diags       = currContext.diags();

  Descriptor *desc = currContext.getDescriptor(descriptor);

  /* descriptor must exist */
  if (!desc)
    {
      error_occurred = 1;
      diags << DgSqlCode(-CLI_DESC_NOT_EXISTS);
      return SQLCLI_ReturnCode(&currContext,-CLI_DESC_NOT_EXISTS);
    }

  Lng32 UsedEntryCount = desc->getUsedEntryCount();
  return UsedEntryCount;
}

// For internal use only -- do not document!
Lng32 SQLCLI_GetRootTdb_Internal(/*IN*/ CliGlobals * cliGlobals,
				/*INOUT*/ char * roottdb_ptr,
                                /*IN*/ Int32 roottdb_len,
				/*INOUT*/ char * srcstr_ptr,
                                /*IN*/ Int32 srcstr_len,
				/*IN*/ SQLSTMT_ID * statement_id)
{
  Lng32 retcode;

  Statement *statement;

  retcode = GetStatement_Internal(cliGlobals,
				  &statement, statement_id);

  if (retcode)
    return retcode;

  if (!statement)       // statement must exists
    return -1;

  ex_root_tdb *exRootTdb = statement->getRootTdb();
  Lng32 rootTdbSize = statement->getRootTdbSize();
  ex_assert(rootTdbSize <= roottdb_len, "Insufficient space for root TDB");
  memcpy(roottdb_ptr, exRootTdb, rootTdbSize);

  if (srcstr_ptr)
    {
      char *srcStr = statement->getSrcStr();
      Lng32 srcStrSize = statement->getSrcStrSize();
      ex_assert(srcStrSize <= srcstr_len, "Insufficient space for source");
      memcpy(srcstr_ptr, srcStr, srcStrSize);
    }

  return retcode;
}

// For internal use only -- do not document!
Lng32 SQLCLI_GetRootTdbSize_Internal(/*IN*/ CliGlobals * cliGlobals,
				    /*INOUT*/ Lng32* roottdb_size,
				    /*INOUT*/ Lng32* srcstr_size,
				    /*IN*/ SQLSTMT_ID * statement_id)
{
  Lng32 retcode;
  Statement *statement;

  retcode = GetStatement_Internal(cliGlobals,
				  &statement, statement_id);

  if (retcode)
    return retcode;

  if (!statement)       // statement must exists
    return -1;

  *roottdb_size = statement->getRootTdbSize();
  *srcstr_size  = statement->getSrcStrSize();
  
  return retcode;
}

// For internal use only -- do not document!
Lng32 SQLCLI_GetCollectStatsType_Internal(/*IN*/ CliGlobals * cliGlobals,
					 /*OUT*/ ULng32 * collectStatsType,
					 /*IN*/ SQLSTMT_ID * statement_id)
{
  Lng32 retcode = 0;
  Statement *statement;

  ContextCli   & currContext = *(cliGlobals->currContext());
  ComDiagsArea & diags       = currContext.diags();
  
  if (statement_id)       
  {
    statement = currContext.getStatement(statement_id);
     
    if ((!statement) || (!statement->getRootTdb()))
      *collectStatsType = (ULng32)ComTdb::NO_STATS;
    else
       *collectStatsType = 
	 (ULng32)((ComTdb*)statement->getRootTdb())->getCollectStatsType();
  }
  else
  {
    if (currContext.getStats())
        *collectStatsType = (ULng32)currContext.getStats()->getCollectStatsType();
    else
      *collectStatsType = (ULng32)ComTdb::NO_STATS;
  }

  return retcode;
}

// For internal use only -- do not document!
Lng32 SQLCLI_GetTotalTcbSpace(/*IN*/ CliGlobals * cliGlobals,
				/*IN*/ char * tdb,
				/*IN*/ char * otherInfo)
{
  Lng32 retcode;


  ContextCli   & currContext = *(cliGlobals->currContext());
  ComDiagsArea & diags       = currContext.diags();

  retcode = getTotalTcbSpace(tdb, otherInfo, 
			     (char*)cliGlobals->getExecutorMemory());

  return retcode;
}

Lng32 SQLCLI_SetParserFlagsForExSqlComp_Internal(
     /*IN*/ CliGlobals * cliGlobals,
     /*IN*/ULng32 flagbits)
{
  if (cliGlobals->currContext())
    cliGlobals->currContext()->setSqlParserFlags(flagbits);
  return 0;
}

Lng32 SQLCLI_ResetParserFlagsForExSqlComp_Internal(
     /*IN*/ CliGlobals * cliGlobals,
     /*IN*/ULng32 flagbits)
{
  if (cliGlobals->currContext())
    cliGlobals->currContext()->resetSqlParserFlags(flagbits);
  return 0;
}

Lng32 SQLCLI_AssignParserFlagsForExSqlComp_Internal(
     /*IN*/ CliGlobals * cliGlobals,
     /*IN*/ULng32 flagbits)
{
  if (cliGlobals->currContext())
    cliGlobals->currContext()->assignSqlParserFlags(flagbits);
  return 0;
}

Lng32 SQLCLI_GetParserFlagsForExSqlComp_Internal(
     /*IN*/ CliGlobals * cliGlobals,
     /*IN*/ULng32 &flagbits)
{
  flagbits = 0;
  if (cliGlobals->currContext())
    flagbits = cliGlobals->currContext()->getSqlParserFlags();
  return 0;
}

Lng32 SQLCLI_OutputValueIntoNumericHostvar(
                /*IN*/ CliGlobals * cliGlobals,
                /*IN*/ SQLDESC_ID * output_descriptor,
		/*IN*/       Lng32   desc_entry,
		/*IN*/       Lng32   value)
{


  // go ahead...
  // create initial context, if first call, and add module, if any.
  Lng32 retcode = CliPrologue(cliGlobals,output_descriptor->module);
  if (isERROR(retcode))
    return retcode;
  ContextCli   & currContext = *(cliGlobals->currContext());
  ComDiagsArea & diags       = currContext.diags();

  Descriptor * output_desc = currContext.getDescriptor(output_descriptor);

  if (!output_desc)
    {
      return -CLI_DESC_NOT_EXISTS;
    }

  retcode = OutputValueIntoNumericHostvar(output_desc, desc_entry, value);

  return retcode;
}

Lng32 SQLCLI_SetEnviron_Internal(/*IN*/ CliGlobals * cliGlobals,
				char ** envvars, Lng32 propagate)
{
  Lng32 retcode = 0;

  ContextCli   & currContext = *(cliGlobals->currContext());
  ComDiagsArea & diags       = currContext.diags();

  retcode = cliGlobals->setEnvVars(envvars);
  if (retcode)
    return SQLCLI_ReturnCode(&currContext,retcode);

  return 0;


}

Lng32 SQLCLI_SetErrorCodeInRTS(
      CliGlobals *cliGlobals,
      SQLSTMT_ID * statement_id,
      Lng32     sqlErrorCode)
{

  Lng32 retcode = 0;

  // create initial context, if first call, and add module, if any.
  retcode = CliPrologue(cliGlobals,statement_id->module);
  if (isERROR(retcode))
    return retcode;

  ContextCli   & currContext = *(cliGlobals->currContext());
  ComDiagsArea & diags       = currContext.diags();
  /* prepare the statement */
  Statement * stmt = currContext.getStatement(statement_id);

  /* stmt must exist */
  if (stmt)
  {
    StmtStats *stmtStats = stmt->getStmtStats();
    if (stmtStats != NULL && stmtStats->getMasterStats() != NULL)
    {
      if (diags.mainSQLCODE() < 0)
      {
        Int64 exeEndTime = NA_JulianTimestamp();
        stmtStats->getMasterStats()->setExeEndTime(exeEndTime);
        stmtStats->getMasterStats()->setElapsedEndTime(exeEndTime);
      }
      stmtStats->getMasterStats()->setSqlErrorCode(diags.mainSQLCODE() != 0 ? 
           diags.mainSQLCODE() : sqlErrorCode); 
    }
  }
  else
    retcode = -CLI_STMT_NOT_EXISTS;
  return retcode;
}

Lng32 SQLCLI_LocaleToUTF8 (
		    CliGlobals *cliGlobals,
                    Int32 conv_charset,
                    void * Input_Buffer_Addr,
                    Int32 Input_Buffer_Length,
                    void * Output_Buffer_Addr,
                    Int32 Output_Buffer_Length,
                    void ** First_Untranslated_Char_Addr,
                    Int32 *Output_Data_Length,
                    Int32 add_null_at_end_Flag,
                    Int32 *num_translated_char)
{

  short error = 0;

  ContextCli   & currContext = *(cliGlobals->currContext());
  char * &firstUntranslatedChar = (char * &)First_Untranslated_Char_Addr; 

  // Bounds check the input buffer
  if (currContext.boundsCheckMemory((void *)Input_Buffer_Addr, 
                                    Input_Buffer_Length))
     return FEBOUNDSERR;

  // Bounds check the output buffer
  if (currContext.boundsCheckMemory((void *)Output_Buffer_Addr, 
                                    Output_Buffer_Length))
     return FEBOUNDSERR;


  error = LocaleToUTF8( cnv_version1, 
                        (char *)Input_Buffer_Addr,
                        Input_Buffer_Length,
                        (char *)Output_Buffer_Addr,
                        Output_Buffer_Length,
                        (cnv_charset)conv_charset,
                        firstUntranslatedChar, 
                        (UInt32 *)Output_Data_Length,
                        add_null_at_end_Flag,
                        (UInt32 *)num_translated_char
                      );
  return error;
}

Lng32 SQLCLI_LocaleToUTF16 (
                    CliGlobals *cliGlobals,
                    Int32 conv_charset,
                    void * Input_Buffer_Addr,
                    Int32 Input_Buffer_Length,
                    void * Output_Buffer_Addr,
                    Int32 Output_Buffer_Length,
                    void ** First_Untranslated_Char_Addr,
                    Int32 *Output_Data_Length,
                    Int32 conv_flags,
                    Int32 add_null_at_end_Flag,
                    Int32 *num_translated_char)
{
  short error = 0;

  ContextCli   & currContext = *(cliGlobals->currContext());
  char * &firstUntranslatedChar = (char * &)First_Untranslated_Char_Addr; 

  // Bounds check the input buffer
  if (currContext.boundsCheckMemory((void *)Input_Buffer_Addr, 
                                    Input_Buffer_Length))
     return FEBOUNDSERR;

  // Bounds check the output buffer
  if (currContext.boundsCheckMemory((void *)Output_Buffer_Addr, 
                                    Output_Buffer_Length))
     return FEBOUNDSERR;


  error = LocaleToUTF16(cnv_version1, 
                        (char *)Input_Buffer_Addr,
                        Input_Buffer_Length,
                        (char *)Output_Buffer_Addr,
                        Output_Buffer_Length,
                        (cnv_charset)conv_charset,
                        firstUntranslatedChar, 
                        (UInt32 *)Output_Data_Length,
                        conv_flags,
                        add_null_at_end_Flag,
                        (UInt32 *)num_translated_char
                      );

  return error;
}

Lng32 SQLCLI_UTF8ToLocale(
                    CliGlobals *cliGlobals,
                    Int32 conv_charset,
                    void * Input_Buffer_Addr,
                    Int32 Input_Buffer_Length,
                    void * Output_Buffer_Addr,
                    Int32 Output_Buffer_Length,
                    void ** First_Untranslated_Char_Addr,
                    Int32 *Output_Data_Length,
                    Int32 add_null_at_end_Flag,
                    Int32 allow_invalids,
                    Int32 *num_translated_char,
                    void * substitution_char_addr)
{
  short error = 0;

  ContextCli   & currContext = *(cliGlobals->currContext());
  char * &firstUntranslatedChar = (char * &)First_Untranslated_Char_Addr; 
  const char *substitutionChar = (const char *)substitution_char_addr;

  // Bounds check the input buffer
  if (currContext.boundsCheckMemory((void *)Input_Buffer_Addr, 
                                    Input_Buffer_Length))
     return FEBOUNDSERR;

  // Bounds check the output buffer
  if (currContext.boundsCheckMemory((void *)Output_Buffer_Addr, 
                                    Output_Buffer_Length))
     return FEBOUNDSERR;


  error = UTF8ToLocale ( cnv_version1, 
                        (char *)Input_Buffer_Addr,
                        Input_Buffer_Length,
                        (char *)Output_Buffer_Addr,
                        Output_Buffer_Length,
                        (cnv_charset)conv_charset,
                        firstUntranslatedChar, 
                        (UInt32 *)Output_Data_Length,
                        add_null_at_end_Flag,
                        allow_invalids,
                        (UInt32 *)num_translated_char,
                        substitutionChar
                      );

  return error;
}

Lng32 SQLCLI_UTF16ToLocale (
                    CliGlobals *cliGlobals,
                    Int32 conv_charset,
                    void * Input_Buffer_Addr,
                    Int32 Input_Buffer_Length,
                    void * Output_Buffer_Addr,
                    Int32 Output_Buffer_Length,
                    void ** First_Untranslated_Char_Addr,
                    Int32 *Output_Data_Length,
                    Int32 conv_flags,
                    Int32 add_null_at_end_Flag,
                    Int32 allow_invalids,
                    Int32 *num_translated_char,
                    void * substitution_char_addr)
{
  short error = 0;

  ContextCli   & currContext = *(cliGlobals->currContext());
  char * &firstUntranslatedChar = (char * &)First_Untranslated_Char_Addr;
  const char *substitutionChar = (const char *)substitution_char_addr; 

  // Bounds check the input buffer
  if (currContext.boundsCheckMemory((void *)Input_Buffer_Addr, 
                                    Input_Buffer_Length))
     return FEBOUNDSERR;

  // Bounds check the output buffer
  if (currContext.boundsCheckMemory((void *)Output_Buffer_Addr, 
                                    Output_Buffer_Length))
     return FEBOUNDSERR;


  error = UTF16ToLocale( cnv_version1, 
                        (char *)Input_Buffer_Addr,
                        Input_Buffer_Length,
                        (char *)Output_Buffer_Addr,
                        Output_Buffer_Length,
                        (cnv_charset)conv_charset,
                        firstUntranslatedChar, 
                        (UInt32 *)Output_Data_Length,
                        conv_flags,
                        add_null_at_end_Flag,
                        allow_invalids,
                        (UInt32 *)num_translated_char,
                        substitutionChar
                      );

  return error;
}

Lng32 SQLCLI_SetSecInvalidKeys(CliGlobals *cliGlobals,
           /* IN */    Int32 numSiKeys,
           /* IN */    SQL_QIKEY siKeys[])
{
  return cliGlobals->currContext()->setSecInvalidKeys(numSiKeys, siKeys);
}

Lng32 SQLCLI_GetSecInvalidKeys(CliGlobals *cliGlobals,
            /* IN */      Int64 prevTimestamp,
            /* IN/OUT */  SQL_QIKEY siKeys[],
            /* IN */      Int32 maxNumSiKeys,
            /* IN/OUT */  Int32 *returnedNumSiKeys,
            /* IN/OUT */  Int64 *maxTimestamp)
{
  Lng32 retcode = 0;
  *returnedNumSiKeys = 0;

  StatsGlobals *statsGlobals = cliGlobals->getStatsGlobals();
  if (statsGlobals)
  {
    Int64 newestSik = statsGlobals->getNewestRevokeTimestamp();
    Int64 newMaxTimestamp = NA_JulianTimestamp();

    if (prevTimestamp < newestSik)
      retcode = cliGlobals->getStatsGlobals()->getSecInvalidKeys(
                          cliGlobals,
                          prevTimestamp,
                          siKeys,
                          maxNumSiKeys,
                          returnedNumSiKeys);
    if (retcode == 0)
      *maxTimestamp = newMaxTimestamp;
  }
  else
  {
    // This could happens as the instance starts -- some compilers could 
    // call this CLI before the RMS shared segment is ready.  It 
    // definitely happens when the init_sql createsysmdf step is 
    // executed, because at that time the compiler is compiling 
    // without having the instance up.  This is too early for a 
    // revoke, so we handle the scenario by returning success, but 
    // leave the maxTimestamp to the same value as the prevTimestamp,
    // so that the compiler will continue asking for SQL_QIKEYs each 
    // time it compiles a query, until the RMS shared segment is 
    // ready.
    *maxTimestamp = prevTimestamp; 
  }

  return retcode;
}

Lng32 SQLCLI_SetLobLock(CliGlobals *cliGlobals,
                        /* IN */    char *lobLockId
                        )
{
  return cliGlobals->currContext()->setLobLock(lobLockId);
}
Lng32 SQLCLI_CheckLobLock(CliGlobals *cliGlobals,
                        /* IN */    char *lobLockId,
                        /*OUT */ NABoolean *found
                        )
{  
  Int32 retcode = 0;
  retcode = cliGlobals->currContext()->checkLobLock(lobLockId, found);
  return retcode;
}
Lng32 SQLCLI_GetStatistics2(CliGlobals *cliGlobals,
            /* IN */  	short statsReqType,
	    /* IN */  	char *statsReqStr,
	    /* IN */  	Lng32 statsReqStrLen,
	    /* IN */	short activeQueryNum,
	    /* IN */ 	short statsMergeType,
	    /* OUT */ 	short *statsCollectType,
	    /* IN/OUT */ SQLSTATS_DESC sqlstats_desc[],
	    /* IN */ 	Lng32 max_stats_desc,
	    /* OUT */	Lng32 *no_returned_stats_desc)
{
  Lng32 retcode;
  
  ContextCli   *currContext = cliGlobals->currContext();
  retcode = currContext->GetStatistics2(statsReqType,
                              statsReqStr,
                              statsReqStrLen,
                              activeQueryNum,
                              statsMergeType,
                              statsCollectType,
                              sqlstats_desc,
                              max_stats_desc,
                              no_returned_stats_desc);

  return retcode;
}

Lng32 SQLCLI_GetStatisticsItems(CliGlobals *cliGlobals,
            /* IN */  	short statsReqType,
	    /* IN */  	char *queryId,
	    /* IN */  	Lng32 queryIdLen,
            /* IN */	Lng32 no_of_stats_items,
	    /* IN/OUT */ SQLSTATS_ITEM sqlStats_items[])
{
  Lng32 retcode;
  

  ContextCli   *currContext = cliGlobals->currContext();
  ComDiagsArea & diags       = currContext->diags();

  ExStatisticsArea *mergedStats = currContext->getMergedStats();
  ExMasterStats *masterStats;
  if (mergedStats == NULL)
  {
    diags << DgSqlCode(-CLI_MERGED_STATS_NOT_AVAILABLE);
    return SQLCLI_ReturnCode(currContext,-CLI_MERGED_STATS_NOT_AVAILABLE);
  }
  if (statsReqType == SQLCLI_STATS_REQ_QID)
  {
    masterStats = mergedStats->getMasterStats();
    if (masterStats != NULL && queryId != NULL)
    {
      if (queryIdLen != masterStats->getQueryIdLen() || 
          str_cmp(masterStats->getQueryId(), queryId, masterStats->getQueryIdLen()) != 0)
      {
        diags << DgSqlCode(-CLI_QID_NOT_MATCHING);
        return SQLCLI_ReturnCode(currContext,-CLI_QID_NOT_MATCHING);
      }
    }
  }
  retcode = mergedStats->getStatsItems(no_of_stats_items, sqlStats_items);
  return retcode;
}
Lng32 SQLCLI_RegisterQuery(CliGlobals *cliGlobals,
                      SQLQUERY_ID *queryId,
                      Lng32 fragId,
                      Lng32 tdbId,
                      Lng32 explainTdbId,
                      short collectStatsType,
                      Lng32 instNum,
                      Lng32 tdbType,
                      char *tdbName,
                      Lng32 tdbNameLen)
{
  

  ContextCli   *currContext = cliGlobals->currContext();
  ComDiagsArea & diags       = currContext->diags();
  Lng32 retcode = SUCCESS;
  StatsGlobals *statsGlobals = cliGlobals->getStatsGlobals();
  if (statsGlobals == NULL)
    return retcode;
  int error;
  error = statsGlobals->getStatsSemaphore(cliGlobals->getSemId(),
                 cliGlobals->myPin());
  retcode = statsGlobals->registerQuery(diags, cliGlobals->myPin(), queryId, 
                            fragId, tdbId, explainTdbId, collectStatsType, instNum, 
                            (ComTdb::ex_node_type)tdbType,
                            tdbName, tdbNameLen);
  statsGlobals->releaseStatsSemaphore(cliGlobals->getSemId(),
            cliGlobals->myPin());
  return retcode;

} 

Lng32 SQLCLI_DeregisterQuery(CliGlobals *cliGlobals,
                      SQLQUERY_ID  *queryId,
                      Lng32 fragId)
{
  

  ContextCli   *currContext = cliGlobals->currContext();
  ComDiagsArea & diags       = currContext->diags();
  Lng32 retcode = SUCCESS;
  StatsGlobals *statsGlobals = cliGlobals->getStatsGlobals();
  if (statsGlobals == NULL)
    return retcode;
  int error;
  error = statsGlobals->getStatsSemaphore(cliGlobals->getSemId(),
                 cliGlobals->myPin());
  retcode = statsGlobals->deregisterQuery(diags, cliGlobals->myPin(), queryId,
                            fragId);
  statsGlobals->releaseStatsSemaphore(cliGlobals->getSemId(),
            cliGlobals->myPin());
  return retcode;
}


// This method returns the pointer to the CLI ExStatistics area.
// The returned pointer is a read only pointer, its contents cannot be
// modified by the caller.
Lng32 SQLCLI_GetStatisticsArea_Internal 
(
 /* IN */    CliGlobals *cliGlobals, 
 /* IN */    short statsReqType,
 /* IN */    char *statsReqStr,
 /* IN */    Lng32 statsReqStrLen,
 /* IN */    short activeQueryNum,
 /* IN */    short statsMergeType,
 /*INOUT*/   const ExStatisticsArea* &exStatsArea)
{
  ContextCli   *currContext = cliGlobals->currContext();
  ComDiagsArea & diagsArea  = currContext->diags();
  Lng32 retcode = SUCCESS;

  short retryAttempts = 0;

  exStatsArea = currContext->getMergedStats
    (statsReqType,
     statsReqStr,
     statsReqStrLen,
     activeQueryNum,
     statsMergeType,
     retryAttempts);

  if (exStatsArea == NULL)
    {
      if (diagsArea.getNumber(DgSqlCode::ERROR_) > 0)    
	return diagsArea.mainSQLCODE();
      else if (statsReqType == SQLCLI_STATS_REQ_QID)
	{
	  (diagsArea) << DgSqlCode(-EXE_RTS_QID_NOT_FOUND) << DgString0(statsReqStr);
	  return diagsArea.mainSQLCODE();
	}
      else
	{
	  (diagsArea) << DgSqlCode(-CLI_MERGED_STATS_NOT_AVAILABLE);
	  return -CLI_MERGED_STATS_NOT_AVAILABLE;
	}
    }
  else
    {
       currContext->setMergedStats((ExStatisticsArea *) exStatsArea);
       // temporary assert to see if I can catch this statsArea in
       // the shared segment. 
       long statsAddr = (long) exStatsArea;
       if ((statsAddr > 0x10000000)  && (statsAddr < 0x14000000))
         ex_assert(0, "ExStatisticsArea in shared seg, need a sema4.");
    }
  
  return retcode;
}


Lng32 SQLCLI_GetChildQueryInfo(CliGlobals *cliGlobals,
     SQLSTMT_ID * statement_id,
     char * uniqueQueryId,
     Lng32 uniqueQueryIdMaxLen,
     Lng32 * uniqueQueryIdLen,
     SQL_QUERY_COST_INFO *query_cost_info,
     SQL_QUERY_COMPILER_STATS_INFO *comp_stats_info)
{

  Lng32 retcode = 0;

  ContextCli   & currContext = *(cliGlobals->currContext());
  ComDiagsArea & diags       = currContext.diags();
  /* prepare the statement */
  Statement * stmt = currContext.getStatement(statement_id);
  if (!stmt)
  {
    diags << DgSqlCode(-CLI_STMT_NOT_EXISTS);
    return SQLCLI_ReturnCode(&currContext,-CLI_STMT_NOT_EXISTS);
  }
  retcode = stmt->getChildQueryInfo(diags, uniqueQueryId,
                    uniqueQueryIdMaxLen, uniqueQueryIdLen,
                    query_cost_info, comp_stats_info);

  return retcode;
}

Lng32 SQLCLI_LOBcliInterface
(
 /*IN*/     CliGlobals *cliGlobals,
 /*IN*/     char * inLobHandle,
 /*IN*/     Lng32  inLobHandleLen,
 /*IN*/     char * blackBox,
 /*INOUT*/  Int32 *blackBoxLen,
 /*OUT*/    char * outLobHandle,
 /*OUT*/    Lng32 * outLobHandleLen,
 /*IN*/     LOBcliQueryType qType,
 /*IN*/     LOBcliQueryPhase qPhase,
 /*INOUT*/  Int64 * dataOffset, /* IN: for insert, 
                                   OUT: for select */
 /*INOUT*/  Int64 * dataLen,    /* length of data.
                                   IN: for insert, out: for select */
 /*INOUT*/    Int64 * inoutDescPartnKey,  /* returned after insert and select 
                                                                             
 /*INOUT*/    Int64 * inoutDescSyskey,    /* returned after insert and select                                                                                 
 /*INOUT*/  void* *inCliInterface,
 /*IN*/     Int64 xnId,          /* xn id of the parent process, if non-zero */
 /*IN*/     NABoolean lobTrace
 )
{
  ContextCli   & currContext = *(cliGlobals->currContext());
  ComDiagsArea & diags       = currContext.diags();

  ComDiagsArea * myDiags = NULL;

  ExeCliInterface *cliInterface = NULL;
  if (inCliInterface && (*inCliInterface))
    {
      cliInterface = (ExeCliInterface*)(*inCliInterface);
    }
  else
    {
      cliInterface = new (currContext.exHeap()) 
	ExeCliInterface(currContext.exHeap(),
			SQLCHARSETCODE_UTF8,
			&currContext,
			NULL);
    }

  Int16 flags = 0;
  Lng32 lobType = 1;
  Lng32 lobNum = 0;
  Int64 uid = 0;
  Int64 inDescSyskey, descPartnKey;
  short schNameLen = 0;
  char schName[512];
  char logBuf[4096];
  Int64 inputValues[5];
  Lng32 inputValuesLen = 0;
  Int64 rowsAffected = 0;

  lobDebugInfo("In LobCliInterface",0,__LINE__,lobTrace);
  if (inLobHandle)
    {
      ExpLOBoper::extractFromLOBhandle(&flags, &lobType, &lobNum, &uid,  
				       &inDescSyskey, &descPartnKey,
				       &schNameLen, schName,
				       inLobHandle);
      str_sprintf(logBuf,"Handle contents : flags %d, lobType %d, lobNum :%d, uid : %ld, descSyskey: %ld, descPartnKey : %ld, schNameLen:%d, schName %s", flags,lobType,lobNum,uid,inDescSyskey,descPartnKey,schNameLen,schName);
       lobDebugInfo(logBuf,0,__LINE__,lobTrace);
    }

  
  char tgtLobNameBuf[100];
  char * tgtLobName = 
    ExpLOBoper::ExpGetLOBname(uid, lobNum, tgtLobNameBuf, 100);
  str_sprintf(logBuf,"lobName %s", tgtLobName);
  lobDebugInfo(logBuf,0,__LINE__,lobTrace);
  char lobDescHandleNameBuf[1024];
  Lng32 lobDescHandleNameLen = 1024;
  char * lobDescHandleName = 
    ExpLOBoper::ExpGetLOBDescHandleName(schNameLen, schName, uid, lobNum,
					lobDescHandleNameBuf, lobDescHandleNameLen);
  str_sprintf(logBuf,"lobDescHandleName %s", lobDescHandleName);
  lobDebugInfo(logBuf,0,__LINE__,lobTrace);
  char lobDescChunksNameBuf[1024];
  Lng32 lobDescChunksNameLen = 1024;
  char * lobDescChunksName = 
    ExpLOBoper::ExpGetLOBDescChunksName(schNameLen, schName, uid, lobNum,
					lobDescChunksNameBuf, lobDescChunksNameLen);
  
  str_sprintf(logBuf,"lobDescChunksName %s", lobDescChunksName);
  lobDebugInfo(logBuf,0,__LINE__,lobTrace);

  char * query = new(currContext.exHeap()) char[4096];
  char stmtName[200];
  if (outLobHandleLen)
    *outLobHandleLen = 0;

  if (blackBoxLen)
    {
      if ((qType == LOB_CLI_CREATE) ||
	  (qType == LOB_CLI_DROP) ||
	  (qType == LOB_CLI_INIT))
	*blackBoxLen = 0;
      else if ((qType == LOB_CLI_SELECT_UNIQUE) ||
	       (qType == LOB_CLI_SELECT_OPEN) ||
	       (qType == LOB_CLI_SELECT_FETCH) ||
	       (qType == LOB_CLI_SELECT_CLOSE))
	*blackBoxLen = 0;
    }

  Lng32 cliRC = 0;

  NABoolean xnAutoCommit = FALSE;
  NABoolean xnJoined = FALSE;

  Int64 transId;
  cliRC = GETTRANSID((short *)&transId);

  if ((xnId != 0) &&  // xnid passed in
      (cliRC == 0))   // and global xn present
    {
      // inherit it
      SQL_EXEC_Xact(SQLTRANS_INHERIT, NULL);
      } 

 
  switch (qType)
    {
    case LOB_CLI_INIT:
      {
	strcpy(query, "set transaction autocommit on;");
	cliRC = cliInterface->executeImmediate(query);
        if (cliRC < 0)
          goto error_return;
        
	cliRC = 0;
      }
      break;

    case LOB_CLI_CREATE:
      {
	

	// create lob descriptor handle table salted	
   	str_sprintf(query, "create ghost table %s (descPartnKey largeint not null, numChunks int not null, lobLen largeint not null) salt using 8 partitions store by (descPartnKey, syskey) ",
		    lobDescHandleName);
	
        lobDebugInfo(query,0,__LINE__,lobTrace);
	currContext.setSqlParserFlags(0x1);
	
	cliRC = cliInterface->executeImmediate(query);

	currContext.resetSqlParserFlags(0x1);

	if (cliRC < 0)
	    goto error_return;

           	// create lob descriptor chunks table salted
       	str_sprintf(query, "create ghost table %s (descPartnKey largeint not null, descSysKey largeint not null, chunkNum int not null, chunkLen largeint not null, dataOffset largeint, stringParam varchar(400), primary key(descPartnKey, descSysKey, chunkNum)) salt using 8 partitions",
	lobDescChunksName); 
        lobDebugInfo(query,0,__LINE__,lobTrace);

	// set parserflags to allow ghost table
	currContext.setSqlParserFlags(0x1);
	
	cliRC = cliInterface->executeImmediate(query);

	currContext.resetSqlParserFlags(0x1);

	if (cliRC < 0)
	    goto error_return;
	cliRC = 0;
      }
      break;

    case LOB_CLI_DROP:
      {
	str_sprintf(query, "drop ghost table %s",
		    lobDescHandleName);
        lobDebugInfo(query,0,__LINE__,lobTrace);
	// set parserflags to allow ghost table
	currContext.setSqlParserFlags(0x1);
	
	cliRC = cliInterface->executeImmediate(query);

	currContext.resetSqlParserFlags(0x1);
	
	if (cliRC < 0)
	    goto error_return;

	str_sprintf(query, "drop ghost table %s",
		    lobDescChunksName);
        lobDebugInfo(query,0,__LINE__,lobTrace);
	// set parserflags to allow ghost table
	currContext.setSqlParserFlags(0x1);
	
	cliRC = cliInterface->executeImmediate(query);

	currContext.resetSqlParserFlags(0x1);

	
	if (cliRC < 0)
	    goto error_return;
	cliRC = 0;
      }
      break;

    case LOB_CLI_CLEANUP:
      {
	str_sprintf(query, "cleanup table %s",
		    lobDescHandleName);
        lobDebugInfo(query,0,__LINE__,lobTrace);
	// set parserflags to allow ghost table
	currContext.setSqlParserFlags(0x1);
	
	cliRC = cliInterface->executeImmediate(query);

	currContext.resetSqlParserFlags(0x1);

	if (cliRC < 0)
	    goto error_return;

	str_sprintf(query, "cleanup table %s",
		    lobDescChunksName);
        lobDebugInfo(query,0,__LINE__,lobTrace);
	// set parserflags to allow ghost table
	currContext.setSqlParserFlags(0x1);
	
	cliRC = cliInterface->executeImmediate(query);

	currContext.resetSqlParserFlags(0x1);
	
	if (cliRC < 0)
	    goto error_return;
	cliRC = 0;
      }
      break;

    case LOB_CLI_INSERT:
      {
	// insert into lob descriptor handle table
        str_sprintf(query, "select syskey from (insert into table(ghost table %s) values (%ld, 1, %ld)) x",
                    lobDescHandleName, descPartnKey, (dataLen ? *dataLen : 0));
                
		   
        lobDebugInfo(query,0,__LINE__,lobTrace);
	// set parserflags to allow ghost table
	currContext.setSqlParserFlags(0x1);
	
        Int64 descSyskey = 0;
	Lng32 len = 0;
     
        cliRC = cliInterface->executeImmediate(query,
					       (char*)&descSyskey, &len, FALSE);
        if (cliRC < 0)
          goto error_return;
	currContext.resetSqlParserFlags(0x1);

	if (cliRC < 0)
	    goto error_return;

        
        // insert into lob descriptor chunks table
        if (blackBox && (blackBoxLen && (*blackBoxLen > 0)))
          {
            //blackBox points to external file name
            str_sprintf(query, "insert into table(ghost table %s) values (%ld, %ld, 1, %ld, %ld, '%s')",
                        lobDescChunksName, descPartnKey, descSyskey,
                        (dataLen ? *dataLen : 0),
                        (dataOffset ? *dataOffset : 0),
                        blackBox);
            lobDebugInfo(query,0,__LINE__,lobTrace);
          }
        else
          {
            str_sprintf(query, "insert into table(ghost table %s) values (%ld, %ld, 1, %ld, %ld, NULL)",
                        lobDescChunksName, descPartnKey, descSyskey,
                        (dataLen ? *dataLen : 0),
                        (dataOffset ? *dataOffset : 0));
            lobDebugInfo(query,0,__LINE__,lobTrace);
          }

        // set parserflags to allow ghost table
        currContext.setSqlParserFlags(0x1);
	
        cliRC = cliInterface->executeImmediate(query);

        currContext.resetSqlParserFlags(0x1);

        if (cliRC < 0)
	    goto error_return;
        
	if (inoutDescPartnKey)
	  *inoutDescPartnKey = descPartnKey;

	if (inoutDescSyskey)
	  *inoutDescSyskey = descSyskey;

	// update lob handle with the returned values
	if (outLobHandle)
	  {
	    str_cpy_all(outLobHandle, inLobHandle, inLobHandleLen);
	    ExpLOBoper::updLOBhandle(descSyskey, 0, outLobHandle); 

	    if (outLobHandleLen)
	      *outLobHandleLen = inLobHandleLen;
	  }
       

    
	cliRC = 0;
      }
      break;

    case LOB_CLI_INSERT_APPEND:
      {
        if (lobType == Lob_External_HDFS_File)
          {
            // Not allowed. For external Lobs there shoudl be only one
            // chunk associated with the contents of the external file.
            cliRC = -LOB_DESC_APPEND_ERROR;       
            goto error_return;
          } 
	str_sprintf(query, "update table(ghost table %s) set numChunks = numChunks + 1, lobLen = lobLen + %ld where descPartnKey = %ld and syskey = %ld",
		    lobDescHandleName, 
		    (dataLen ? *dataLen : 0),
		    descPartnKey, inDescSyskey);
        lobDebugInfo(query,0,__LINE__,lobTrace);
	// set parserflags to allow ghost table
	currContext.setSqlParserFlags(0x1);
	
	cliRC = cliInterface->executeImmediate(query);
	currContext.resetSqlParserFlags(0x1);

	if (cliRC < 0)
	    goto error_return;

	str_sprintf(query, "select numChunks from table(ghost table %s) h where h.descPartnKey = %ld and h.syskey = %ld for read committed access",
		    lobDescHandleName,  
		    descPartnKey, inDescSyskey);

	// set parserflags to allow ghost table
	currContext.setSqlParserFlags(0x1);
	
	Lng32 numChunks = 0;
	Lng32 len;
	cliRC = cliInterface->executeImmediate(query, (char*)&numChunks, &len, FALSE);

	currContext.resetSqlParserFlags(0x1);

	if (cliRC < 0)
	    goto error_return;
	
	// insert into lob descriptor chunks table
	if (blackBox && (blackBoxLen && (*blackBoxLen > 0)))
	  {
	    str_sprintf(query, "insert into table(ghost table %s) values (%ld, %ld, %d, %ld, %ld, '%s')",
			lobDescChunksName, descPartnKey, inDescSyskey, 
			numChunks, (dataLen ? *dataLen : 0),
			(dataOffset ? *dataOffset : 0),
			blackBox);
            lobDebugInfo(query,0,__LINE__,lobTrace);
	  }
	else
	  {
	    str_sprintf(query, "insert into table(ghost table %s) values (%ld, %ld, %d, %ld, %ld, NULL)",
			lobDescChunksName, descPartnKey, inDescSyskey, 
			numChunks, (dataLen ? *dataLen : 0),
			(dataOffset ? *dataOffset : 0)
			);
            lobDebugInfo(query,0,__LINE__,lobTrace);
	  }
	
	// set parserflags to allow ghost table
	currContext.setSqlParserFlags(0x1);
	
	cliRC = cliInterface->executeImmediate(query);

	currContext.resetSqlParserFlags(0x1);

	if (cliRC < 0)
	    goto error_return;
      	if (inoutDescPartnKey)
	  *inoutDescPartnKey = descPartnKey;

	if (inoutDescSyskey)
	  *inoutDescSyskey = inDescSyskey;

        if(blackBoxLen)
          *blackBoxLen = numChunks;
	cliRC = 0;

	//	if (outDescSyskey)
	//	  *outDescSyskey = inDescSyskey;
      }
      break;


  case LOB_CLI_UPDATE_UNIQUE:
      {
	// update desc handle table
	str_sprintf(query, "update table(ghost table %s) set numChunks = 1, lobLen = %ld where descPartnKey = %ld and syskey = %ld",
		    lobDescHandleName, 
		    (dataLen ? *dataLen : 0),
		    descPartnKey, inDescSyskey);
	lobDebugInfo(query,0,__LINE__,lobTrace);

	// set parserflags to allow ghost table
	currContext.setSqlParserFlags(0x1);
	
	cliRC = cliInterface->executeImmediate(query);
	currContext.resetSqlParserFlags(0x1);

	if (cliRC < 0)
	    goto error_return;



	// delete all chunks from lob descriptor chunks table
	str_sprintf(query, "delete from table(ghost table %s) where descPartnKey = %ld and descSysKey = %ld",
		    lobDescChunksName, descPartnKey, inDescSyskey);

	// set parserflags to allow ghost table
	currContext.setSqlParserFlags(0x1);
	
	cliRC = cliInterface->executeImmediate(query);

	currContext.resetSqlParserFlags(0x1);

	if (cliRC < 0)
	    goto error_return;

        if ((lobType != Lob_External_HDFS_File) && blackBox)
          {
            //Error . Cannot update an LOB column that has a non-external LOB
            // with an external LOB. 
            cliRC = -LOB_DESC_UPDATE_ERROR;        
            goto error_return;
          }
	// insert the new chunk into lob descriptor chunks table
	if (blackBox && (blackBoxLen && (*blackBoxLen > 0)))
	  {
	    str_sprintf(query, "insert into table(ghost table %s) values (%ld, %ld, 1, %ld, %ld, '%s')",
			lobDescChunksName, descPartnKey, inDescSyskey,
			(dataLen ? *dataLen : 0),
			(dataOffset ? *dataOffset : 0),
			blackBox);
	    lobDebugInfo(query,0,__LINE__,lobTrace);
	  }
	else
	  {
	   str_sprintf(query, "insert into table(ghost table %s) values (%ld, %ld, 1, %ld, %ld, NULL)",
			lobDescChunksName, descPartnKey, inDescSyskey,
			(dataLen ? *dataLen : 0),
			(dataOffset ? *dataOffset : 0));
           lobDebugInfo(query,0,__LINE__,lobTrace);
	  }
	  
	// set parserflags to allow ghost table
	currContext.setSqlParserFlags(0x1);
	
	cliRC = cliInterface->executeImmediate(query);

	currContext.resetSqlParserFlags(0x1);

	if (cliRC < 0)
	   goto error_return;
       
	// update lob handle with the returned values
	if (outLobHandle)
	  {
	    str_cpy_all(outLobHandle, inLobHandle, inLobHandleLen);
	    ExpLOBoper::updLOBhandle(inDescSyskey, 0, outLobHandle); 

	    if (outLobHandleLen)
	      *outLobHandleLen = inLobHandleLen;
	  }
	if (inoutDescPartnKey)
	  *inoutDescPartnKey = descPartnKey;

	if (inoutDescSyskey)
	  *inoutDescSyskey = inDescSyskey;
	cliRC = 0;
      }
      break;

    case LOB_CLI_DELETE:
      {
	// delete from lob descriptor handle table
	str_sprintf(query, "delete from table(ghost table %s) where descPartnKey = %ld and syskey = %ld",
		    lobDescHandleName, descPartnKey, inDescSyskey);
        lobDebugInfo(query,0,__LINE__,lobTrace);
	// set parserflags to allow ghost table
	currContext.setSqlParserFlags(0x1);
	
	cliRC = cliInterface->executeImmediate(query);

	currContext.resetSqlParserFlags(0x1);

	if (cliRC < 0)
	   goto error_return;

	// delete from lob descriptor chunks table
	str_sprintf(query, "delete from table(ghost table %s) where descPartnKey = %ld and descSysKey = %ld",
		    lobDescChunksName, descPartnKey, inDescSyskey);
        lobDebugInfo(query,0,__LINE__,lobTrace);
	// set parserflags to allow ghost table
	currContext.setSqlParserFlags(0x1);
	
	cliRC = cliInterface->executeImmediate(query);

	currContext.resetSqlParserFlags(0x1);

	if (cliRC < 0)
	    goto error_return;
        
      }
      break;

   case LOB_CLI_SELECT_UNIQUE:
      {
	// check if there are multiple chunks.
	Int32 numChunks = 0;
	str_sprintf(query, "select numChunks from table(ghost table %s) where descPartnKey = %ld for read committed access",
		    lobDescHandleName,
		    descPartnKey);
        lobDebugInfo(query,0,__LINE__,lobTrace);
	// set parserflags to allow ghost table
	currContext.setSqlParserFlags(0x1);
	
	cliRC = cliInterface->fetchRowsPrologue(query);

	currContext.resetSqlParserFlags(0x1);

	if (cliRC < 0)
	    goto error_return;

        cliRC = cliInterface->fetch();
	if (cliRC < 0)
	  {
	    cliInterface->fetchRowsEpilogue(0);
	    goto error_return;
	  }

	if (cliRC != 100)
	  {
	    char * ptr;
	    Lng32 len;

	    cliInterface->getPtrAndLen(1, ptr, len);	    
	    str_cpy_all((char*)&numChunks, ptr, len);
	  }
	if (numChunks > 1)
	  {
	    //The master will redrive with a cursor read
	    *blackBoxLen = -1;
	    cliInterface->fetchRowsEpilogue(0);
	    goto error_return;
	  }
        else if ((numChunks > 1 ) && (lobType == Lob_External_HDFS_File))
          {
            // Should not happen. For external Lobs there should be only one 
            // chunk associated with the contents of the external file.
            cliRC = -LOB_DATA_READ_ERROR;        
            goto error_return;
          }
	else
	  {	    
	    cliRC = cliInterface->fetchRowsEpilogue(0);
	    if (cliRC < 0)
		goto error_return;	 	  
	  }
	
	// This lob has only one chunk. Read and return the single descriptor.
      
	str_sprintf(query, "select c.chunkLen, c.dataOffset ,c.stringParam from table(ghost table %s) h, table(ghost table %s) c where h.descPartnKey = c.descPartnKey and h.syskey = c.descSyskey and h.descPartnKey = %ld and h.syskey = %ld and c.chunkNum = h.numChunks for read committed access",
		    lobDescHandleName, lobDescChunksName, 
		    descPartnKey, inDescSyskey);
         
        lobDebugInfo(query,0,__LINE__,lobTrace);
	// set parserflags to allow ghost table
	currContext.setSqlParserFlags(0x1);
	
	cliRC = cliInterface->fetchRowsPrologue(query);

	currContext.resetSqlParserFlags(0x1);

	if (cliRC < 0)
	    goto error_return;

	cliRC = cliInterface->fetch();
	if (cliRC < 0)
	  {

	    cliInterface->fetchRowsEpilogue(0);

	    goto error_return;
	  }

	if (cliRC != 100)
	  {
	    char * ptr;
	    Lng32 len;

	    cliInterface->getPtrAndLen(1, ptr, len);	    
	    if (dataLen)
	      str_cpy_all((char*)dataLen, ptr, len);

	    cliInterface->getPtrAndLen(2, ptr, len);	    
	    if (dataOffset)
	      str_cpy_all((char*)dataOffset, ptr, len);
 
           cliInterface->getPtrAndLen(3, ptr, len);	    
	    if (blackBox)
              {
	      str_cpy_all((char*)blackBox, ptr, len);
              *blackBoxLen = len;
              }

	    if (inoutDescPartnKey)
	      *inoutDescPartnKey = descPartnKey;

	    if (inoutDescSyskey)
	      *inoutDescSyskey = inDescSyskey;
	  }
        else
          {
            if (cliRC == 100)
              {
                if (dataLen)
                  *dataLen = 0;
                if (dataOffset)
                  *dataOffset = 0;
                if (blackBoxLen)
                  *blackBoxLen = 0;
                if (inoutDescPartnKey)
                  *inoutDescPartnKey = descPartnKey;

                if (inoutDescSyskey)
                  *inoutDescSyskey = inDescSyskey;
              }
          }

	Lng32 saveCliErr = cliRC;

	cliRC = cliInterface->fetchRowsEpilogue(0);
	if (cliRC < 0)
	    goto error_return;

	cliRC = saveCliErr;
      }
      break;

   case LOB_CLI_SELECT_CURSOR:
      {
	str_sprintf(query, "select dataOffset, chunkLen, stringParam from table(ghost table %s) where descPartnKey = %ld and descSyskey = %ld order by chunkNum for read committed access",
		    lobDescChunksName, descPartnKey, inDescSyskey);
        lobDebugInfo(query,0,__LINE__,lobTrace);
	// set parserflags to allow ghost table
	currContext.setSqlParserFlags(0x1);
	
	cliRC = cliInterface->fetchRowsPrologue(query);

	currContext.resetSqlParserFlags(0x1);

	if (cliRC < 0)
	    goto error_return;

	if (inCliInterface)
	  *inCliInterface = cliInterface;
      }
      break;

    case LOB_CLI_SELECT_FETCH:
      {
	cliRC = cliInterface->fetch();
	if (cliRC < 0)
	  {
	    cliInterface->fetchRowsEpilogue(0);

	    if (inCliInterface)
	      *inCliInterface = NULL;

	    goto error_return;
	  }

	if (cliRC != 100)
	  {
	    char * ptr;
	    Lng32 len;

	    cliInterface->getPtrAndLen(1, ptr, len);
	    
	    if (dataOffset)
	      str_cpy_all((char*)dataOffset, ptr, len);


	    cliInterface->getPtrAndLen(2, ptr, len);
	    
	    if (dataLen)
	      str_cpy_all((char*)dataLen, ptr, len);

            cliInterface->getPtrAndLen(3, ptr, len);
            if (blackBox)
              {
                str_cpy_all((char*)blackBox, ptr, len);
                *blackBoxLen = len;
              }
	    cliRC = 0;
	  }
	else
	  {
	    
	    cliRC = 100;
	  }
      }
      break;

    case LOB_CLI_SELECT_CLOSE:
      {
	cliRC = cliInterface->fetchRowsEpilogue(0);
	if (cliRC < 0)
	  {
	    
	    if (inCliInterface)
	      *inCliInterface = NULL;
	    goto error_return;
	  }
	
	cliRC = 100;
	
	if (inCliInterface)
	  *inCliInterface = NULL;
      }
      break;

   case LOB_CLI_PURGEDATA:
      {
	// delete data from the handle desc table
	str_sprintf(query, "delete from table(ghost table %s)",
		    lobDescHandleName);
        lobDebugInfo(query,0,__LINE__,lobTrace);
	// set parserflags to allow ghost table
	currContext.setSqlParserFlags(0x1);
	
	cliRC = cliInterface->executeImmediate(query);

	currContext.resetSqlParserFlags(0x1);

	if (cliRC < 0)
	    goto error_return;

	// delete data from the chunks desc table
	str_sprintf(query, "delete from table(ghost table %s)",
		    lobDescChunksName);
        lobDebugInfo(query,0,__LINE__,lobTrace);
	// set parserflags to allow ghost table
	currContext.setSqlParserFlags(0x1);
	
	cliRC = cliInterface->executeImmediate(query);

	currContext.resetSqlParserFlags(0x1);

	if (cliRC < 0)
           goto error_return;

      }
      break;
  case LOB_CLI_SELECT_LOBLENGTH:
      {
	
	//aggregate on chunklen for this lob.

	str_sprintf (query,  "select sum(chunklen) from  %s   where descpartnkey = %ld and descsyskey = %ld ", lobDescChunksName, descPartnKey, inDescSyskey );
        lobDebugInfo(query,0,__LINE__,lobTrace);
	// set parserflags to allow ghost table
	currContext.setSqlParserFlags(0x1);
	

	Int64 outlen = 0;Lng32 len = 0;
	cliRC = cliInterface->executeImmediate(query,(char *)dataLen, &len, FALSE);
        currContext.resetSqlParserFlags(0x1);
        if (inoutDescPartnKey)
          *inoutDescPartnKey = descPartnKey;

        if (inoutDescSyskey)
          *inoutDescSyskey = inDescSyskey;
	    
	Lng32 saveCliErr = cliRC;

	
	if (cliRC < 0)
	  {
	    cliInterface->retrieveSQLDiagnostics(myDiags);
	    
	    goto error_return;
	  }

	cliRC = saveCliErr;
      }
      break;
     case LOB_CLI_SELECT_LOBOFFSET:
      {
	
	//Retrive offset of the first chunk
	str_sprintf(query, "select  c.dataOffset from table(ghost table %s) h, table(ghost table %s) c where h.descPartnKey = c.descPartnKey and h.syskey = c.descSyskey and h.descPartnKey = %ld and h.syskey = %ld and c.chunkNum = 1 for read committed access",
		    lobDescHandleName, lobDescChunksName, 
		    descPartnKey, inDescSyskey);

        lobDebugInfo(query,0,__LINE__,lobTrace);
	// set parserflags to allow ghost table
	currContext.setSqlParserFlags(0x1);
	

	Lng32 len = 0;
	cliRC = cliInterface->executeImmediate(query,(char *)dataOffset, &len, FALSE);
        currContext.resetSqlParserFlags(0x1);
        if (inoutDescPartnKey)
          *inoutDescPartnKey = descPartnKey;

        if (inoutDescSyskey)
          *inoutDescSyskey = inDescSyskey;
	    


	Lng32 saveCliErr = cliRC;

	
	if (cliRC < 0)
	    goto error_return;

	cliRC = saveCliErr;
      }
      break;    
    } // switch 

  // normal return. Fall down to deallocate of structures.
  
 error_return:

  Lng32 tempCliRC = 0;
  if (xnJoined)
    {
      tempCliRC = SUSPENDTRANSACTION((short *) &xnId);
      if (tempCliRC)
	cliRC = -EXE_BEGIN_TRANSACTION_ERROR;
    }
    
  if (xnAutoCommit)
    {
      strcpy(query, "set transaction autocommit off;");
      tempCliRC = cliInterface->executeImmediate(query);
      if (tempCliRC < 0)
	cliRC = tempCliRC;
    
    }
 
  NADELETEBASIC(query, currContext.exHeap());

  if (cliRC < 0)
    {
      if (myDiags == NULL)
         myDiags = ComDiagsArea::allocate(currContext.exHeap());
      cliInterface->retrieveSQLDiagnostics(myDiags);
      diags.mergeAfter(*myDiags);
      myDiags->decrRefCount();
    }
  if (NOT (inCliInterface && (*inCliInterface)))
    {
      delete cliInterface;
      cliInterface = NULL;
    }
  if (cliRC < 0)
     return cliRC;
  else if (cliRC == 100)
    return 100;
  else
    return 0;
}
/* The process for GC is as follows:
1. Check LOB descriptor chunks table (per column) for any holes in the LOB sections.
2. Create an in memory array that can be used to calculate new offsets.
3. Update the lob descriptor chunks table to reflect the new offsets
   if any error, return an error and rollback the user transaction.
4. Compact the lob data file buy doing hte following :
   a) Save a copy of the LOB data file.
   b) Create a temp lob file to copy the sections contiguously from the lob data file to the temp file.
        If any error return an error and rollback all updates to the lob descriptor chunks table.
   c) Delete the lob data file. 
   d) Rename the tempfile to original lob data file name.
      If any error, restore the lob data file from the saved backup in step (a)
   e) Purge the saved backup.
*/


Lng32 SQLCLI_LOB_GC_Interface
(
     /*IN*/     CliGlobals *cliGlobals,
     /*IN*/     ExLobGlobals *lobGlobals, // can be passed or NULL
     /*IN*/     char * handle,
     /*IN*/     Lng32  handleLen,
     /*IN*/     char*  hdfsServer,
     /*IN*/     Lng32  hdfsPort,
     /*IN*/     char  *lobLocation,
     /*IN*/    Int64 lobMaxMemChunkLen, // if passed in as 0, will use default value of 1G for the in memory buffer to do compaction.
     /*IN*/    NABoolean lobTrace
 )
{
  Lng32 cliRC = 0;
  char logBuf[4096];
  lobDebugInfo("In LOB_GC_Interface",0,__LINE__,lobTrace);
  ContextCli   & currContext = *(cliGlobals->currContext());
  ComDiagsArea & diags       = currContext.diags();

  ComDiagsArea * myDiags = NULL;

  ExeCliInterface *cliInterface = NULL;
  cliInterface = new (currContext.exHeap()) 
    ExeCliInterface(currContext.exHeap(),
		    SQLCHARSETCODE_UTF8,
		    &currContext,
		    NULL);
  Int32 rc = 0;
  Int16 flags = 0;
  Lng32 lobType = 1;
  Lng32 lobNum = 0;
  Int64 uid = 0;
  Int64 inDescSyskey, inDescPartnKey;
  short schNameLen = 0;
  char schName[512];
  if (handle)
    {
      ExpLOBoper::extractFromLOBhandle(&flags, &lobType, &lobNum, &uid,  
				       &inDescSyskey, &inDescPartnKey,
				       &schNameLen, schName,
				       handle);
    }
  str_sprintf(logBuf,"flags %d, lobType %d, lobNum :%d, uid : %ld, descSyskey: %ld, descPartnKey : %ld, schNameLen:%d, schName %s", flags,lobType,lobNum,uid,inDescSyskey,inDescPartnKey,schNameLen,schName);
  lobDebugInfo(logBuf,0,__LINE__,lobTrace);
  char tgtLobNameBuf[100];
  char * tgtLobName = 
    ExpLOBoper::ExpGetLOBname(uid, lobNum, tgtLobNameBuf, 100);
  str_sprintf(logBuf,"lobName %s", tgtLobName);
  lobDebugInfo(logBuf,0,__LINE__,lobTrace);
  char lobDescHandleNameBuf[1024];
  Lng32 lobDescHandleNameLen = 1024;
  char * lobDescHandleName = 
    ExpLOBoper::ExpGetLOBDescHandleName(schNameLen, schName, uid, lobNum,
					lobDescHandleNameBuf, lobDescHandleNameLen);
  str_sprintf(logBuf,"lobDescHandleName %s", lobDescHandleName);
  lobDebugInfo(logBuf,0,__LINE__,lobTrace);
  char lobDescChunksNameBuf[1024];
  Lng32 lobDescChunksNameLen = 1024;
  char * lobDescChunksName = 
    ExpLOBoper::ExpGetLOBDescChunksName(schNameLen, schName, uid, lobNum,
					lobDescChunksNameBuf, lobDescChunksNameLen);
  str_sprintf(logBuf,"lobDescChunksName %s", lobDescChunksName);
  lobDebugInfo(logBuf,0,__LINE__,lobTrace);
  
 
  char * query = new(currContext.exHeap()) char[4096];
  //Find how many entries in the descchunks table to allocate 
  //in memory array.
  str_sprintf(query, "select count(*) from table(ghost table %s) ",
              lobDescChunksName);		    
  lobDebugInfo(query,0,__LINE__,lobTrace);
  // set parserflags to allow ghost table
  currContext.setSqlParserFlags(0x1);
	
  Int64 numEntries = 0;
  Lng32 len;
  cliRC = cliInterface->executeImmediate(query, (char*)&numEntries, &len, FALSE);
  str_sprintf(logBuf,"Number of entries in descchunktable %s is %ld",lobDescChunksName, numEntries);
   lobDebugInfo(logBuf,0,__LINE__,lobTrace);
  currContext.resetSqlParserFlags(0x1);

  if (cliRC < 0)
      goto error_return;
  {     
  //Allocate an inmemory array of numEntries.
  ExLobInMemoryDescChunksEntry *dcInMemoryArray = new ExLobInMemoryDescChunksEntry[numEntries];
  //Read the desc chunks table into memory
        
  str_sprintf(query, "select dataOffset, descPartnKey,descSyskey,chunkLen,chunkNum from table(ghost table %s) order by dataOffset,chunkLen for read committed access",
              lobDescChunksName);
  lobDebugInfo(logBuf,0,__LINE__,lobTrace);
  // set parserflags to allow ghost table
  currContext.setSqlParserFlags(0x1);
	
  cliRC = cliInterface->fetchRowsPrologue(query);

  currContext.resetSqlParserFlags(0x1);

  if (cliRC < 0)
      goto error_return;
  cliRC = cliInterface->fetch();
  if (cliRC < 0)
    {
      cliInterface->fetchRowsEpilogue(0);
      goto error_return;
    }
  
  short i = 0;
  Int64 currentOffset = 0;
  Int64 descPartnKey = 0;
  Int64 descSyskey = 0;
  Int64 chunkLen = 0;
  Int64 chunkNum = 0;
  while (cliRC != 100)
    {
      char * ptr;
      Lng32 len;

      cliInterface->getPtrAndLen(1, ptr, len);	   
      str_cpy_all((char*)&currentOffset, ptr, len);

      cliInterface->getPtrAndLen(2, ptr, len);	    	    
      str_cpy_all((char*)&descPartnKey, ptr, len);

      cliInterface->getPtrAndLen(3, ptr, len);	    	    
      str_cpy_all((char*)&descSyskey, ptr, len);

      cliInterface->getPtrAndLen(4, ptr, len);	    	    
      str_cpy_all((char*)&chunkLen, ptr, len);

      cliInterface->getPtrAndLen(5, ptr, len);	    	    
      str_cpy_all((char*)&chunkNum, ptr, len);
           
      dcInMemoryArray[i].setCurrentOffset(currentOffset);
      dcInMemoryArray[i].setNewOffset(currentOffset);
      dcInMemoryArray[i].setDescPartnKey(descPartnKey);
      dcInMemoryArray[i].setSyskey(descSyskey);
      dcInMemoryArray[i].setChunkLen(chunkLen);
      dcInMemoryArray[i].setChunkNum(chunkNum);

      str_sprintf(logBuf,"Fetched for entry i=%d; currentOffset:%ld, descPartnKey:%ld, sysKey:%ld, chunkLen:%ld,chunkNum %ld", i,currentOffset,descPartnKey,descSyskey,chunkLen,chunkNum);
      lobDebugInfo(logBuf,0,__LINE__,lobTrace);

      cliRC = cliInterface->fetch();
      i++;
      if (cliRC < 0)
        {
          cliInterface->fetchRowsEpilogue(0);
          goto error_return;
        }
    }
	
  cliRC = cliInterface->fetchRowsEpilogue(0);
  if (cliRC < 0)
      goto error_return;
 
  // adjust in memory array to calculate holes and new offsets.
  ExpLOBoper::calculateNewOffsets(dcInMemoryArray,numEntries);
  lobDebugInfo("Calculated new offsets",0,__LINE__,lobTrace);
    
        
  // Update the descChunks table with new offsets
  //TBD start a separate transaction to manage this.
  //For now use the transaction associated with the IUD operation 
  //that triggered this GC

  i = 0;
  while (i < numEntries)
    {
      if (dcInMemoryArray[i].getCurrentOffset() == dcInMemoryArray[i].getNewOffset())
        i++;
      else
        {
         
          str_sprintf(query, "update table(ghost table %s) set dataOffset=%ld, chunkLen = %ld where descPartnKey = %ld and descSysKey = %ld",
                      lobDescChunksName, 
                      dcInMemoryArray[i].getNewOffset(),
                      dcInMemoryArray[i].getChunkLen(),
                      dcInMemoryArray[i].getDescPartnKey(), 
                      dcInMemoryArray[i].getSyskey());
          // set parserflags to allow ghost table
          lobDebugInfo(query,0,__LINE__,lobTrace);

          currContext.setSqlParserFlags(0x1);
	
          cliRC = cliInterface->executeImmediate(query);
          currContext.resetSqlParserFlags(0x1);

          if (cliRC < 0)
            {
              //tbd Give warning and rollback just these updates  and return with warning. For now return error and abort the iud operation itself since there is no support for nested transactions or SUSPEND and RESUME. 
              goto error_return;
            }
          i++;
        }
    }
       
  // Compact into new temp file
       
        
  rc = ExpLOBoper::compactLobDataFile(lobGlobals,dcInMemoryArray,numEntries,tgtLobName,lobMaxMemChunkLen, currContext.exHeap(), &currContext,hdfsServer, hdfsPort,lobLocation);
               
  if (rc )
    {
      cliRC = 1; // Warning 
      ComDiagsArea * da = &diags;
      lobDebugInfo("compactLobDataFile Failed",0,__LINE__,lobTrace);

      ExRaiseSqlError(currContext.exHeap(), &da, 
                      (ExeErrorCode)(8442), NULL, &cliRC    , 
                      &rc, NULL, (char*)"Lob GC call",
		      getLobErrStr(rc), (char*)getSqlJniErrorStr());
      // TBD When local transaction support is in
      // rollback all the updates to the lob desc chunks file too. 
      // return with warning
      // For now, return error for the IUD operation

      // Restore original data file.
      Int32 rc2=ExpLOBoper::restoreLobDataFile(lobGlobals,tgtLobName, currContext.exHeap(),&currContext,hdfsServer,hdfsPort,lobLocation);
      if (rc2)
        {
          lobDebugInfo("restoreLobDataFile Failed",0,__LINE__,lobTrace);
        }
      // if error restoring, this lob could become corrupt.
      goto error_return;
    }
  else
    {
      //TBD :commit all updates and remove the saved copy of datafile
      ExpLOBoper::purgeBackupLobDataFile(lobGlobals, tgtLobName,currContext.exHeap(),&currContext,hdfsServer,hdfsPort,lobLocation);
      lobDebugInfo("purgedLobDataFile ",0,__LINE__,lobTrace);
    }
  }
 error_return:

  Lng32 tempCliRC = 0;
  NADELETEBASIC(query, currContext.exHeap());


  if (cliRC < 0)
    {
      if (myDiags == NULL)
         myDiags = ComDiagsArea::allocate(currContext.exHeap());
      diags.mergeAfter(*myDiags);
      myDiags->decrRefCount();
    	
    }
  if (cliRC < 0)
     return cliRC;
  else if (cliRC == 100)
    return 100;
  else
    return 0;   
}

Lng32 SQLCLI_LOBddlInterface
(
/*IN*/     CliGlobals *cliGlobals,
 /*IN*/     char * schName,
 /*IN*/     Lng32  schNameLen,
 /*IN*/     Int64  objectUID,
 /*IN*/     Lng32  &numLOBs,
 /*IN*/     LOBcliQueryType qType,
 /*IN*/     short *lobNumList,
 /*IN*/     short *lobTypList,
 /*IN*/     char* *lobLocList,
/*IN*/      char* *lobColNameList,
 /*IN*/     char *lobHdfsServer,
 /*IN*/     Int32 hdfsPort,
/*IN*/    Int64 lobMaxSize,
/*IN*/    NABoolean lobTrace
 )
 
{
  Lng32 cliRC = 0;
  ExLobGlobals *exLobGlob = NULL;
  ContextCli   & currContext = *(cliGlobals->currContext());
  ComDiagsArea & diags       = currContext.diags();

  ComDiagsArea * myDiags = NULL;
  NABoolean useLibHdfs = currContext.getSessionDefaults()->getUseLibHdfs();
  char logBuf[4096];
  lobDebugInfo("In LOBddlInterface",0,__LINE__,lobTrace);
  ExeCliInterface *cliInterface = NULL;
  cliInterface = new (currContext.exHeap()) 
    ExeCliInterface(currContext.exHeap(),
		    SQLCHARSETCODE_UTF8,
		    &currContext,
		    NULL);

  char lobMDNameBuf[1024];
  Lng32 lobMDNameLen = 1024;
  char * lobMDName = 
    ExpLOBoper::ExpGetLOBMDName(schNameLen, schName, objectUID,
				lobMDNameBuf, lobMDNameLen);
  str_sprintf(logBuf,"lobMDName %s", lobMDName);
  lobDebugInfo(logBuf,0,__LINE__,lobTrace);
  char * query = new(currContext.exHeap()) char[4096];
  char *hdfsServer = new(currContext.exHeap()) char[256];
  strcpy(hdfsServer,lobHdfsServer);
  Int32 rc = 0;
  switch (qType)
    {
    case LOB_CLI_CREATE:
    case LOB_CLI_ALTER :
      {
       
        // create lob metadata table
        str_sprintf(query, "create ghost table %s (lobnum smallint not null, storagetype smallint not null, location varchar(4096) not null, column_name varchar(256 bytes) character set utf8, primary key (lobnum)) ",lobMDName);
        lobDebugInfo(query,0,__LINE__,lobTrace);

        // set parserflags to allow ghost table
        currContext.setSqlParserFlags(0x1);
	
        cliRC = cliInterface->executeImmediate(query);	
        currContext.resetSqlParserFlags(0x1);
	
        if (cliRC < 0)
          {
            ComDiagsArea *tempDiags = ComDiagsArea::allocate(currContext.exHeap());
            cliInterface->retrieveSQLDiagnostics(tempDiags);
            if (tempDiags->containsError(-CAT_TRAFODION_OBJECT_EXISTS))
              {
                if (qType ==LOB_CLI_ALTER)
                  {
                    //Clear the diags . This table already has a lob column
                    //So no need to create an MD table. Just continue
                    cliInterface->clearGlobalDiags();
                    tempDiags->decrRefCount();
                  }
              }
            else
              goto error_return;
          }
          
	// populate the lob metadata table
	for (Lng32 i = 0; i < numLOBs; i++)
	  {
	    str_sprintf(query, "insert into table (ghost table %s) values (%d, %d, '%s','%s')",
			lobMDName, 
			lobNumList[i], lobTypList[i], lobLocList[i],lobColNameList[i]);
            lobDebugInfo(query,0,__LINE__,lobTrace);

	    // set parserflags to allow ghost table
	    currContext.setSqlParserFlags(0x1);
	    
	    cliRC = cliInterface->executeImmediate(query);
	    
	    currContext.resetSqlParserFlags(0x1);
	    
	    if (cliRC < 0)
	       goto error_return;
	    
	  } // for

        //Initialize LOB interface 
        
        exLobGlob = ExpLOBoper::initLOBglobal(currContext.exHeap(), &currContext, useLibHdfs);
        if (exLobGlob == NULL) 
          {
            cliRC = -1;
            ComDiagsArea * da = &diags;
            ExRaiseSqlError(currContext.exHeap(), &da, 
			    (ExeErrorCode)(8442), NULL, &cliRC    , 
			    &rc, NULL, (char*)"ExpLOBInterfaceCreate",
		            getLobErrStr(rc), (char*)getSqlJniErrorStr());
            goto non_cli_error_return;
          }

	for (Lng32 i = 0; i < numLOBs; i++)
	  {
	    // create lob data tables
	       rc = ExpLOBoper::createLOB
	      (exLobGlob, &currContext,
	       lobLocList[i],  hdfsPort,hdfsServer,
	       objectUID, lobNumList[i],lobMaxSize);
	    
	    if (rc)
	      {
		cliRC = -1;
		ComDiagsArea * da = &diags;
		ExRaiseSqlError(currContext.exHeap(), &da, 
			    (ExeErrorCode)(8442), NULL, &cliRC    , 
			    &rc, NULL, (char*)"ExpLOBInterfaceCreate",
		            getLobErrStr(rc), (char*)getSqlJniErrorStr());
		goto non_cli_error_return;
	      }
	    
	    // create LOB descriptor and LOB header tables
	    char lobHandle[LOB_HANDLE_LEN];
	    Lng32 handleLen = 0;
	    ExpLOBoper::genLOBhandle(objectUID,
				     lobNumList[i],
				     lobTypList[i],
				     0, 0, 0,
				     schNameLen,
				     schName,
				     handleLen,
				     lobHandle);
	    
	    cliRC = SQL_EXEC_LOBcliInterface(lobHandle, handleLen,
					     NULL, 0,
					     NULL, NULL,
					     LOB_CLI_CREATE,
					     LOB_CLI_ExecImmed,
					     NULL,
					     NULL,
					     NULL,
					     NULL,
					     NULL,
					     0,lobTrace);
	    if (cliRC < 0)
	       goto error_return;
	    
	  } // for
	
      }
      break;

    case LOB_CLI_DROP:
      {
	str_sprintf(query, "drop ghost table %s",
		    lobMDName);
        lobDebugInfo(query,0,__LINE__,lobTrace);

	// set parserflags to allow ghost table
	currContext.setSqlParserFlags(0x1);
	
	cliRC = cliInterface->executeImmediate(query);
	
	currContext.resetSqlParserFlags(0x1);

	if (cliRC < 0)
           goto error_return;
	
	// drop descriptor table
	for (Lng32 i = 0; i < numLOBs; i++)
	  {	   
	    
	    // drop LOB descriptor and LOB header tables
	    char lobHandle[LOB_HANDLE_LEN];
	    Lng32 handleLen = 0;
	    ExpLOBoper::genLOBhandle(objectUID,
				     lobNumList[i],
				     lobTypList[i],
				     0, 0, 0,
				     schNameLen,
				     schName,
				     handleLen,
				     lobHandle);
	    
	    cliRC = SQL_EXEC_LOBcliInterface(lobHandle, handleLen,
					     NULL, 0,
					     NULL, NULL,
					     LOB_CLI_DROP,
					     LOB_CLI_ExecImmed,
					     NULL,
					     NULL,
					     NULL,
					     NULL,
					     NULL,
					     0,lobTrace);
	    if (cliRC < 0)
		goto error_return;
	    
	  } // for
        //If all the descriptor tables got dropped correctly, drop the hdfs 
        //lob data files.  Note that if there is an error in the drop of the 
        //descriptor tables above , the transaction will restore each of the 
        //above tables . 
        //Initialize LOB interface 
       
        exLobGlob = ExpLOBoper::initLOBglobal(currContext.exHeap(), &currContext, useLibHdfs);
        if (exLobGlob == NULL) 
          {
            cliRC = -1;
            ComDiagsArea * da = &diags;
            ExRaiseSqlError(currContext.exHeap(), &da, 
			    (ExeErrorCode)(8442), NULL, &cliRC    , 
			    &rc, NULL, (char*)"ExpLOBInterfaceCreate",
		            getLobErrStr(rc), (char*)getSqlJniErrorStr());
            goto non_cli_error_return;
	      
          }
        for (Lng32 i = 0; i < numLOBs; i++)
	  {
	      rc = ExpLOBoper::dropLOB
	      (exLobGlob,&currContext,
	       lobLocList[i],hdfsPort,hdfsServer,
	       objectUID, lobNumList[i]);
            // Ignore 'not found' error from hdfs file deletes until this is made transactional just like Hbase tables are.
            if (rc && (rc != -LOB_DATA_FILE_DELETE_ERROR))
	      {
		cliRC = -1;
		ComDiagsArea * da = &diags;
		ExRaiseSqlError(currContext.exHeap(), &da, 
			    (ExeErrorCode)(8442), NULL, &cliRC    , 
			    &rc, NULL, (char*)"ExpLOBInterfaceDrop  ",
		            getLobErrStr(rc), (char*)getSqlJniErrorStr());
		goto non_cli_error_return;
              }
          }//for
      }
      break;

    case LOB_CLI_CLEANUP:
      {
	str_sprintf(query, "cleanup table %s", lobMDName);
        lobDebugInfo(query,0,__LINE__,lobTrace);

	// set parserflags to allow ghost table
	currContext.setSqlParserFlags(0x1);
	
	cliRC = cliInterface->executeImmediate(query);
	
	currContext.resetSqlParserFlags(0x1);
	
	if (cliRC < 0)
           goto error_return;

	//Initialize LOB interface 
        exLobGlob = ExpLOBoper::initLOBglobal(currContext.exHeap(), &currContext, useLibHdfs);
        if (exLobGlob == NULL) 
          {
            cliRC = -1;
            ComDiagsArea * da = &diags;
            ExRaiseSqlError(currContext.exHeap(), &da, 
			    (ExeErrorCode)(8442), NULL, &cliRC    , 
                            &rc, NULL, (char*)"ExpLOBInterfaceCreate",
		            getLobErrStr(rc), (char*)getSqlJniErrorStr());
            goto non_cli_error_return;	      
          }
	// drop descriptor table
	for (Lng32 i = 0; i < numLOBs; i++)
	  {
	    Lng32 rc = ExpLOBoper::dropLOB
	      (exLobGlob,&currContext,
	       lobLocList[i],hdfsPort, hdfsServer,
	       objectUID, lobNumList[i]);
	    
	    if (rc && rc != -LOB_DATA_FILE_DELETE_ERROR)
	      {
		cliRC = -1;
		ComDiagsArea * da = &diags;
		ExRaiseSqlError(currContext.exHeap(), &da, 
			    (ExeErrorCode)(8442), NULL, &cliRC    , 
			    &rc, NULL, (char*)"ExpLOBInterfaceDrop  ",
		            getLobErrStr(rc), (char*)getSqlJniErrorStr());
		goto non_cli_error_return;
	      }
	    
	    // drop LOB descriptor and LOB header tables
	    char lobHandle[512];
	    Lng32 handleLen = 0;
	    ExpLOBoper::genLOBhandle(objectUID,
				     lobNumList[i],
				     lobTypList[i],
				     0, 0, 0,
				     schNameLen,
				     schName,
				     handleLen,
				     lobHandle);
	    
	    cliRC = SQL_EXEC_LOBcliInterface(lobHandle, handleLen,
					     NULL, 0,
					     NULL, NULL,
					     LOB_CLI_CLEANUP,
					     LOB_CLI_ExecImmed,
					     NULL,
					     NULL,
					     NULL,
					     NULL,
					     NULL,
					     0,lobTrace);
	    if (cliRC < 0)
		goto error_return;
	    
	  } // for
	
      }
      break;

    case LOB_CLI_SELECT_CURSOR:
    case LOB_CLI_SELECT_UNIQUE:
       {
	 if (qType == LOB_CLI_SELECT_CURSOR)
	   str_sprintf(query, "select lobnum, storagetype, location,column_name from table(ghost table %s) order by lobnum for read uncommitted access",
		       lobMDName);
         
	 else
	   str_sprintf(query, "select lobnum, storagetype, location ,column_name from table(ghost table %s) where lobnum = %d for read uncommitted access",
		       lobMDName, numLOBs);
         lobDebugInfo(query,0,__LINE__,lobTrace);

	// set parserflags to allow ghost table
	currContext.setSqlParserFlags(0x1);
	
	cliRC = cliInterface->fetchRowsPrologue(query);

	currContext.resetSqlParserFlags(0x1);

	if (cliRC < 0)
	    goto error_return;

	cliRC = 0;
	Lng32 j = 0;
	numLOBs = 0;
	while (cliRC != 100)
	  {
	    cliRC = cliInterface->fetch();
	    if (cliRC < 0)
	      {
		
		cliInterface->fetchRowsEpilogue(0);
		
		goto error_return;
	      }
	    
	    if (cliRC != 100)
	      {
		char * ptr;
		Lng32 len;
		
		short lobNum;
		cliInterface->getPtrAndLen(1, ptr, len);
		str_cpy_all((char*)&lobNum, ptr, len);
		lobNumList[j] = lobNum;

		short stType;
		cliInterface->getPtrAndLen(2, ptr, len);
		str_cpy_all((char*)&stType, ptr, len);
		lobTypList[j] = stType;

		cliInterface->getPtrAndLen(3, ptr, len);
		str_cpy_and_null(lobLocList[j], ptr, len, '\0', ' ', TRUE);
	
                cliInterface->getPtrAndLen(4, ptr, len);
		str_cpy_and_null(lobColNameList[j], ptr, len, '\0', ' ', TRUE);
		j++;

		if ((qType == LOB_CLI_SELECT_UNIQUE) &&
		    (j > 1))
		  {
		    // error. Unique cannot return multiple rows.
		    cliRC = -8900;
		    cliInterface->fetchRowsEpilogue(0);
		    
		    goto error_return;

		  }
	      }
	    else
	      {
		Lng32 ccliRC = cliInterface->fetchRowsEpilogue(0);
		if (ccliRC < 0)
		  {
		    cliRC = ccliRC;
		    goto error_return;
		  }
	      }
	  } // while

	if (j > 0)
	  cliRC = 0;
	else
	  cliRC = 100;
	
	if (qType == LOB_CLI_SELECT_CURSOR)
	  numLOBs = j;
      }
      break;

    } // switch

 error_return:
  if (cliRC < 0)
    {
      if (myDiags == NULL)
         myDiags = ComDiagsArea::allocate(currContext.exHeap());
      cliInterface->retrieveSQLDiagnostics(myDiags);
      diags.mergeAfter(*myDiags);
      myDiags->decrRefCount();
    }
 non_cli_error_return:
  if (exLobGlob != NULL)
     ExpLOBoper::deleteLOBglobal(exLobGlob, currContext.exHeap());
  NADELETEBASIC(query, currContext.exHeap());
  NADELETEBASIC(hdfsServer,currContext.exHeap());
  delete cliInterface;
  if (cliRC < 0)
     return cliRC;
  else if (cliRC == 100)
    return 100;
  else
    return 0;
}

/*
  Int32 SQLCLI_SWITCH_TO_COMPILER_TYPE(CliGlobals * cliGlobals,
                                       Int32 compiler_class_type)
          - switch to unused CmpContext instance with the same class type,
            if compiler_class_type is 0, switch to any unused CmpContext,
            if no desired CmpContext to switch to, create new one
          - return value
              0 success
              -1 failed to create new CmpContext
              -2 invalid compile_class_type
*/
Int32 SQLCLI_SWITCH_TO_COMPILER_TYPE (
 /*IN*/     CliGlobals *cliGlobals,
 /*IN*/     Int32 cmpClassType
 )
{
  ContextCli *currContext = GetCliGlobals()->currContext();

  Int32 retCode = currContext->switchToCmpContext(cmpClassType);
 
  if (retCode == 0)
    return retCode;  // success

  ComDiagsArea &diagsArea = currContext->diags();
  if (retCode == -1)
    diagsArea << DgSqlCode(2032)
              << DgString0(CmpContextInfo::getCmpContextClassName(cmpClassType))
              ;
  else
    diagsArea << DgSqlCode(2032)
              << DgString0("(invalid type)");  // give warning

  return retCode;
}  

/*
  Int32 SQLCLI_SWITCH_TO_COMPILER(CliGlobals * cliGlobals,
                                  void * cmpCntxt)
          - switch to given CmpContext instance
            if the given instance is not known, add it to the CmpContext
            list with class name "NONE" (default)
          - return value
              0 success
              -1 given instance is null
              1 given instance is in use but switched anyway
*/
Int32 SQLCLI_SWITCH_TO_COMPILER (
 /*IN*/     CliGlobals *cliGlobals,
 /*IN*/     void * cmpCntxt
)  
{
  ContextCli *currContext = cliGlobals->currContext();

  Int32 retCode = currContext->switchToCmpContext(cmpCntxt);

  if (retCode >= 0)
    return retCode;  // success

  ComDiagsArea &diagsArea = currContext->diags();
  diagsArea << DgSqlCode(2032)
            << DgString0("invalid compiler pointer");  // give warning

  return retCode;
}

/*
  Int32 SQLCLI_SWITCH_BACK_COMPILER(CliGlobals *cliGlobals)
          - switch back to previous used CmpContext instance
          - return value
              0 success
              -1 no previous CmpContext to switch back
*/
Int32 SQLCLI_SWITCH_BACK_COMPILER (
 /*IN*/     CliGlobals *cliGlobals
)  
{
  ContextCli *currContext = cliGlobals->currContext();

  return (currContext->switchBackCmpContext());
}

Lng32 SQLCLI_SEcliInterface
(
 CliGlobals *cliGlobals,
 SECliQueryType qType,
 
 void* *inCliInterface,

 const char * inStrParam1,
 const char * inStrParam2,
 Lng32 inIntParam1,
 Lng32 inIntParam2,

 char* *outStrParam1,
 char* *outStrParam2,
 Lng32 *outIntParam1
 )
{
  Lng32 rc = 0;

  ContextCli   & currContext = *(cliGlobals->currContext());
  ComDiagsArea & diags       = currContext.diags();

  ExeCliInterface *cliInterface = NULL;
  if (inCliInterface && (*inCliInterface))
    {
      cliInterface = (ExeCliInterface*)(*inCliInterface);
    }
  else
    {
      cliInterface = new (currContext.exHeap()) 
	ExeCliInterface(currContext.exHeap(),
			SQLCHARSETCODE_UTF8,
			&currContext,
			NULL);

      cliInterface->setNotExeUtilInternalQuery(TRUE);

      if (inCliInterface)
	*inCliInterface = cliInterface;
    }

  switch (qType)
    {
    case SE_CLI_CREATE_CONTEXT:
      {
	rc = cliInterface->createContext((char*)inStrParam1);
      }
      break;

    case SE_CLI_SWITCH_CONTEXT:
      {
	rc = cliInterface->switchContext((char*)inStrParam1);
      }
      break;

    case SE_CLI_CURRENT_CONTEXT:
      {
	rc = cliInterface->currentContext((char*)inStrParam1);
      }
      break;

    case SE_CLI_DROP_CONTEXT:
      {
	rc = cliInterface->deleteContext((char*)inStrParam1);
      }
      break;

    case SE_CLI_CLEAR_DIAGS:
      {
	cliInterface->clearGlobalDiags();
	rc = 0;
      }
      break;

    case SE_CLI_EXEC_IMMED:
      {
	rc = cliInterface->executeImmediate((char*)inStrParam1);
      }
      break;

    case SE_CLI_EXEC_IMMED_PREP:
      {
	rc = cliInterface->executeImmediatePrepare((char*)inStrParam1, 
						   NULL, NULL, NULL, FALSE,
						   (char*)inStrParam2);
      }
      break;

    case SE_CLI_EXEC_IMMED_CEFC:
      {
	rc = cliInterface->executeImmediateCEFC((char*)inStrParam1, NULL, 0, 
                                                (char*)inStrParam2, NULL);
      }
      break;

    case SE_CLI_FETCH_ROWS_PROLOGUE:
      {
	rc = cliInterface->fetchRowsPrologue((char*)inStrParam1, FALSE, FALSE,
					     (char*)inStrParam2);
      }
      break;

    case SE_CLI_EXEC:
      {
	rc = cliInterface->exec((char*)inStrParam1, inIntParam1);
      }
      break;

    case SE_CLI_FETCH:
      {
	rc = cliInterface->fetch();
      }
      break;

    case SE_CLI_CLOSE:
      {
	rc = cliInterface->close();
      }
      break;

    case SE_CLI_CEFC:
      {
	rc = cliInterface->clearExecFetchClose((char*)inStrParam1, inIntParam1);
      }
      break;

    case SE_CLI_BEGIN_XN:
      {
	rc = cliInterface->beginXn();
      }
      break;

    case SE_CLI_COMMIT_XN:
      {
	rc = cliInterface->commitXn();
      }
      break;

    case SE_CLI_ROLLBACK_XN:
      {
	rc = cliInterface->rollbackXn();
      }
      break;

    case SE_CLI_STATUS_XN:
      {
	rc = cliInterface->statusXn();
      }
      break;

    case SE_CLI_GET_DATA_OFFSETS:
      {
	rc = cliInterface->getDataOffsets( inIntParam1, inIntParam2,
					   (Lng32*)inStrParam1, (Lng32*)inStrParam2);
      }
      break;

    case SE_CLI_GET_PTR_AND_LEN:
      {
	char * ptr = NULL;
	Lng32 len = 0;
	short * ind = NULL;
	rc = cliInterface->getPtrAndLen(inIntParam1, ptr, len, &ind);
	if (outStrParam1)
	  *outStrParam1 = ptr;
	if (outStrParam2)
	  *outStrParam2 = (char*)ind;
	if (outIntParam1)
	  *outIntParam1 = len;
      }
      break;

    case SE_CLI_GET_IO_LEN:
      {
	if (inIntParam1 == 0)
	  {
	    *outIntParam1 = cliInterface->inputDatalen();
	  }
 
	if (inIntParam1 == 1)
	  {
	    *outIntParam1 = cliInterface->outputDatalen();
	  }

	rc = 0;
      }
      break;

    case SE_CLI_GET_STMT_ATTR:
      {

	rc = cliInterface->getStmtAttr((char*)inStrParam1, (Lng32)inIntParam1, 
				       (Lng32*)outIntParam1, *outStrParam1);
      }
      break;

   case SE_CLI_DEALLOC:
      {
	rc = cliInterface->dealloc();
      }
      break;

    case SE_CLI_TRAFQ_INSERT:
      {
	currContext.trafSElist()->insert(inStrParam1, inIntParam1, (void*)inStrParam2);
      }
      break;

    case SE_CLI_TRAFQ_GET:
      {
	currContext.trafSElist()->position(inStrParam1, inIntParam1);
	*outStrParam1 = (char*)currContext.trafSElist()->getNext();
      }
      break;

    } // switch

  return rc;
}

///////////////////////////////////////////////////////////////////////
// Current design to update sequence metadata:
//
// If there is no Xn running:
//    A transaction is started, update is done within it, and then that Xn is committed.
//    If there is a conflict during commit, then update is retried.
//   
// If there is a user Xn running:
//    Seq Gen table is not updated as part of user xn. It is run in non-transactional
//    mode using hbase transactions.
//    To avoid concurrent updates to seq gen table,
//    Sequence gen table col upd_ts is updated with a generated unique value.
//    Table is then updated with new nextValue and current value is retrieved.
//    At the end, upd_ts value is retrieved and compared to the generated unique
//    value. If they are different, update is retried.
//
//    seq gen update is retried max 10 times.
//    An error is returned if we dont get consistent result after that.
//
//
// Future design:
// 
//    When support for local transactions and repeatable reads are in, 
//    then the select...update will be done in one local transaction.
//    That will guarantee that the select and update are done in the same transaction.
//
//    If a transaction is already running when this update is to be done, then that Xn
//    will be suspended and a new local transaction wil be started. 
//    This local Xn will be committed after update and the
//    original transaction will be resumed(joined back).
// 
////////////////////////////////////////////////////////////////////////////

#define SEQ_GEN_NUM_PREPS 4
#define SEQ_UPD_TS_QRY_IDX 0
#define SEQ_SEL_TS_QRY_IDX 1
#define SEQ_PROCESS_QRY_IDX 2
#define SEQ_CQD_IDX  3


static Lng32 SeqGenCliInterfacePrepQry(
				       const char * qryStr,
				       Lng32 qryIdx,
				       const char * qryName,
				       ExeCliInterface ** cliInterfaceArr,
				       SequenceGeneratorAttributes* sga,
				       ContextCli &currContext,
				       ComDiagsArea & diags,
				       NAHeap *exHeap)
{
  Lng32 cliRC = 0;

  char query[2000];
  char stmtName[200];

  Int64 rowsAffected = 0;

  ComDiagsArea *myDiags = NULL;

  ExeCliInterface * cliInterface = NULL;
  ExeCliInterface * cqdCliInterface = NULL;

  NABoolean doPrep = FALSE;
  if (! cliInterfaceArr[qryIdx])
    {
      str_sprintf(query, qryStr,
		  TRAFODION_SYSCAT_LIT, SEABASE_MD_SCHEMA, SEABASE_SEQ_GEN,
		  sga->getSGObjectUID().get_value());
      
      cliInterfaceArr[qryIdx] = new (currContext.exHeap()) 
	ExeCliInterface(currContext.exHeap(),
			SQLCHARSETCODE_UTF8,
			&currContext,
			NULL);
      
      if (! cliInterfaceArr[SEQ_CQD_IDX])
	cliInterfaceArr[SEQ_CQD_IDX] = new (currContext.exHeap()) 
	  ExeCliInterface(currContext.exHeap(),
			  SQLCHARSETCODE_UTF8,
			  &currContext,
			  NULL);
      
      str_sprintf(stmtName, "%s_%ld", qryName, sga->getSGObjectUID().get_value());
      
      doPrep = TRUE;
    }
  
  cliInterface = cliInterfaceArr[qryIdx];
  cqdCliInterface = cliInterfaceArr[SEQ_CQD_IDX];

  if (doPrep)
    {
      cliRC = cqdCliInterface->holdAndSetCQD("limit_max_numeric_precision", "ON");
      if (cliRC < 0)
	{
         if (myDiags == NULL)
             myDiags = ComDiagsArea::allocate(exHeap);
	  cqdCliInterface->retrieveSQLDiagnostics(myDiags);
	  diags.mergeAfter(*myDiags);
          myDiags->decrRefCount();
	  return cliRC;
	}

      cliRC = cliInterface->executeImmediatePrepare(query, 
						    NULL, 0, 
						    &rowsAffected, FALSE,
						    stmtName);
      if (cliRC < 0)
	{
          if (myDiags == NULL)
             myDiags = ComDiagsArea::allocate(exHeap);
	  cliInterface->retrieveSQLDiagnostics(myDiags);
	  diags.mergeAfter(*myDiags);
          myDiags->decrRefCount();
	  cqdCliInterface->restoreCQD("limit_max_numeric_precision");
	  return cliRC;
	}

      cqdCliInterface->restoreCQD("limit_max_numeric_precision");
    }

  return 0;
}

//static Int64 globalUID = 0;
static Lng32 SeqGenCliInterfaceUpdAndValidate(
					      ExeCliInterface ** cliInterfaceArr,
					      SequenceGeneratorAttributes* sga,
					      NABoolean recycleQry,
                                              NABoolean startLocalXn,
					      ContextCli &currContext,
					      ComDiagsArea & diags,
					      NAHeap *exHeap,
					      Int64 &nextValue,
					      Int64 &endValue)
{
  Lng32 cliRC;

  Int64 outputValues[5];
  Int64 inputValues[5];

  Lng32 outputValuesLen = 0;
  Lng32 inputValuesLen = 0;

  Int64 rowsAffected = 0;

  ExeCliInterface * cliInterface = NULL;

  ComDiagsArea *myDiags = NULL;
  
  char queryBuf[2000];

  Int64 updUID = 0;

  if (NOT startLocalXn)
    {
      if (! cliInterfaceArr[SEQ_UPD_TS_QRY_IDX])
        {
          cliRC = SeqGenCliInterfacePrepQry(
                                            "update %s.\"%s\".%s set upd_ts = cast(? as largeint not null) where seq_uid = %ld",
                                            SEQ_UPD_TS_QRY_IDX,
                                            "SEQ_UPD_TS_QRY_IDX",
                                            cliInterfaceArr, sga, currContext, diags, exHeap);
          if (cliRC < 0)
            return cliRC;
        }
      
      cliInterface = cliInterfaceArr[SEQ_UPD_TS_QRY_IDX];
      
      // generated a unique id and update it. If this value changes later, then
      // this operation will be retried.
      ComUID comUID;
      comUID.make_UID();
      updUID = comUID.get_value();
      inputValues[0] = updUID;
      inputValuesLen = sizeof(updUID);
      cliRC = cliInterface->clearExecFetchCloseOpt
        ((char*)inputValues, inputValuesLen, NULL, NULL, &rowsAffected);
      if (cliRC < 0)
        {
         if (myDiags == NULL)
             myDiags = ComDiagsArea::allocate(exHeap);
          cliInterface->retrieveSQLDiagnostics(myDiags);
          diags.mergeAfter(*myDiags);
          myDiags->decrRefCount();
          return cliRC;
        }
      
      // if not found, aqr
      if (rowsAffected == 0)
        {
          ComDiagsArea * da = &diags;
          ExRaiseSqlError(exHeap, &da,  (ExeErrorCode)(1584));
          
          return -1584;
        }
      
    }

  if (! cliInterfaceArr[SEQ_PROCESS_QRY_IDX])
    {
      cliRC = SeqGenCliInterfacePrepQry(
                                        "select  case when cast(? as largeint not null) = 1 then t.startVal else t.nextValue end, t.redefTS from (update %s.\"%s\".%s set next_value = (case when cast(? as largeint not null) = 1 then start_value + cast(? as largeint not null) else (case when next_value + cast(? as largeint not null) > max_value then max_value+1 else next_value + cast(? as largeint not null) end) end), num_calls = num_calls + 1 where seq_uid = %ld return old.start_value, old.next_value, old.redef_ts) t(startVal, nextValue, redefTS);",
                                        SEQ_PROCESS_QRY_IDX,
                                        "SEQ_PROCESS_QRY_IDX",
                                        cliInterfaceArr, sga, currContext, diags, exHeap);
      if (cliRC < 0)
        return cliRC;
    }
  
  cliInterface = cliInterfaceArr[SEQ_PROCESS_QRY_IDX];

  // execute using optimized path
  Int64 delta = sga->getSGIncrement() * 
    (sga->getSGCache() > 0 ? sga->getSGCache() : 1);
  inputValues[0] = (recycleQry ? 1 : 0);
  inputValues[1] = (recycleQry ? 1 : 0);
  inputValues[2] = delta;
  inputValues[3] = delta;
  inputValues[4] = delta;
  inputValuesLen = 5 * sizeof(Int64);

  cliRC = cliInterface->clearExecFetchCloseOpt
    ((char*)inputValues, inputValuesLen, (char*)outputValues, &outputValuesLen, 
     &rowsAffected);
  if (cliRC < 0)
    {
      if (myDiags == NULL)
         myDiags = ComDiagsArea::allocate(exHeap);
      cliInterface->retrieveSQLDiagnostics(myDiags);
      diags.mergeAfter(*myDiags);
      myDiags->decrRefCount();
      if (diags.mainSQLCODE() == -EXE_NUMERIC_OVERFLOW)
        {
          cliRC = -EXE_SG_MAXVALUE_EXCEEDED;
        }

      return cliRC;
    }

  // must find this uid in seq generator. if not found, aqr.
  if (rowsAffected == 0)
    {
      ComDiagsArea * da = &diags;
      ExRaiseSqlError(exHeap, &da,  (ExeErrorCode)(1584));
      
      return -1584;
    }

  Int64 startValue = outputValues[0];
  Int64 redefTS = outputValues[1];

  // if timestamp mismatch, aqr
  if  (redefTS != sga->getSGRedefTime())
    {
      ComDiagsArea * da = &diags;
      ExRaiseSqlError(exHeap, &da,  (ExeErrorCode)(1584));
      
      return -1584;
     }

  if (NOT startLocalXn)
    {
      // this query retrieves upd_ts after this seqgen has been updated.
      // it is used to validate that it didn't get updated by someone else
      // after my update.
      if (! cliInterfaceArr[SEQ_SEL_TS_QRY_IDX])
        {
          cliRC = SeqGenCliInterfacePrepQry(
                                            "select upd_ts from %s.\"%s\".%s where seq_uid = %ld",
                                            SEQ_SEL_TS_QRY_IDX,
                                            "SEQ_SEL_TS_QRY_IDX",
                                            cliInterfaceArr, sga, currContext, diags, exHeap);
          if (cliRC < 0)
            return cliRC;
        }
      
      cliInterface = cliInterfaceArr[SEQ_SEL_TS_QRY_IDX];
      cliRC = cliInterface->clearExecFetchCloseOpt
        (NULL, 0, (char*)outputValues, &outputValuesLen, &rowsAffected);
      if (cliRC < 0)
        {
          if (myDiags == NULL)
             myDiags = ComDiagsArea::allocate(exHeap);
          cliInterface->retrieveSQLDiagnostics(myDiags);
          diags.mergeAfter(*myDiags);
          myDiags->decrRefCount();
          return cliRC;
        }
      
      // must find this uid in seq generator. if not found, is an error.
      if (rowsAffected == 0)
        {
          ComDiagsArea * da = &diags;
          ExRaiseSqlError(exHeap, &da,  (ExeErrorCode)(1582));
          
          return -1582;
        }
      
      // if update time different than my upd time, retry.
      if (outputValues[0] != updUID)
        {
          return -2;
        }
    }

  nextValue = startValue;
  endValue = nextValue + sga->getSGIncrement() * (sga->getSGCache() - 1);

  if (endValue > sga->getSGMaxValue())
    endValue = sga->getSGMaxValue();

  return 0;
}

static Lng32 SeqGenCliInterfaceUpdAndValidateMulti(
						   ExeCliInterface ** cliInterfaceArr,
						   SequenceGeneratorAttributes* sga,
						   NABoolean recycleQry,
						   ContextCli &currContext,
						   ComDiagsArea & diags,
						   NAHeap *exHeap,
						   Int64 &nextValue,
						   Int64 &endValue)
{
  Lng32 cliRC = 0;
  Lng32 retCliRC = 0;
  ComDiagsArea *myDiags = NULL;

  if (! cliInterfaceArr[SEQ_CQD_IDX])
    cliInterfaceArr[SEQ_CQD_IDX] = new (currContext.exHeap()) 
      ExeCliInterface(currContext.exHeap(),
                      SQLCHARSETCODE_UTF8,
                      &currContext,
                      NULL);
  ExeCliInterface * cqdCliInterface = cliInterfaceArr[SEQ_CQD_IDX];

  NABoolean startLocalXn = FALSE;
  if (cqdCliInterface->statusXn())
    {
      // no xn in progress. Start one.
      startLocalXn = TRUE;
    }
  else
    {
      // a transaction is already running. Do not run seq queries as part of
      // that transaction.
      cliRC = cqdCliInterface->holdAndSetCQD("traf_no_dtm_xn", "ON");
    }

  Lng32 numTries = 0, maxRetryNum = sga->getSGRetryNum();
  NABoolean isOk = FALSE;
  while ((NOT isOk) && (numTries < maxRetryNum))
    {
      if (startLocalXn)
        {
          // no xn in progress. Start one.
          cliRC = cqdCliInterface->beginWork();
          if (cliRC < 0)
            {
              if (myDiags == NULL)
                 myDiags = ComDiagsArea::allocate(exHeap);
              cqdCliInterface->retrieveSQLDiagnostics(myDiags);
              diags.mergeAfter(*myDiags);
              myDiags->decrRefCount();
              retCliRC = cliRC;
              goto label_return;
            }
        }

      cliRC = SeqGenCliInterfaceUpdAndValidate(
					       cliInterfaceArr,
					       sga,
					       recycleQry,
                                               startLocalXn,
					       currContext,
					       diags,
					       exHeap,
					       nextValue,
					       endValue);

     if (cliRC == 0)
        {
          if (startLocalXn)
            {
              // xn was started here, commit it.
              // If an error happens during commit, retry.
              cliRC = cqdCliInterface->commitWork();
              if (cliRC < 0)
                {
                  currContext.diags().clear();

                  cliRC = -2; // retry
                }
            }
        }
     else 
       {
         if (startLocalXn)
            {
              if (cqdCliInterface->statusXn() == 0) // xn running
                {
                  // error case. If xn was started here, abort it.
                  cqdCliInterface->rollbackWork();
                }
            }
       }

      if (cliRC == 0)
        {
          isOk = TRUE;
        }
      else if (cliRC != -2)
        {
          retCliRC = cliRC;
          goto label_return;
        }
      
      numTries++;
      Lng32 delayTime = 100 + numTries*25 + rand()%10; 
      if( delayTime < 1000)   //MAX is 1 second
          DELAY(delayTime);
      else
          DELAY( 900 + rand() % 100);
    }

    // could not update it after 10 tries. Return error.
  if (NOT isOk)
    {
      ComDiagsArea * da = &diags;
      ExRaiseSqlError(exHeap, &da,  (ExeErrorCode)(1583));

      retCliRC = -1583;
      goto label_return;
    }

 label_return:
  if (NOT startLocalXn)
    cliRC = cqdCliInterface->restoreCQD("traf_no_dtm_xn");
  
  return retCliRC;
}

Lng32 SQLCLI_SeqGenCliInterface
(
 CliGlobals *cliGlobals,
 void ** inCliInterfaceArr,
 void * seqGenAttrs
 )
{
  Lng32 rc = 0;
  Lng32 cliRC = 0;

  ContextCli   & currContext = *(cliGlobals->currContext());
  ComDiagsArea & diags       = currContext.diags();

  ExeCliInterface ** cliInterfaceArr = NULL;
  if (inCliInterfaceArr && (*inCliInterfaceArr))
    {
      cliInterfaceArr = (ExeCliInterface**)(*inCliInterfaceArr);
    }
  else
    {
      cliInterfaceArr = new(currContext.exHeap()) ExeCliInterface*[SEQ_GEN_NUM_PREPS];

      for (Lng32 i = 0; i < SEQ_GEN_NUM_PREPS; i++)
	{
	  cliInterfaceArr[i] = NULL;
	}

      if (inCliInterfaceArr)
	*inCliInterfaceArr = cliInterfaceArr;
    }

  SequenceGeneratorAttributes* sga = (SequenceGeneratorAttributes*)seqGenAttrs;

  Int64 nextValue = 0;
  Int64 endValue = 0;

  cliRC = SeqGenCliInterfaceUpdAndValidateMulti(
						cliInterfaceArr,
						sga,
						FALSE,
						currContext,
						diags,
						currContext.exHeap(),
						nextValue,
						endValue);
  if (cliRC < 0) {
     return cliRC;
  }
  
  if ((sga->getSGCycleOption()) &&
      (nextValue > sga->getSGMaxValue()))
    {
      cliRC = SeqGenCliInterfaceUpdAndValidateMulti(
						    cliInterfaceArr,
						    sga,
						    TRUE,
						    currContext,
						    diags,
						    currContext.exHeap(),
						    nextValue,
						    endValue);
      if (cliRC < 0) {
	 return cliRC;
      }
    }
  sga->setSGNextValue(nextValue);
  sga->setSGEndValue(endValue);

  return 0;
}


Int32 SQLCLI_GetRoutine
(
     /* IN */     CliGlobals  *cliGlobals,
     /* IN */     const char  *serializedInvocationInfo,
     /* IN */     Int32        invocationInfoLen,
     /* IN */     const char  *serializedPlanInfo,
     /* IN */     Int32        planInfoLen,
     /* IN */     Int32        language,
     /* IN */     Int32        paramStyle,
     /* IN */     const char  *externalName,
     /* IN */     const char  *containerName,
     /* IN */     const char  *externalPath,
     /* IN */     const char  *librarySqlName,
     /* OUT */    Int32       *handle
 )
{
  Lng32 cliRC                = 0;
  ContextCli   & currContext = *(cliGlobals->currContext());
  ComDiagsArea & diags       = currContext.diags();
  LmLanguageManager *lm      = cliGlobals->getLanguageManager(
                                               (ComRoutineLanguage) language);
  LmRoutine *createdRoutine  = NULL;
  LmResult lmres             = LM_ERR;

  *handle = NullCliRoutineHandle;

  if (lm)
    lmres = lm->getObjRoutine(
         serializedInvocationInfo,
         invocationInfoLen,
         serializedPlanInfo,
         planInfoLen,
         (ComRoutineLanguage) language,
         (ComRoutineParamStyle) paramStyle,
         externalName,
         containerName,
         externalPath,
         librarySqlName,
         &createdRoutine,
         &diags);

  if (lmres == LM_OK && createdRoutine != NULL)
    {
      // At the moment we don't set any callback pointers for getRow/emitRow,
      // so the object we are getting can't be used to call the runtime interface,
      // only compile-time calls will work.
      // createdRoutine->setFunctionPtrs(TBD, TBD);

      // assign a CLI handle to the routine and remember it in the context
      *handle = (Int32) currContext.addTrustedRoutine(createdRoutine);
    }
  else
    {
      cliRC = diags.mainSQLCODE();
      if (lmres == LM_OK &&
          cliRC >= 0 &&
          invocationInfoLen == 0)
        // The DDL code calls getRoutine to validate the routine
        // entry point. It does not specify an InvocationInfo and
        // therefore no routine is created, due to insufficient
        // info. Indicate this through this special warning code.
        // Note: No diags area is set, since this is an expected
        // code.
        cliRC = LME_ROUTINE_VALIDATED;
      else
        ex_assert(cliRC < 0, "no diags from getObjRoutine");
    }

  return cliRC;
}

Int32 SQLCLI_InvokeRoutine
(
     /* IN */     CliGlobals  *cliGlobals,
     /* IN */     Int32        handle,
     /* IN */     Int32        phaseEnumAsInt,
     /* IN */     const char  *serializedInvocationInfo,
     /* IN */     Int32        invocationInfoLen,
     /* OUT */    Int32       *invocationInfoLenOut,
     /* IN */     const char  *serializedPlanInfo,
     /* IN */     Int32        planInfoLen,
     /* IN */     Int32        planNum,
     /* OUT */    Int32       *planInfoLenOut,
     /* IN */     char        *inputRow,
     /* IN */     Int32        inputRowLen,
     /* OUT */    char        *outputRow,
     /* IN */     Int32        outputRowLen
 )
{
  Lng32         cliRC       = 0;
  ContextCli   &currContext = *(cliGlobals->currContext());
  ComDiagsArea &diags       = currContext.diags();
  LmResult      res         = LM_ERR;
  LmRoutine    *lmRoutine   = cliGlobals->currContext()->findTrustedRoutine(handle);

  if (lmRoutine)
    res = lmRoutine->invokeRoutineMethod(
         static_cast<tmudr::UDRInvocationInfo::CallPhase>(phaseEnumAsInt),
         serializedInvocationInfo,
         invocationInfoLen,
         invocationInfoLenOut,
         serializedPlanInfo,
         planInfoLen,
         planNum,
         planInfoLenOut,
         inputRow,
         inputRowLen,
         outputRow,
         outputRowLen,
         &diags);

  if (res != LM_OK)
    {
      cliRC = diags.mainSQLCODE();

      if (cliRC >= 0)
        {
          // make sure the diags area indicates an error
          cliRC = -CLI_ROUTINE_INVOCATION_ERROR;
          diags << DgSqlCode(cliRC);
        }
    }

  return cliRC;
}

Int32 SQLCLI_GetRoutineInvocationInfo
(
     /* IN */     CliGlobals  *cliGlobals,
     /* IN */     Int32        handle,
     /* IN/OUT */ char        *serializedInvocationInfo,
     /* IN */     Int32        invocationInfoMaxLen,
     /* OUT */    Int32       *invocationInfoLenOut,
     /* IN/OUT */ char        *serializedPlanInfo,
     /* IN */     Int32        planInfoMaxLen,
     /* IN */     Int32        planNum,
     /* OUT */    Int32       *planInfoLenOut
 )
{
  Lng32         cliRC       = 0;
  ContextCli   &currContext = *(cliGlobals->currContext());
  ComDiagsArea &diags       = currContext.diags();
  LmResult      res         = LM_ERR;
  LmRoutine    *lmRoutine   = cliGlobals->currContext()->findTrustedRoutine(handle);

  if (lmRoutine)
    res = lmRoutine->getRoutineInvocationInfo(
         serializedInvocationInfo,
         invocationInfoMaxLen,
         invocationInfoLenOut,
         serializedPlanInfo,
         planInfoMaxLen,
         planNum,
         planInfoLenOut,
         &diags);

  if (res != LM_OK)
    {
      cliRC = diags.mainSQLCODE();

      if (cliRC >= 0)
        {
          cliRC = -CLI_ROUTINE_INVOCATION_INFO_ERROR;
          diags << DgSqlCode(cliRC);
        }
    }

  return cliRC;
}

Int32 SQLCLI_PutRoutine
(
     /* IN */     CliGlobals  *cliGlobals,
     /* IN */     Int32        handle
 )
{
  if (handle != NullCliRoutineHandle)
    cliGlobals->currContext()->putTrustedRoutine(handle);

  return 0;
}
