/**********************************************************************
// @@@ START COPYRIGHT @@@
//
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.
//
// @@@ END COPYRIGHT @@@
**********************************************************************/

/* -*-C++-*-
 *****************************************************************************
 *
 * File:         ExExeUtilCli.cpp
 * Description:  
 *               
 *               
 * Language:     C++
 *
 *
 *
 *
 *****************************************************************************
 */

//#include "ComCextdecs.h"
#include  "cli_stdh.h"
#include  "ex_stdh.h"
#include  "sql_id.h"
#include  "ComSqlId.h"
#include  "ExExeUtilCli.h"
OutputInfo::OutputInfo(Lng32 numEntries)
  : numEntries_(numEntries)
{
  
   ex_assert( numEntries <= MAX_OUTPUT_ENTRIES, "try to fetch more than max rows allowed");
  
   for (Int32 i = 0; i < numEntries_; i++)
    {
      data_[i] = NULL;
      len_[i] = 0;
    }
}

void OutputInfo::insert(Lng32 index, char * data)
{
  data_[index] = data;
}

void OutputInfo::insert(Lng32 index, char * data, Lng32 len)
{
  data_[index] = data;
  len_[index] = len;
}

void OutputInfo::insert(Lng32 index, char * data, Lng32 len, Lng32 type, Lng32 *indOffset , Lng32 *varOffset )
{
  data_[index] = data;
  len_[index] = len;
  type_[index] = type;
}

char * OutputInfo::get(Lng32 index)
{
  if (index < numEntries_)
    return data_[index];
  else
    return NULL;
}

short OutputInfo::get(Lng32 index, char* &data, Lng32 &len)
{
  if (index < numEntries_)
    {
      data = data_[index];
      len = len_[index];
      return 0;
    }

  return -1;
}

short OutputInfo::get(Lng32 index, char* &data, Lng32 &len, Lng32 &type, Lng32 *indOffset , Lng32 *varOffset )
{
  if (index < numEntries_)
    {
      data = data_[index];
      len = len_[index];
      type = type_[index];
      return 0;
    }

  return -1;
}

void OutputInfo::dealloc(CollHeap * heap)
{
  for (Int32 i = 0; i < numEntries_; i++)
    {
      if(data_[i] != NULL)
        NADELETEBASIC(data_[i], heap);
    }
}

/////////////////////////////////////////////////////////////////
// class ExeCliInterface
/////////////////////////////////////////////////////////////////
ExeCliInterface::ExeCliInterface(CollHeap * heap, Int32 isoMapping,
				 ContextCli * currContext,
                                 const char *parentQid)
     : heap_(heap),
       module_(NULL),
       stmt_(NULL),
       sql_src_(NULL),
       input_desc_(NULL),
       output_desc_(NULL),
       rs_input_maxsize_desc_(NULL),
       outputBuf_(NULL),
       inputBuf_(NULL),
       currContext_(currContext),
       moduleWithCK_(NULL),
       stmtWithCK_(NULL),
       sql_src_withCK_(NULL),
       input_desc_withCK_(NULL),
       output_desc_withCK_(NULL),
       outputBuf_withCK_(NULL),
       rsInputBuffer_(NULL),
       isoMapping_((Int32)SQLCHARSETCODE_ISO88591), // ISO_MAPPING=ISO88591
       parentQid_(parentQid),
       inputAttrs_(NULL),
       outputAttrs_(NULL),
       explainData_(NULL),
       explainDataLen_(0),
       flags_(0)
{
  if (parentQid_)
  {
    Int32 len = str_len(parentQid_);
    ex_assert( len >= ComSqlId::MIN_QUERY_ID_LEN, "parentQid too short.");
    ex_assert( len <= ComSqlId::MAX_QUERY_ID_LEN, "parentQid too long.");
    ex_assert( !str_cmp(parentQid_, COM_SESSION_ID_PREFIX, 4), 
               "invalid parentQid.");
  }  
}

ExeCliInterface::~ExeCliInterface()
{
   dealloc();
}

Lng32 ExeCliInterface::deallocStuff(SQLMODULE_ID * &module,
				SQLSTMT_ID * &stmt,
				SQLDESC_ID * &sql_src,
				SQLDESC_ID * &input_desc,
				SQLDESC_ID * &output_desc)
{
  if (sql_src)
    {
      SQL_EXEC_DeallocDesc(sql_src);
      NADELETEBASIC(sql_src, heap_);
      sql_src = NULL;
    }

  if (stmt)
    {
      SQL_EXEC_DeallocStmt(stmt);
      NADELETEBASIC(stmt, heap_);
      stmt = NULL;
    }

  if (input_desc)
    {
      SQL_EXEC_DeallocDesc(input_desc);
      NADELETEBASIC(input_desc, heap_);
      input_desc = NULL;
    }

  if (output_desc)
    {
      SQL_EXEC_DeallocDesc(output_desc);
      NADELETEBASIC(output_desc, heap_);
      output_desc = NULL;
    }

  if (module)
    {
      NADELETEBASIC(module, heap_);
      module = NULL;
    }

  if (rsInputBuffer_)
    {
      NADELETEBASIC(rsInputBuffer_, heap_);
      rsInputBuffer_ = NULL;
    }

  if (outputAttrs_)
    {
      NADELETEBASIC(outputAttrs_, heap_);
      outputAttrs_ = NULL;
    }

  if (outputBuf_)
    {
      NADELETEBASIC(outputBuf_, heap_);
      outputBuf_ = NULL;
    }

  return 0;
}

Lng32 ExeCliInterface::dealloc()
{
  return deallocStuff(module_, stmt_, sql_src_, input_desc_, output_desc_);
}

void ExeCliInterface::clearGlobalDiags()
{
  SQL_EXEC_ClearDiagnostics(NULL);
}

Lng32 ExeCliInterface::allocStuff(SQLMODULE_ID * &module,
				  SQLSTMT_ID * &stmt,
				  SQLDESC_ID * &sql_src,
				  SQLDESC_ID * &input_desc,
				  SQLDESC_ID * &output_desc,
				  const char * stmtName
  )
{
  Lng32 retcode = 0;
  deallocStuff(module, stmt, sql_src, input_desc, output_desc);

  clearGlobalDiags();

  module = new(heap_) SQLMODULE_ID;
  init_SQLMODULE_ID(module);

  // Allocate a SQL statement
  stmt = new(heap_) SQLSTMT_ID;
  if (stmtName)
    {
      init_SQLSTMT_ID(stmt, SQLCLI_CURRENT_VERSION, stmt_name, module);
      stmt->identifier = 
	new(heap_) char[strlen(stmtName) +1];
      strcpy((char*)stmt->identifier, stmtName);
      stmt->identifier_len = (Lng32)strlen(stmtName);
    }
  else
    init_SQLSTMT_ID(stmt, SQLCLI_CURRENT_VERSION, stmt_handle, module);

  retcode = SQL_EXEC_AllocStmt(stmt, 0);
  if (retcode < 0)
    return retcode;

  // Allocate a descriptor which will hold the SQL statement source
  sql_src = new(heap_) SQLSTMT_ID;
  init_SQLDESC_ID(sql_src, SQLCLI_CURRENT_VERSION, desc_handle, module);

  retcode = SQL_EXEC_AllocDesc(sql_src, 1);
  if (retcode < 0)
    return retcode;

  retcode = SQL_EXEC_SetDescItem(sql_src, 1, SQLDESC_TYPE_FS,
				 REC_BYTE_V_ANSI, 0);
  if (retcode < 0)
    return retcode;

  // Allocate a descriptor which will hold the SQL statement input
  input_desc = new(heap_) SQLSTMT_ID;
  init_SQLDESC_ID(input_desc, SQLCLI_CURRENT_VERSION, desc_handle, module);

  retcode = SQL_EXEC_AllocDesc(input_desc, 1);
  if (retcode < 0)
    return retcode;

  // Allocate a descriptor which will hold the SQL statement output
  output_desc = new(heap_) SQLSTMT_ID;
  init_SQLDESC_ID(output_desc, SQLCLI_CURRENT_VERSION, desc_handle, module);

  retcode = SQL_EXEC_AllocDesc(output_desc, 1);
  if (retcode < 0)
    return retcode;

  return 0;
}

Lng32 ExeCliInterface::prepare(const char * stmtStr,
                              SQLMODULE_ID * module,
                              SQLSTMT_ID * stmt,
                              SQLDESC_ID * sql_src,
                              SQLDESC_ID * input_desc,
                              SQLDESC_ID * output_desc,
                              char ** outputBuf,
                              Queue * outputVarPtrList,
                              char ** inputBuf,
                              Queue * inputVarPtrList,
                              char *uniqueStmtId,
                              Lng32 *uniqueStmtIdLen,
                              SQL_QUERY_COST_INFO *query_cost_info, 
                              SQL_QUERY_COMPILER_STATS_INFO *comp_stats_info,
                              NABoolean monitorThis,
                              NABoolean doNotCachePlan)
{
  Lng32 retcode = 0;
  ULng32 prepFlags = 0;
  SQL_QUERY_COST_INFO local_query_cost_info;
  SQL_QUERY_COMPILER_STATS_INFO local_comp_stats_info;

  if (monitorThis)
    prepFlags |= PREPARE_MONITOR_THIS_QUERY;

  if ((currContext_) && (currContext_->getSessionDefaults()))
    {
      if(currContext_->getSessionDefaults()->callEmbeddedArkcmp())
	prepFlags |= PREPARE_USE_EMBEDDED_ARKCMP;
    }

  if (doNotCachePlan)
    {
      prepFlags |= PREPARE_NO_TEXT_CACHE;
      prepFlags |= PREPARE_DONT_CACHE;
    }

  retcode = SQL_EXEC_SetDescItem(sql_src, 1, SQLDESC_LENGTH,
				 strlen(stmtStr) + 1, 0);
  if (retcode != SUCCESS)
    return retcode;
  retcode = SQL_EXEC_SetDescItem(sql_src, 1, SQLDESC_VAR_PTR,
				 (Long)stmtStr, 0);
  if (retcode != SUCCESS)
    return retcode;

    retcode = SQL_EXEC_SetDescItem(sql_src, 1, SQLDESC_CHAR_SET,  
                                   (Int32)SQLCHARSETCODE_UTF8,0);
  if (retcode != SUCCESS)
    return retcode;

  char parentQid[ComSqlId::MAX_QUERY_ID_LEN + 1];
  char *pQidPtr = NULL;
  if (parentQid_)
  {
    // The parentQid_ is a const char *, but the CLI doesn't 
    // want a const char * arg, so convert it safely here.
    memset(parentQid, 0, sizeof(parentQid));
    memcpy(parentQid,  parentQid_, ComSqlId::MAX_QUERY_ID_LEN);
    pQidPtr = parentQid;
  }
  retcode = SQL_EXEC_SetStmtAttr(stmt, SQL_ATTR_PARENT_QID, 0, pQidPtr);
  if (retcode < 0)
    return retcode;

  // set parserflags to indicate that this is an internal query from exeutil
  NABoolean flagWasSetHere = FALSE;
  if (currContext_)
    {
      if (((currContext_->getSqlParserFlags() & 0x20000) == 0) &&
	  (NOT notExeUtilInternalQuery())) // this is an exeutil internal query. This is the default.
	{
	  flagWasSetHere = TRUE;
	  currContext_->setSqlParserFlags(0x20000); // INTERNAL_QUERY_FROM EXEUTIL
	}
    }
   
  if (uniqueStmtId == NULL)
    retcode = SQL_EXEC_Prepare2(stmt, sql_src,NULL,0,NULL,
				(query_cost_info?query_cost_info:&local_query_cost_info), 
				(comp_stats_info?comp_stats_info:&local_comp_stats_info),
				NULL,0,prepFlags);
  else
  {
    prepFlags |= PREPARE_STANDALONE_QUERY;
    retcode = SQL_EXEC_Prepare2(stmt, sql_src, NULL, 0, NULL,
				(query_cost_info?query_cost_info:&local_query_cost_info), 
				(comp_stats_info?comp_stats_info:&local_comp_stats_info),
				uniqueStmtId, uniqueStmtIdLen, prepFlags);
  }
  // reset internal exeutil query parserflags if it was set in this method.
  if ((currContext_) && (flagWasSetHere))
    currContext_->resetSqlParserFlags(0x20000); // INTERNAL_QUERY_FROM EXEUTIL

  // return the error code that was returned from SQL_EXEC_Prepare
  if (retcode < 0)
    return retcode;

  // clear diagnostics to reset any warnings.
  SQL_EXEC_ClearDiagnostics(NULL);

  Lng32 num_input_entries, num_output_entries;
  retcode = SQL_EXEC_DescribeStmt(stmt, input_desc, output_desc);
  if (retcode != SUCCESS)
    return retcode;
  
  retcode = SQL_EXEC_GetDescEntryCount(input_desc, &num_input_entries);
  if (retcode != SUCCESS)
    return retcode;

  retcode = SQL_EXEC_GetDescEntryCount(output_desc, &num_output_entries);
  if (retcode != SUCCESS)
    return retcode;

  numInputEntries_ = num_input_entries;
  numOutputEntries_ = num_output_entries;

  inputAttrs_ = NULL;
  outputAttrs_ = NULL;
  if (numInputEntries_ > 0)
    inputAttrs_ = (Attrs*) (new(heap_) char[sizeof(Attrs) * numInputEntries_]);

  if (numOutputEntries_ > 0)
    outputAttrs_ = (Attrs*) (new(heap_) char[sizeof(Attrs) * numOutputEntries_]);

  short entry=1;
  Lng32 datatype = 0;
  Lng32 datacharset = 0;
  Lng32 length = 0;
  Lng32 null_flag = 0;
  Lng32 dataOffset = -1;
  Lng32 nullIndOffset = -1;

  outputDatalen_ = 0;
  inputDatalen_ = 0;
  for (; entry <= num_output_entries; entry++)
    {
      retcode = SQL_EXEC_GetDescItem(output_desc, entry,
				     SQLDESC_TYPE_FS,
				     &datatype, 0, 0, 0, 0);
      if (retcode != SUCCESS)
	return retcode;

      retcode = SQL_EXEC_GetDescItem(output_desc, entry,
				     SQLDESC_OCTET_LENGTH,
				     &length, 0, 0, 0, 0);
      if (retcode != SUCCESS)
	return retcode;

      retcode = SQL_EXEC_GetDescItem(output_desc, entry,
				     SQLDESC_NULLABLE,
				     &null_flag, 0, 0, 0, 0);
      if (retcode != SUCCESS)
	return retcode;

      retcode = SQL_EXEC_GetDescItem(output_desc, entry,
				     SQLDESC_CHAR_SET,
				     &datacharset, 0, 0, 0, 0);
      if (retcode != SUCCESS)
	return retcode;

      outputDatalen_ += length;
      if (null_flag)
	outputDatalen_ += SQL_NULL_HDR_SIZE;
      if (datatype == REC_BYTE_V_ASCII ||
	  datatype == REC_BYTE_V_ASCII_LONG ||
	  datatype == REC_BYTE_V_DOUBLE)
	outputDatalen_ += SQL_VARCHAR_HDR_SIZE;

      retcode = SQL_EXEC_GetDescItem(output_desc, entry,
				     SQLDESC_NULL_IND_OFFSET,
				     &nullIndOffset, 0, 0, 0, 0);
      if (retcode != SUCCESS)
	return retcode;
      
      retcode = SQL_EXEC_GetDescItem(output_desc, entry,
				     SQLDESC_DATA_OFFSET,
				     &dataOffset, 0, 0, 0, 0);
      if (retcode != SUCCESS)
	return retcode;
      
      outputAttrs_[entry-1].fsDatatype_ = datatype;
      outputAttrs_[entry-1].length_ = length;
      outputAttrs_[entry-1].nullFlag_ = null_flag;
      outputAttrs_[entry-1].indOffset_ = nullIndOffset;
      outputAttrs_[entry-1].varOffset_ = dataOffset;
    }

  if (outputBuf)
    {
      if ((*outputBuf == NULL) &&
	  (outputDatalen_ > 0))
	*outputBuf = new (heap_) char[outputDatalen_];
      
      Lng32 curpos = 0;
      for (entry=1; entry <= num_output_entries; entry++)
	{
	  retcode = SQL_EXEC_GetDescItem(output_desc, entry,
					 SQLDESC_NULLABLE,
					 &null_flag, 0, 0, 0, 0);
	  if (retcode != SUCCESS)
	    return retcode;
	  
	  if (null_flag)
	    {
	      retcode = SQL_EXEC_SetDescItem(output_desc, entry,
					     SQLDESC_IND_PTR,
					     (Long)&(*outputBuf)[curpos],0);
	      if (retcode != SUCCESS)
		return retcode;

	      curpos += SQL_NULL_HDR_SIZE;
	    }

	  retcode = SQL_EXEC_SetDescItem(output_desc, entry,
					 SQLDESC_VAR_PTR,
					 (Long)&(*outputBuf)[curpos],0);
	  if (retcode != SUCCESS)
	    return retcode;
	  
	  retcode = SQL_EXEC_GetDescItem(output_desc, entry,
					 SQLDESC_OCTET_LENGTH,
					 &length, 0, 0, 0, 0);

          if (outputVarPtrList)
          {
            outputVarPtrList->insert((char*) &(*outputBuf)[curpos]);
          }

	  curpos += length;
	  
	  retcode = SQL_EXEC_GetDescItem(output_desc, entry,
					 SQLDESC_TYPE_FS,
					 &datatype, 0, 0, 0, 0);
	  if (retcode != SUCCESS)
	    return retcode;
	  
	  retcode = SQL_EXEC_GetDescItem(output_desc, entry,
					 SQLDESC_CHAR_SET,
					 &datacharset, 0, 0, 0, 0);
	  if (retcode != SUCCESS)
	    return retcode;

	  if (datatype == REC_BYTE_V_ASCII ||
	      datatype == REC_BYTE_V_ASCII_LONG ||
	      datatype == REC_BYTE_V_DOUBLE)
	    curpos += SQL_VARCHAR_HDR_SIZE;

	}
    }

  entry=1;
  inputDatalen_ = 0;
  for (; entry <= num_input_entries; entry++)
    {
      Lng32 alignedLen = 0;
      retcode = SQL_EXEC_GetDescItem(input_desc, entry,
				     SQLDESC_ALIGNED_LENGTH,
				     &alignedLen, 0, 0, 0, 0);
      if (retcode != SUCCESS)
	return retcode;

      inputDatalen_ += alignedLen;

      retcode = SQL_EXEC_GetDescItem(input_desc, entry,
				     SQLDESC_TYPE_FS,
				     &datatype, 0, 0, 0, 0);
      if (retcode != SUCCESS)
	return retcode;

      retcode = SQL_EXEC_GetDescItem(input_desc, entry,
				     SQLDESC_OCTET_LENGTH,
				     &length, 0, 0, 0, 0);
      if (retcode != SUCCESS)
	return retcode;

      retcode = SQL_EXEC_GetDescItem(input_desc, entry,
				     SQLDESC_NULLABLE,
				     &null_flag, 0, 0, 0, 0);
      if (retcode != SUCCESS)
	return retcode;

      retcode = SQL_EXEC_GetDescItem(input_desc, entry,
				     SQLDESC_NULL_IND_OFFSET,
				     &nullIndOffset, 0, 0, 0, 0);
      if (retcode != SUCCESS)
	return retcode;
      
      retcode = SQL_EXEC_GetDescItem(input_desc, entry,
				     SQLDESC_DATA_OFFSET,
				     &dataOffset, 0, 0, 0, 0);
      if (retcode != SUCCESS)
	return retcode;
      
      inputAttrs_[entry-1].fsDatatype_ = datatype;
      inputAttrs_[entry-1].length_ = length;
      inputAttrs_[entry-1].nullFlag_ = null_flag;
      inputAttrs_[entry-1].indOffset_ = nullIndOffset;
      inputAttrs_[entry-1].varOffset_ = dataOffset;
    }

  if (inputBuf)
    {
      if ((*inputBuf == NULL) &&
	  (inputDatalen_ > 0))
	*inputBuf = new (heap_) char[inputDatalen_];
      
      Lng32 curpos = 0;
      for (entry=1; entry <= num_input_entries; entry++)
	{
	  retcode = SQL_EXEC_GetDescItem(input_desc, entry,
					 SQLDESC_NULL_IND_OFFSET,
					 &nullIndOffset, 0, 0, 0, 0);
	  if (retcode != SUCCESS)
	    return retcode;

	  retcode = SQL_EXEC_GetDescItem(input_desc, entry,
					 SQLDESC_DATA_OFFSET,
					 &dataOffset, 0, 0, 0, 0);
	  if (retcode != SUCCESS)
	    return retcode;

	  if (nullIndOffset >= 0)
	    {
	      retcode = SQL_EXEC_SetDescItem(input_desc, entry,
					     SQLDESC_IND_PTR,
					     (Long)&(*inputBuf)[nullIndOffset],0);
	      if (retcode != SUCCESS)
		return retcode;
	    }
	  
	  retcode = SQL_EXEC_SetDescItem(input_desc, entry,
					 SQLDESC_VAR_PTR,
					 (Long)&(*inputBuf)[dataOffset],0);
	  if (retcode != SUCCESS)
	    return retcode;
	}
    }

  return 0;
}

Lng32 ExeCliInterface::setupExplainData(SQLMODULE_ID * module,
                                        SQLSTMT_ID * stmt)
{
  Lng32 retcode = 0;

  if (explainData_)
    NADELETEBASIC(explainData_, getHeap());

  explainData_ = NULL;
  explainDataLen_ = 0;

  // get explain fragment.
  explainDataLen_ = 50000; // start with 50K bytes
  Int32 retExplainLen = 0;
  explainData_ = new(getHeap()) char[explainDataLen_+1];
  retcode = SQL_EXEC_GetExplainData(stmt,
                                    explainData_, explainDataLen_+1, 
                                    &retExplainLen
                                    );
  if (retcode == -CLI_GENCODE_BUFFER_TOO_SMALL)
    {
      NADELETEBASIC(explainData_, getHeap());

      explainDataLen_ = retExplainLen;
      explainData_ = new(getHeap()) char[explainDataLen_ + 1];

      retcode = SQL_EXEC_GetExplainData(stmt,
                                        explainData_, explainDataLen_+1, 
                                        &retExplainLen
                                        );
    }
  
  if (retcode != SUCCESS)
    {
      NADELETEBASIC(explainData_, getHeap());
      explainData_ = NULL;
      explainDataLen_ = 0;

      return retcode;
    }

  explainDataLen_ = retExplainLen;
  
  return retcode;
}

Lng32 ExeCliInterface::setupExplainData()
{
  return setupExplainData(module_, stmt_);
}


Lng32 ExeCliInterface::exec(char * inputBuf, Lng32 inputBufLen)
{
  Lng32 retcode = 0;

  if (! stmt_)
    {
      return -CLI_STMT_NOT_EXISTS;
    }

  // set parserflags to indicate that this is an internal query from exeutil
  NABoolean flagWasSetHere = FALSE;
  if (currContext_)
    {
      if (((currContext_->getSqlParserFlags() & 0x20000) == 0) &&
	  (NOT notExeUtilInternalQuery())) // this is an exeutil internal query. This is the default.
	{
	  flagWasSetHere = TRUE;
	  currContext_->setSqlParserFlags(0x20000); // INTERNAL_QUERY_FROM EXEUTIL
	}
    }

  if ((inputBuf) && (inputBuf_) && (inputDatalen_ > 0) && (inputBufLen > 0))
    memcpy(inputBuf_, inputBuf, MINOF(inputDatalen_, inputBufLen));

  retcode = SQL_EXEC_Exec(stmt_, input_desc_, 0);

  // reset internal exeutil query parserflags if it was set in this method.
   if ((currContext_) && (flagWasSetHere))
     currContext_->resetSqlParserFlags(0x20000); // INTERNAL_QUERY_FROM EXEUTIL

  if (retcode != SUCCESS)
    return retcode;
 
  return retcode;
}

Lng32 ExeCliInterface::fetch()
{
  Lng32 retcode = 0;

  retcode = SQL_EXEC_Fetch(stmt_, output_desc_, 0);
  if (retcode != SUCCESS)
    return retcode;
 
  return retcode;
}

//if indicator pointer is NULL, do not retrieve the indicator
//the datatype SQLTYPECODE... is added (the others did not work)
Lng32 ExeCliInterface::getPtrAndLen(short entry, char* &ptr, Lng32 &len, short**ind)
{
  Long data_addr;
  Lng32 datatype = 0;
  Lng32 retcode;
  Long ind_addr;

  retcode = SQL_EXEC_GetDescItem(output_desc_, entry,
				 SQLDESC_VAR_PTR,
				 &data_addr, 0, 0, 0, 0);
  if (retcode != SUCCESS)
    return retcode;
  
  retcode = SQL_EXEC_GetDescItem(output_desc_, entry,
		  		 SQLDESC_IND_PTR ,
			  	 &ind_addr, 0, 0, 0, 0);
  if (retcode != SUCCESS)
    return retcode;
  
  if (ind != NULL)
    *ind = (short*)ind_addr;
  
  retcode = SQL_EXEC_GetDescItem(output_desc_, entry,
				 SQLDESC_TYPE,
				 &datatype, 0, 0, 0, 0);
  if (retcode != SUCCESS)
    return retcode;
  
  retcode = SQL_EXEC_GetDescItem(output_desc_, entry,
				 SQLDESC_OCTET_LENGTH,
				 &len, 0, 0, 0, 0);
  if (retcode != SUCCESS)
    return retcode;

  short *nullIndPtr = (short *)ind_addr;
  if (nullIndPtr && *nullIndPtr < 0)  
    {
      // without this test, when "showddl component sql_operations"
      // ran some child query which returned a nullable column
      // with a SQL NULL value, junk from data_addr was interpreted
      // as a length and the caller of this method tried to allocate
      // too many bytes.
      len = 0;
    }
  else 
  if (datatype == REC_BYTE_V_ASCII ||
      datatype == REC_BYTE_V_ASCII_LONG ||
      datatype == REC_BYTE_V_DOUBLE ||
      datatype == SQLTYPECODE_VARCHAR_WITH_LENGTH ||
      datatype == SQLTYPECODE_VARCHAR_LONG ||
      datatype == SQLTYPECODE_BLOB ||
      datatype == SQLTYPECODE_CLOB
      )
    {

      // Depending on value of len, first 2 or 4 bytes of data indicate
      // the actual length -- adjust data and length
      if (len & 0xFFFF8000)
	{
	  Lng32 VClen;
	  str_cpy_all((char*)&VClen, (char*)data_addr, sizeof(Lng32));
	  data_addr += sizeof(Lng32);
	  len = VClen;
	}
      else
	{
	  short VClen;
	  str_cpy_all((char*)&VClen, (char*)data_addr, sizeof(short));
	  data_addr += sizeof(short);
	  len = VClen;
	}
    }

  ptr = (char*)data_addr;

  return 0;
}

Lng32 ExeCliInterface::getHeadingAndLen(short entry, char* heading, Lng32 &len)
{
  Lng32 retcode;

  len = 0;
  retcode = SQL_EXEC_GetDescItem(output_desc_, entry,
				 SQLDESC_HEADING,
				 0, heading,
				 ComMAX_1_PART_EXTERNAL_UTF8_NAME_LEN_IN_BYTES, &len, 0);
  if (retcode != SUCCESS)
    return retcode;
  
  if (len == 0)
    {
      retcode = SQL_EXEC_GetDescItem(output_desc_, entry,
				     SQLDESC_NAME,
				     0, heading,
				     ComMAX_1_PART_EXTERNAL_UTF8_NAME_LEN_IN_BYTES/*CAT_MAX_HEADING_LEN*/, &len, 0);
      if (retcode != SUCCESS)
	return retcode;
    }

  return 0;
}

Lng32 ExeCliInterface::getNumEntries(Lng32 &numInput, Lng32 &numOutput)
{
  Lng32 retcode = 0;

  retcode = SQL_EXEC_GetDescEntryCount(input_desc_, &numInput);
  if (retcode != SUCCESS)
    return retcode;

  retcode = SQL_EXEC_GetDescEntryCount(output_desc_, &numOutput);
  if (retcode != SUCCESS)
    return retcode;

  return retcode;
}


Lng32 ExeCliInterface::getAttributes(short entry, NABoolean forInput,
				    Lng32 &fsDatatype, Lng32 &length,
				    Lng32 *indOffset, Lng32 *varOffset)
{
  Lng32 retcode = 0;

  if (forInput)
    {
      fsDatatype = inputAttrs_[entry-1].fsDatatype_;
      length = inputAttrs_[entry-1].length_;
      if (indOffset)
	*indOffset = inputAttrs_[entry-1].indOffset_;
      if (varOffset)
	*varOffset = inputAttrs_[entry-1].varOffset_;
    }
  else
    {
      fsDatatype = outputAttrs_[entry-1].fsDatatype_;
      length = outputAttrs_[entry-1].length_;
      if (indOffset)
	*indOffset = outputAttrs_[entry-1].indOffset_;
      if (varOffset)
	*varOffset = outputAttrs_[entry-1].varOffset_;
    }

  return retcode;
}

Lng32 ExeCliInterface::getDataOffsets(short entry, Lng32 forInput,
				    Lng32 *indOffset, Lng32 *varOffset)
{
  Lng32 temp;
  if (forInput)
    {
      if (inputAttrs_ && inputAttrs_[entry-1].varOffset_ && inputAttrs_[entry-1].indOffset_)
	{
	  *varOffset = inputAttrs_[entry-1].varOffset_;
	  *indOffset = inputAttrs_[entry-1].indOffset_;
	}
      else
	{
	  return getAttributes(entry, forInput, temp, temp,
			       indOffset, varOffset);
	}
    }
  else
    {
      return getAttributes(entry, forInput, temp, temp,
			   indOffset, varOffset);
    }
  return 0;
}

Lng32 ExeCliInterface::getStmtAttr(char * stmtName, Lng32 attrName, 
				   Lng32 * numeric_value, char * string_value)
{
  Lng32 retcode = 0;
  
  SQLMODULE_ID module;
  init_SQLMODULE_ID(&module);
  
  char stmtNameBuf[400];
  SQLSTMT_ID stmt;
  init_SQLSTMT_ID(&stmt, SQLCLI_CURRENT_VERSION, stmt_name, &module);
  stmt.identifier = stmtNameBuf;
  strcpy((char*)stmt.identifier, stmtName);
  stmt.identifier_len = (Lng32)strlen(stmtName);
  
  retcode = SQL_EXEC_GetStmtAttr(&stmt, attrName, numeric_value, string_value,
				  0, NULL);
  
  return retcode;
}

Lng32 ExeCliInterface::close()
{
  Lng32 retcode = 0;

  if (stmt_)
    {
      retcode = SQL_EXEC_CloseStmt(stmt_);
      if (retcode != SUCCESS)
	return retcode;
    }

  return retcode;
}



Lng32 ExeCliInterface::executeImmediatePrepare(const char * stmtStr,
					       char * outputBuf,
					       Lng32 * outputBufLen,
					       Int64 * rowsAffected,
					       NABoolean monitorThis,
					       char * stmtName
					      )
{
  Lng32 retcode = 0;
  if (outputBufLen)
    *outputBufLen = 0;

  retcode = allocStuff(module_, stmt_, sql_src_, input_desc_, output_desc_,
		       stmtName);
  if (retcode != SUCCESS)
    return retcode;

  retcode = prepare(stmtStr, module_, stmt_, sql_src_, 
		    input_desc_, output_desc_, &outputBuf,NULL,&inputBuf_,
		    NULL,NULL,NULL,NULL,NULL,monitorThis);
  if (retcode < 0)
    {
      deallocStuff(module_, stmt_, sql_src_, input_desc_, output_desc_);
      return retcode;
    }
  
  return 0;
}

Lng32 ExeCliInterface::executeImmediatePrepare2(const char * stmtStr,
					     char *uniqueStmtId,
                                             Lng32 *uniqueStmtIdLen,
                                             SQL_QUERY_COST_INFO *query_cost_info,
                                             SQL_QUERY_COMPILER_STATS_INFO *comp_stats_info,
                                             char * outputBuf,
					     Lng32 * outputBufLen,
					     Int64 * rowsAffected,
					     NABoolean monitorThis
					     )
{
  Lng32 retcode = 0;

  if (outputBufLen)
    *outputBufLen = 0;

  retcode = allocStuff(module_, stmt_, sql_src_, input_desc_, output_desc_);
  if (retcode != SUCCESS)
    return retcode;

  retcode = prepare(stmtStr, module_, stmt_, sql_src_, 
		    input_desc_, output_desc_, &outputBuf, NULL, NULL, NULL,
                    uniqueStmtId, uniqueStmtIdLen, query_cost_info, comp_stats_info,monitorThis);
  if (retcode < 0)
    {
      deallocStuff(module_, stmt_, sql_src_, input_desc_, output_desc_);
      return retcode;
    }
  
  return 0;
}

Lng32 ExeCliInterface::executeImmediateExec(const char * stmtStr,
					   char * outputBuf,
					   Lng32 * outputBufLen,
					   NABoolean nullTerminate,
					   Int64 * rowsAffected,
                                           ComDiagsArea **diagsArea)
{
  Lng32 retcode = 0;
  Lng32 diagsCount = 0;

  retcode = exec();
  if (retcode < 0)
    {
      deallocStuff(module_, stmt_, sql_src_, input_desc_, output_desc_);
      goto ExecReturn;
    }

  retcode = fetch();
  if (retcode < 0)
    {
      deallocStuff(module_, stmt_, sql_src_, input_desc_, output_desc_);
      goto ExecReturn;
    }

  if ((outputBuf) &&
      (outputBufLen))
    {
      *outputBufLen = 0;
      if (retcode != 100)
	{
	  char * ptr;
	  Lng32 len;
	  getPtrAndLen(1, ptr, len);         
          str_cpy_all(outputBuf, ptr, len);
	  
	  if (nullTerminate)
	    outputBuf[len] = 0;
	  *outputBufLen = len;
	}
    }

  Lng32 rc;
  if (retcode >= 0)
  {
    if (rowsAffected)
    {
      Int64 tmpRowsAffected = 0;
      rc = SQL_EXEC_GetDiagnosticsStmtInfo2(NULL, SQLDIAG_ROW_COUNT,
        &tmpRowsAffected, NULL,
        0, NULL);

      if (rc == EXE_NUMERIC_OVERFLOW) 
      {
        GetRowsAffected(rowsAffected);
      }
      else
        *rowsAffected = tmpRowsAffected;
    }
    rc = SQL_EXEC_GetDiagnosticsStmtInfo2(NULL, SQLDIAG_NUMBER,
                       &diagsCount, NULL, 0, NULL);
    // No need to passback the warnings of SQL_NO_DATA (100)
    if (retcode == 100)
       diagsCount--; 
  }
ExecReturn:
  if (retcode < 0 ||  diagsCount > 0) 
  {   
     if (diagsArea != NULL) 
     {
         if (*diagsArea == NULL)
            *diagsArea = ComDiagsArea::allocate(heap_); 
         rc = SQL_EXEC_MergeDiagnostics_Internal(**diagsArea);
     }
     // if diagsArea is not passed in, retain the diagnostics info
     // in ContextCli for it to be retrieved later 
     // But, deallocate the statement
     else
     {
        rc = close();
        deallocStuff(module_, stmt_, sql_src_, input_desc_, output_desc_);
        return retcode;
     }
  }
  rc = close();
  deallocStuff(module_, stmt_, sql_src_, input_desc_, output_desc_);
  clearGlobalDiags();
  return retcode;
}
// When the globalDiags is not null, errors and warnings are
// passed to the caller. If *globalsDiags points to NULL,
// allocate ComDiagsArea and pass back the error or warnings
// to the caller.
// 
// If *globalDiags points to ComDiagsArea already, pass back
// the diagnostics conditions back to the caller after executing
// the stmtStr along with new errors or warnings.
Lng32 ExeCliInterface::executeImmediate(const char * stmtStr,
				       char * outputBuf,
				       Lng32 * outputBufLen,
				       NABoolean nullTerminate,
				       Int64 * rowsAffected,
				       NABoolean monitorThis,
				       ComDiagsArea **globalDiags)
{
  Lng32 retcode = 0;

  ComDiagsArea * tempDiags = NULL;
  if (globalDiags != NULL && *globalDiags != NULL && (*globalDiags)->getNumber() > 0)
  {
     tempDiags = ComDiagsArea::allocate(heap_);
     tempDiags->mergeAfter(**globalDiags);
  }

  clearGlobalDiags();
  outputBuf_ = NULL;
  inputBuf_ = NULL;
  retcode = executeImmediatePrepare(stmtStr, 
				    (nullTerminate ? outputBuf_ : outputBuf),
				    outputBufLen,
				    rowsAffected,monitorThis);
  if (retcode < 0) 
     goto ExecuteImmediateReturn;
  retcode = executeImmediateExec(stmtStr, 
				 outputBuf, outputBufLen,
				 nullTerminate,
				 rowsAffected,
                                 globalDiags);
ExecuteImmediateReturn:
  if ((globalDiags))
    {
      // Allocate the diagnostics area if needed
      // and populate the diagnostics conditions
      if (*globalDiags == NULL && retcode != 0 && retcode != 100) {
         *globalDiags = ComDiagsArea::allocate(getHeap());
         SQL_EXEC_MergeDiagnostics_Internal(**globalDiags);
      }
      //  populate the diagnostics conditons passed in
      if (tempDiags)
         (*globalDiags)->mergeAfter(*tempDiags);
    }

  if (tempDiags)
      tempDiags->deAllocate();
  return retcode;
}

short ExeCliInterface::fetchRowsPrologue(const char * sqlStrBuf, 
					 NABoolean noExec,
					 NABoolean monitorThis,
					 char * stmtName)
{
  Lng32 retcode;

  clearGlobalDiags();

  retcode = allocStuff(module_, stmt_, sql_src_, input_desc_, output_desc_,
		       stmtName);
  if (retcode < 0)
    {
      //ex_assert(0, "Error in fetchRows");
      return (short)retcode;
    }

  outputBuf_ = NULL;
  inputBuf_ = NULL;
  retcode = prepare(sqlStrBuf, module_, stmt_, sql_src_,
		    input_desc_, output_desc_, &outputBuf_, NULL,
		    &inputBuf_, NULL,NULL,NULL,NULL,NULL,monitorThis);
  if (retcode < 0)
    {
      //ex_assert(0, "Error in fetchRows");
      return (short)retcode;
    }

  if (NOT noExec)
    {
      retcode = exec();
      if (retcode < 0)
	{
	  //ex_assert(0, "Error in fetchRows");
	  return (short)retcode;
	}
    }

  return 0;
}

short ExeCliInterface::fetchRowsEpilogue(const char * sqlStrBuf,
					 NABoolean noClose)
{
  if (NOT noClose)
    close();

  deallocStuff(module_, stmt_, sql_src_, input_desc_, output_desc_);

  if (NOT noClose)
    SQL_EXEC_ClearDiagnostics(NULL);

  return 0;
}

short ExeCliInterface::initializeInfoList(Queue* &infoList,
					  NABoolean infoListIsOutputInfo)
{
  if (infoList)
    {
      infoList->position();
      while (NOT infoList->atEnd())
	{
	  if (infoListIsOutputInfo)
	    {
	      OutputInfo * r = (OutputInfo*)infoList->getCurr();
	      r->dealloc(getHeap());
	    }
	  else
	    {
	      char * c = (char*)infoList->getCurr();
	      NADELETEBASIC(c, getHeap());
	    }

	  infoList->advance();
	}
      NADELETE(infoList, Queue, getHeap());
    }
  
  infoList = new(getHeap()) Queue(getHeap());

  return 0;
}

short ExeCliInterface::fetchAllRows(Queue * &infoList, 
				    const char * query,
				    Lng32 inNumOutputEntries,
				    NABoolean varcharFormat,
				    NABoolean monitorThis,
				    NABoolean initInfoList)
{
  short rc = 0;

  Lng32 numOutputEntries = inNumOutputEntries;

  if (initInfoList)
    {
      rc = initializeInfoList(infoList, TRUE);
      if (rc < 0)
	{
	  return rc;
	}
    }

  rc = fetchRowsPrologue(query,FALSE,monitorThis);
  if (rc < 0)
    {
      return rc;
    }

  NABoolean rowsFound = FALSE;
  while ((rc >= 0) && 
	 (rc != 100))
    {
      rc = (short)fetch();
      if (rc < 0)
	{
	  fetchRowsEpilogue(0, TRUE);

	  return rc;
	}

      if (rc == 100)
	continue;

      rowsFound = TRUE;
      if (numOutputEntries == -1)
      {
	char * ob = new(getHeap()) char[outputDatalen()];
	str_cpy_all(ob, outputBuf(), 
		    outputDatalen());
	
	infoList->insert(ob);
      }
      else
      {
	if (numOutputEntries == 0)
	  numOutputEntries = numOutputEntries_;

	OutputInfo * oi = new(getHeap()) OutputInfo(numOutputEntries);
	
	for (Int32 j = 0; j < numOutputEntries; j++)
	{
	  char * ptr, *r;
	  Lng32   len;
          Lng32   type;
          short nulind=0;
          short *indaddr=&nulind;
          short **ind=&indaddr;
          getAttributes(j+1, FALSE, type, len, NULL, NULL);
	  getPtrAndLen(j+1, ptr, len, ind);
          NABoolean  nullableCol = TRUE, isNullVal = FALSE;
          if(*ind == NULL) // It is not a nullable value
            isNullVal = FALSE; 
          else
          {
            if( ((char*)*ind)[0] == -1 ) // NULL value
              isNullVal = TRUE;
          }
  
          if(isNullVal) 
          {
            oi->insert(j, NULL, 0, type);
          }
          else
          {
	    NABoolean nullTerminate = 
	    DFS2REC::is8bitCharacter(outputAttrs_[j].fsDatatype_);

	    r = new(getHeap()) char
	      [(varcharFormat ? SQL_VARCHAR_HDR_SIZE : 0) 
	       + len + (nullTerminate ? 1 : 0)];
	    if (varcharFormat)
	    {
	      *(short*)r = (short)len;
	      str_cpy_all(&r[SQL_VARCHAR_HDR_SIZE], ptr, len);

	      if (nullTerminate)
	        r[SQL_VARCHAR_HDR_SIZE + len] = 0;
	    }
	    else
	    {
	      str_cpy_all(r, ptr, len);
	      if (nullTerminate)
	        r[len] = 0;
	    }
	    oi->insert(j, r, len, type);
           }
	}
	
	infoList->insert(oi);
      }
    } // while

  rc = fetchRowsEpilogue(0);
  if (rc < 0)
    {
      return rc;
    }
  
  if (NOT rowsFound)
    rc = 100;

  return rc;
}

short ExeCliInterface::clearExecFetchClose(char * inputBuf,
					   Lng32 inputBufLen,

					   // ptr to buf where output values will be copied to. 
					   // Caller need to allocate this.
					   char * outputBuf, 
					   Lng32 * outputBufLen)
{
  Lng32 retcode = 0;

  SQL_EXEC_ClearDiagnostics(NULL);

  retcode = exec(inputBuf, inputBufLen);
  if (retcode < 0)
    {
      return (short)retcode;
    }

  retcode = fetch();
  if (retcode < 0)
    {
      return (short)retcode;
    }

  if ((outputBuf) &&
      (outputBufLen))
    {
      *outputBufLen = 0;
      if (retcode != 100)
	{
	  char * currPtr = outputBuf;
	  for (Int32 j = 0; j < numOutputEntries_; j++)
	    {
	      char * ptr;
	      Lng32   len;
	      getPtrAndLen(j+1, ptr, len);
	      
	      str_cpy_all(currPtr, ptr, len);
	      currPtr += len;

	      *outputBufLen += len;
	    }
	}
    }
  close(); 
  if (retcode == 100)
     fetchRowsEpilogue(NULL, TRUE); 
  return (short)retcode;
}

short ExeCliInterface::clearExecFetchCloseOpt(char * inputBuf,
					      Lng32 inputBufLen,
					      
					      // ptr to buf where output values will be copied to. 
					      // Caller need to allocate this.
					      char * outputBuf, 
					      Lng32 * outputBufLen,
                                              Int64 * rowsAffected)
{
  Lng32 retcode = 0;

  if (inputBuf)
    {
      if (inputDatalen_ < inputBufLen)
        {
          // input data will not fit in inputBuf_.
          // return error.
          return -EXE_STRING_OVERFLOW;
        }

      str_cpy_all(inputBuf_, inputBuf, inputBufLen);
    }

  if (rowsAffected)
    *rowsAffected = 0;

  retcode = SQL_EXEC_ClearExecFetchClose(
					 stmt_, 
					 (numInputEntries_ > 0 ? input_desc_ : NULL),
					 (numOutputEntries_ > 0 ? output_desc_ : NULL),
					 0, 0, 0);
  
  if ((retcode == 0) ||
      ((retcode >= 0) && (retcode != 100)))
    {
      if ((numOutputEntries_ > 0) &&
          (outputBuf) &&
          (outputBufLen))
        {
          *outputBufLen = 0;
          
          char * currPtr = outputBuf;
          for (Int32 j = 0; j < numOutputEntries_; j++)
            {
              char * ptr;
              Lng32   len;
              getPtrAndLen(j+1, ptr, len);
              
              str_cpy_all(currPtr, ptr, len);
              currPtr += len;
              
              *outputBufLen += len;
            }
          
          if (rowsAffected)
            {
              *rowsAffected = 1;
            }
        } // values being returned
      else if (rowsAffected)
        {
          Lng32 tmpRowsAffected = 0;
          retcode = SQL_EXEC_GetDiagnosticsStmtInfo2(NULL, SQLDIAG_ROW_COUNT,
                                                     &tmpRowsAffected, NULL,
                                                     0, NULL);
          
          if(retcode == EXE_NUMERIC_OVERFLOW) // rowsAffected > LONG_MAX
            {
              GetRowsAffected(rowsAffected);
            }
          else
            *rowsAffected = (Int64)tmpRowsAffected;
        } // rowsAffected
    }

  return (short)retcode;
}

Lng32 ExeCliInterface::executeImmediateCEFC(const char * stmtStr,
                                            char * inputBuf,
                                            Lng32 inputBufLen,
                                            char * outputBuf,
                                            Lng32 * outputBufLen,
                                            Int64 * rowsAffected
                                            )
{
  Lng32 retcode = 0;


  clearGlobalDiags();

  outputBuf_ = NULL;
  inputBuf_ = NULL;
  retcode = executeImmediatePrepare(stmtStr, 
				    outputBuf,
				    outputBufLen,
				    rowsAffected);
  if (retcode < 0)
    goto ExecuteImmediateCEFCReturn;
  
  retcode = clearExecFetchCloseOpt(inputBuf, inputBufLen, NULL, NULL, rowsAffected);

ExecuteImmediateCEFCReturn:
  return retcode;
}

Lng32 ExeCliInterface::cwrsAllocStuff(SQLMODULE_ID * &module,
					SQLSTMT_ID * &stmt,
					SQLDESC_ID * &sql_src,
					SQLDESC_ID * &input_desc,
					SQLDESC_ID * &output_desc,
					SQLDESC_ID * &rs_input_maxsize_desc,
					const char * stmtName
  )
{
  Lng32 retcode = 0;

  retcode = cwrsDeallocStuff(module,
			       stmt,
			       sql_src,
			       input_desc,
			       output_desc,
			       rs_input_maxsize_desc);
  if (retcode < 0)
    {
      return (short)retcode;
    }

  retcode = allocStuff(module,
		       stmt,
		       sql_src,
		       input_desc,
		       output_desc);
  if (retcode < 0)
    {
      return (short)retcode;
    }

  // Allocate a descriptor to set input array maximum size
  rs_input_maxsize_desc = new(heap_) SQLSTMT_ID;
  init_SQLDESC_ID(rs_input_maxsize_desc, SQLCLI_CURRENT_VERSION, desc_handle, module);

  retcode = SQL_EXEC_AllocDesc(rs_input_maxsize_desc, 1);
  if (retcode < 0)
    return retcode;

  retcode = SQL_EXEC_SetDescItem(rs_input_maxsize_desc, 1, SQLDESC_TYPE,
				 SQLTYPECODE_INTEGER, NULL);
  if (retcode < 0)
    return retcode;

  retcode = SQL_EXEC_SetDescItem( rs_input_maxsize_desc,
				  1,  // entry #1, attr value.
				  SQLDESC_VAR_PTR, // what to set - host var addr
				  (long) &rsMaxsize_,  // Notice that output from CLI
				                // will be read from host var
                        			// rowset_size.
				  NULL);

  retcode = SQL_EXEC_SetStmtAttr(stmt,
                                 SQL_ATTR_INPUT_ARRAY_MAXSIZE,
                                 rsMaxsize_,
				 NULL);

  return retcode;
}
  
Lng32 ExeCliInterface::cwrsDeallocStuff(
  SQLMODULE_ID * &module,
  SQLSTMT_ID * &stmt,
  SQLDESC_ID * &sql_src,
  SQLDESC_ID * &input_desc,
  SQLDESC_ID * &output_desc,
  SQLDESC_ID * &rs_input_maxsize_desc)
{
  deallocStuff(module, stmt, sql_src, input_desc, output_desc);

  if (rs_input_maxsize_desc)
    {
      SQL_EXEC_DeallocDesc(rs_input_maxsize_desc);
      NADELETEBASIC(rs_input_maxsize_desc, heap_);
      rs_input_maxsize_desc = NULL;
    }

  return 0;
}
  
Lng32 ExeCliInterface::cwrsPrepare(const char * stmtStr,
				   Lng32 rs_maxsize, NABoolean monitorThis)
{
  Lng32 retcode = 0;

  rsMaxsize_ = rs_maxsize;
  retcode = cwrsAllocStuff(module_, stmt_, sql_src_, 
			     input_desc_, output_desc_,
                             rs_input_maxsize_desc_);
  if (retcode != SUCCESS)
    return retcode;

  retcode = prepare(stmtStr, module_, stmt_, sql_src_, 
		    input_desc_, output_desc_, NULL,NULL,NULL,NULL,
		    NULL,NULL,NULL,NULL,monitorThis);
  if (retcode < 0)
    {
      cwrsDeallocStuff(module_, stmt_, sql_src_, 
			 input_desc_, output_desc_,
			 rs_input_maxsize_desc_);
      return retcode;
    }
  
  numQuadFields_ = numInputEntries_;// + 1;
  quadFields_ = (SQLCLI_QUAD_FIELDS*)
    new (heap_) char[sizeof(SQLCLI_QUAD_FIELDS) * numQuadFields_];
  
  rsInputBuffer_ = new(heap_) char[rsMaxsize_ * inputDatalen_];

  Lng32 fsDatatype;
  Lng32 length;
  Lng32 indOffset = 0;
  Lng32 varOffset = 0;

  quadFields_[0].var_layout = 0;
  quadFields_[0].var_ptr = (void *)&currRSrow_;
  quadFields_[0].ind_layout = 0;
  quadFields_[0].ind_ptr = NULL; 

  Lng32 currOffset = 0;
  for (Lng32 entry = 2; entry <= numInputEntries_; entry++)
    {
      getAttributes(entry, TRUE,
		    fsDatatype, length,
		    &indOffset, &varOffset);
 
      quadFields_[entry-1].var_layout = length;
      quadFields_[entry-1].var_ptr = (void*)&rsInputBuffer_[currOffset];
      quadFields_[entry-1].ind_layout = 0;
      quadFields_[entry-1].ind_ptr = NULL;
      
      currOffset += length * rsMaxsize_;
    }

  currRSrow_ = 0;

  return 0;
}

Lng32 ExeCliInterface::cwrsExec(
  char * inputRow,
  Int32 inputRowLen,
  Int64 * rowsAffected)
{
  Lng32 retcode = 0;

  Int32    rowset_status[1];    // Has no functionality currently. 
                                //However it is part of RowsetSetDesc API

  if ((inputRow) && (currRSrow_ < rsMaxsize_))
    {
      Lng32 fsDatatype;
      Lng32 length;
      Lng32 indOffset = 0;
      Lng32 varOffset = 0;
      
      for (Lng32 entry = 2; entry <= numInputEntries_; entry++)
        {
	  getAttributes(entry, TRUE,
			fsDatatype, length,
			&indOffset, &varOffset);
	  
	  str_cpy_all((char*)((long)(quadFields_[entry-1].var_ptr) + 
			      currRSrow_*length),
		      &inputRow[varOffset], length);
	}

      currRSrow_++;
      return 0;
    }

  if ((inputRow == NULL) && (currRSrow_ == 0))
    return 0;

  retcode = SQL_EXEC_SETROWSETDESCPOINTERS(input_desc_,
                                           currRSrow_,
                                           rowset_status,
                                           1,
                                           numQuadFields_,
                                           quadFields_);
  if (retcode < 0)
    return retcode;

  retcode = exec();
  if (retcode < 0)
    return retcode;

  retcode = fetch();
  if (retcode < 0)
    return retcode;

  if (retcode >= 0)
  {
    if (rowsAffected)
    {
      Lng32 tmpRowsAffected = 0;
      retcode = SQL_EXEC_GetDiagnosticsStmtInfo2(NULL, SQLDIAG_ROW_COUNT,
        &tmpRowsAffected, NULL,
        0, NULL);

      if(retcode == EXE_NUMERIC_OVERFLOW) // rowsAffected > LONG_MAX
      {
        GetRowsAffected(rowsAffected);
      }
      else
        *rowsAffected = (Int64)tmpRowsAffected;

      retcode = 0;
    }
  }

  retcode = close();

  currRSrow_ = 0;

  // current input row has not been moved to the rowset buffer.
  // move the input row to the rowset buffer
  return cwrsExec(inputRow, inputRowLen, rowsAffected);
}

Lng32 ExeCliInterface::cwrsClose(Int64 * rowsAffected)
{
  Lng32 retcode = 0;

  if (rowsAffected)
    *rowsAffected = 0;

  retcode = cwrsExec(NULL, 0, rowsAffected);

  Lng32 retcode2 = cwrsDeallocStuff(module_, stmt_, sql_src_, 
                                    input_desc_, output_desc_,
                                    rs_input_maxsize_desc_);
  return retcode;
}

Lng32 ExeCliInterface::rwrsPrepare(const char * stmtStr, Lng32 rs_maxsize,NABoolean monitorThis)
{
  Lng32 retcode = 0;

  rsMaxsize_ = rs_maxsize;
  retcode = allocStuff(module_, stmt_, sql_src_, 
		       input_desc_, output_desc_);
  if (retcode != SUCCESS)
    return retcode;

  /*
  retcode = SQL_EXEC_SetStmtAttr(stmt_,
                                 SQL_ATTR_INPUT_ARRAY_MAXSIZE,
                                 rsMaxsize_,
				 NULL);
  if (retcode != SUCCESS)
    return retcode;
  */

  retcode = prepare(stmtStr, module_, stmt_, sql_src_, 
		    input_desc_, output_desc_, NULL,NULL,NULL,NULL,NULL,
		    NULL,NULL,NULL,monitorThis);
  if (retcode < 0)
    {
      deallocStuff(module_, stmt_, sql_src_, 
		   input_desc_, output_desc_);
      return retcode;
    }
  
  rsInputBuffer_ = new(heap_) char[rsMaxsize_ * inputDatalen_];

  retcode = SQL_EXEC_SetDescItem(input_desc_,0,SQLDESC_ROWSET_TYPE, 3, 0);
  
  retcode = SQL_EXEC_SetDescItem(input_desc_,0,SQLDESC_ROWWISE_ROWSET_PTR, 
				 (long)rsInputBuffer_, 0);

  retcode = SQL_EXEC_SetDescItem(input_desc_,0,SQLDESC_ROWWISE_ROWSET_ROW_LEN, 
				 inputDatalen_, 0);

  currRSrow_ = 0;

  return 0;
}

Lng32 ExeCliInterface::rwrsExec(
  char * inputRow,
  Int32 inputRowLen,
  Int64 * rowsAffected)
{
  Lng32 retcode = 0;

  clearGlobalDiags();

  if (rowsAffected)
    *rowsAffected = 0;

  if ((inputRow) && (currRSrow_ < rsMaxsize_))
    {
      str_cpy_all(&rsInputBuffer_[currRSrow_ * inputDatalen_], 
		  inputRow, inputRowLen);
      currRSrow_++;
      return 0;
    }

  if ((inputRow == NULL) && (currRSrow_ == 0))
    return 0;

  retcode = SQL_EXEC_SetDescItem(input_desc_, 0, SQLDESC_ROWWISE_ROWSET_SIZE, 
				 currRSrow_, 0);

  retcode = exec();
  if (retcode < 0)
    return retcode;

  retcode = fetch();
  if (retcode < 0)
    return retcode;

  Lng32 cliRetcode = -1;
  if (retcode >= 0)
  {
    cliRetcode = retcode;
    if (rowsAffected)
    {
      Lng32 tmpRowsAffected = 0;
      retcode = SQL_EXEC_GetDiagnosticsStmtInfo2(NULL, SQLDIAG_ROW_COUNT,
        &tmpRowsAffected, NULL,
        0, NULL);

      if(retcode == EXE_NUMERIC_OVERFLOW) // rowsAffected > LONG_MAX
      {
        GetRowsAffected(rowsAffected);
      }
      else
        *rowsAffected = (Int64)tmpRowsAffected;

      retcode = 0;
    }
  }

  currRSrow_ = 0;

  return retcode;
}

Lng32 ExeCliInterface::rwrsClose()
{
  Lng32 retcode = 0;

  retcode = rwrsExec(NULL, 0, NULL);

  close();

  deallocStuff(module_, stmt_, sql_src_, 
	       input_desc_, output_desc_);

  return retcode;
}

short ExeCliInterface::prepareAndExecRowsPrologue(const char * sqlInitialStrBuf,
                                                  char * sqlSecondaryStrBuf,
                                                  Queue* initialOutputVarPtrList,
                                                  Queue* secondaryOutputVarPtrList,
                                                  Int64   &rowsAffected,
						  NABoolean monitorThis)
{
  Lng32 retcode = 0;
  
  SQL_EXEC_ClearDiagnostics(NULL);
  retcode = allocStuff(module_, stmt_, sql_src_, input_desc_, output_desc_);
  if (retcode < 0)
    return (short)retcode;

  // Prepare
  outputBuf_ = NULL;
  inputBuf_ = NULL;
  retcode = prepare(sqlInitialStrBuf, module_, stmt_, sql_src_,
		    input_desc_, output_desc_, &outputBuf_,
                    initialOutputVarPtrList, NULL,NULL,NULL,NULL,
		    NULL,NULL,monitorThis);
  if (retcode < 0)
    return (short)retcode;
  
  retcode = allocStuff(moduleWithCK_, stmtWithCK_, sql_src_withCK_,
                      input_desc_withCK_, output_desc_withCK_);
  if (retcode < 0)
    return (short)retcode;
  
  // Prepare
  outputBuf_withCK_ = NULL;
  retcode = prepare(sqlSecondaryStrBuf, moduleWithCK_, stmtWithCK_, sql_src_withCK_,
		    input_desc_withCK_, output_desc_withCK_, &outputBuf_withCK_,
		    secondaryOutputVarPtrList,NULL,NULL,NULL,NULL,
		    NULL,NULL,monitorThis);
  if (retcode < 0)
    return (short)retcode;
  
  // Ensure the input entries have the correct character set type
  retcode = setCharsetTypes();
  if (retcode < 0)
    return (short)retcode;
   
  retcode = SQL_EXEC_Exec(stmt_, input_desc_, 0);
  if (retcode < 0)
    return (short)retcode;
  
  Lng32 cliRetcode = -1;
  retcode = SQL_EXEC_Fetch(stmt_, output_desc_, 0);
  if (retcode < 0)
    return (short)retcode;
  
  if (retcode >=  0) // we continue for warnings (retcode > 0)
                     // and NO errors or warnings (retcode == 0)
  {
    cliRetcode = retcode; // save the retcode from cli fetch.
    setOutputPtrsAsInputPtrs(initialOutputVarPtrList, 0);

    Int64 tmpRowsAffected = 0;
    retcode = SQL_EXEC_GetDiagnosticsStmtInfo2(NULL, SQLDIAG_ROW_COUNT,
      &tmpRowsAffected, NULL,
      0, NULL);

    if(retcode == EXE_NUMERIC_OVERFLOW) // rowsAffected > LONG_MAX
    {
      GetRowsAffected(&rowsAffected);
    }
    else
      rowsAffected = tmpRowsAffected;
  }
  
  SQL_EXEC_ClearDiagnostics(NULL);
  
  retcode = SQL_EXEC_CloseStmt(stmt_);
  if (retcode < 0)
    return (short)retcode;
  
  // return the return code from the cli fetch if it succeded.
  if (cliRetcode != -1) 
    return (short) cliRetcode;
  else
    return (short) retcode;
}

short ExeCliInterface::execContinuingRows(Queue * continuingOutputVarPtrList,
                                          Int64   &rowsAffected)
{
  Lng32 retcode = 0;

  SQL_EXEC_ClearDiagnostics(NULL);
 
  retcode = SQL_EXEC_Exec(stmtWithCK_, input_desc_withCK_, 0);
  if (retcode < 0)
      return (short)retcode;

  Lng32 cliRetcode = -1;
  retcode = SQL_EXEC_Fetch(stmtWithCK_, output_desc_withCK_, 0);
  if (retcode < 0)
      return (short)retcode;

  if (retcode >= 0)
  {
    cliRetcode = retcode; // save the retcode from cli fetch.
    setOutputPtrsAsInputPtrs(continuingOutputVarPtrList, 0);

    Int64 tmpRowsAffected = 0;
    retcode = SQL_EXEC_GetDiagnosticsStmtInfo2(NULL, SQLDIAG_ROW_COUNT,
      &tmpRowsAffected, NULL,
      0, NULL);

    if(retcode == EXE_NUMERIC_OVERFLOW) // rowsAffected > LONG_MAX
    {
      GetRowsAffected(&rowsAffected);
    }
    else
      rowsAffected = tmpRowsAffected;
  }

  retcode = SQL_EXEC_CloseStmt(stmtWithCK_);
  if (retcode < 0)
      return (short)retcode;

  // return the return code from the cli fetch if it succeded.
  if (cliRetcode != -1) 
    return (short) cliRetcode;
  else
    return (short) retcode;
}

Lng32 ExeCliInterface::setCharsetTypes()
{
  Lng32 retcode = 0;
  Lng32 num_input_entries = 0;

  // Obtain the number of entries
  retcode = SQL_EXEC_GetDescEntryCount(input_desc_withCK_, &num_input_entries);

  if (retcode < 0)
    return (short)retcode;

  Lng32 data_charset = 0;

  for (Lng32 i = 1; i <= num_input_entries; i++)
  {
  
    retcode = SQL_EXEC_GetDescItem(output_desc_withCK_,
                                   i,
     			           SQLDESC_CHAR_SET,
				   &data_charset, 0, 0, 0, 0);
    if (retcode < 0)
      return (short)retcode;

    if (data_charset != SQLCHARSETCODE_UNKNOWN)  
      {
         retcode = SQL_EXEC_SetDescItem(input_desc_withCK_,
                                        i,
     			                SQLDESC_CHAR_SET,
				        data_charset, 0);
         if (retcode < 0)
	   return (short)retcode;
       }
   }

   return (short)retcode;
}

void ExeCliInterface::setOutputPtrsAsInputPtrs(Queue* outputVarPtrList,
                                                SQLDESC_ID * target_inputDesc)
{
    // Process the queue
    Int32 j = 1;
    outputVarPtrList->position();

    while (NOT outputVarPtrList->atEnd())
      {
        char * entry = (char*)outputVarPtrList->getCurr();
        SQL_EXEC_SetDescItem(input_desc_withCK_, j++,
                             SQLDESC_VAR_PTR, 
                             (Long)entry, 0);

        outputVarPtrList->advance();
      }

    return;
}

Lng32 ExeCliInterface::prepareAndExecRowsEpilogue()
{
  Lng32 retcode = 0;

  retcode = close();

  deallocStuff(module_, stmt_, sql_src_, input_desc_, output_desc_);

  if (stmtWithCK_)
    {
      retcode = SQL_EXEC_CloseStmt(stmtWithCK_);
    }

  deallocStuff(moduleWithCK_, stmtWithCK_,
               sql_src_withCK_, input_desc_withCK_, output_desc_withCK_);

  SQL_EXEC_ClearDiagnostics(NULL);

  return 0;
}

Lng32 ExeCliInterface::beginWork()
{
  return executeImmediate("begin work;");
}

Lng32 ExeCliInterface::commitWork()
{
  return executeImmediate("commit work waited;");
}

Lng32 ExeCliInterface::rollbackWork()
{
  return executeImmediate("rollback work;");
}

Lng32 ExeCliInterface::autoCommit(NABoolean v)
{
  if (v)
    return executeImmediate("set transaction autocommit ON;");
  else
    return executeImmediate("set transaction autocommit OFF;");
}

Lng32 ExeCliInterface::beginXn()
{
  return SQL_EXEC_Xact(SQLTRANS_BEGIN, 0);
}

Lng32 ExeCliInterface::commitXn()
{
  return SQL_EXEC_Xact(SQLTRANS_COMMIT, 0);
}

Lng32 ExeCliInterface::rollbackXn()
{
  return SQL_EXEC_Xact(SQLTRANS_ROLLBACK, 0);
}

Lng32 ExeCliInterface::statusXn()
{
  return SQL_EXEC_Xact(SQLTRANS_STATUS, NULL);
}

Lng32 ExeCliInterface::suspendXn()
{
  return SQL_EXEC_Xact(SQLTRANS_SUSPEND, 0);
}

Lng32 ExeCliInterface::resumeXn()
{
  return SQL_EXEC_Xact(SQLTRANS_RESUME, 0);
}

Lng32 ExeCliInterface::createContext(char * contextHandle)
{
  Lng32 rc = 0;
  rc = SQL_EXEC_CreateContext((SQLCTX_HANDLE*)contextHandle, NULL, FALSE);
  return rc;
}

Lng32 ExeCliInterface::switchContext(char * contextHandle)
{
  Lng32 rc = 0;
  rc = SQL_EXEC_SwitchContext(*(SQLCTX_HANDLE*)contextHandle, NULL);
  return rc;
}

Lng32 ExeCliInterface::currentContext(char * contextHandle)
{
  Lng32 rc = 0;
  rc = SQL_EXEC_CurrentContext((SQLCTX_HANDLE*)contextHandle);
  return rc;
}

Lng32 ExeCliInterface::deleteContext(char* contextHandle) // in buf contains context handle
{
  return SQL_EXEC_DeleteContext(*(SQLCTX_HANDLE*)contextHandle);
}

Lng32 ExeCliInterface::retrieveSQLDiagnostics(ComDiagsArea *toDiags)
{
  Lng32 retcode;
  ex_assert(toDiags != NULL, "ComDiagsArea is null");
  retcode = SQL_EXEC_MergeDiagnostics_Internal(*toDiags);
  SQL_EXEC_ClearDiagnostics(NULL);
  return retcode;
}


ComDiagsArea *ExeCliInterface::allocAndRetrieveSQLDiagnostics(ComDiagsArea *&toDiags)
{
  Lng32 retcode;
  NABoolean daAllocated = FALSE; 
  if (toDiags == NULL) { 
      toDiags = ComDiagsArea::allocate(heap_);
      daAllocated = TRUE;
  }

  retcode = SQL_EXEC_MergeDiagnostics_Internal(*toDiags);
  SQL_EXEC_ClearDiagnostics(NULL);
 
  if (retcode == 0)
     return toDiags;
  else {
     if (daAllocated)
        toDiags->decrRefCount();
     return NULL;
  }
}

Lng32 ExeCliInterface::GetRowsAffected(Int64 *rowsAffected)
{
	SQLDESC_ID *rowCountDesc = NULL;
	SQLMODULE_ID * module = NULL;

	Lng32 retcode = SUCCESS;
	NABoolean sqlWarning = FALSE;

	SQLDIAG_STMT_INFO_ITEM_ID sqlItem = SQLDIAG_ROW_COUNT;
	rowCountDesc = new(heap_) SQLDESC_ID;
	rowCountDesc->version = SQLCLI_CURRENT_VERSION;
	rowCountDesc->name_mode = desc_handle;
	module = new(heap_) SQLMODULE_ID;
	rowCountDesc->module = module;
	module->module_name = 0;
	module->charset = "ISO88591";
	module->module_name_len = 0;
	module->version = SQLCLI_CURRENT_VERSION;
	rowCountDesc->identifier = 0;
	rowCountDesc->handle = 0;
  
	// get number of rows affected
  
	retcode = SQL_EXEC_AllocDesc (rowCountDesc, 1);
 	retcode = SQL_EXEC_SetDescItem(rowCountDesc, 1,
					 SQLDESC_TYPE_FS, REC_BIN64_SIGNED, 0);
	retcode = SQL_EXEC_SetDescItem(rowCountDesc, 1,
					 SQLDESC_VAR_PTR, (Long)rowsAffected, 0);

	Lng32 *temp;
	temp = (Lng32 *) &sqlItem;
  
	retcode = SQL_EXEC_GetDiagnosticsStmtInfo(temp, rowCountDesc);

  // free up resources
	SQL_EXEC_DeallocDesc(rowCountDesc);

	return SUCCESS;

} // GetRowsAffected()

Lng32 ExeCliInterface::holdAndSetCQD(const char * defaultName, const char * defaultValue, ComDiagsArea *globalDiags)
{
  Lng32 cliRC;
  
  char buf[400];
  
  strcpy(buf, "control query default ");
  strcat(buf, defaultName);
  strcat(buf, " hold;");

  // hold the current value for defaultName
  cliRC = executeImmediate(buf, NULL, NULL, TRUE, NULL, 0,&globalDiags);
  if (cliRC < 0)
    {
      return cliRC;
    }

  // now set the new value for defaultName
  strcpy(buf, "control query default ");
  strcat(buf, defaultName);
  strcat(buf, " '");
  strcat(buf, defaultValue);
  strcat(buf, "';");
  cliRC = executeImmediate(buf, NULL, NULL, TRUE, NULL, 0,&globalDiags);
  if (cliRC < 0)
    {
      return cliRC;
    }

  return 0;
}


Lng32 ExeCliInterface::restoreCQD(const char * defaultName, ComDiagsArea *globalDiags)
{
  Lng32 cliRC;

  char buf[400];
  
  // remove this cqd from the cqd array
  strcpy(buf, "control query default ");
  strcat(buf, defaultName);
  strcat(buf, " reset;");
  cliRC = executeImmediate(buf, NULL, NULL, TRUE, NULL, 0,&globalDiags);
  if (cliRC < 0)
    {
      return cliRC;
    }

  // restore the saved cqd default value
  strcpy(buf, "control query default ");
  strcat(buf, defaultName);
  strcat(buf, " restore;");
  cliRC = executeImmediate(buf, NULL, NULL, TRUE, NULL, 0,&globalDiags);
  if (cliRC < 0)
    {
      return cliRC;
    }

  return 0;
}

Lng32 ExeCliInterface::getCQDval(const char * defaultName, 
				 char * val,
				 ComDiagsArea *globalDiags)

{
  Lng32 cliRC;

  char buf[400];
  
  strcpy(buf, "cqd showcontrol_show_all 'ON';");
  cliRC = executeImmediate(buf);
  if (cliRC < 0)
    {
      return cliRC;
    }

  char valBuf[4000];
  Lng32 valBufLen = 0;
  strcpy(buf, "showcontrol default ");
  strcat(buf, defaultName);
  strcat(buf, ", match full, no header;");

  cliRC = executeImmediate(buf, valBuf, &valBufLen);
  if (cliRC < 0)
    {
      strcpy(buf, "cqd showcontrol_show_all 'OFF';");
      executeImmediate(buf);

      return cliRC;
    }

  strcpy(val, valBuf);

  strcpy(buf, "cqd showcontrol_show_all 'OFF';");
  cliRC = executeImmediate(buf);

  return 0;
}

Lng32 ExeCliInterface::setCQS(const char * shape, ComDiagsArea *globalDiags)
{
  Lng32 cliRC;

  cliRC = executeImmediate(shape, NULL, NULL, TRUE, NULL, 0,&globalDiags);
  if (cliRC < 0)
    {
      return cliRC;
    }

  return 0;
}
  

Lng32 ExeCliInterface::resetCQS(ComDiagsArea * globalDiags)
{
  Lng32 cliRC;

  char buf[400];
  
  strcpy(buf, "control query shape cut ");
  cliRC = executeImmediate(buf, NULL, NULL, TRUE, NULL, 0,&globalDiags);
  if (cliRC < 0)
    {
      return cliRC;
    }

  return 0;
}
  
  
// methods for routine invocation

Lng32 ExeCliInterface::getRoutine(
     /* 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,
     /* IN/OUT */ ComDiagsArea *diags)
{
  Lng32 retcode = 0;

  SQL_EXEC_ClearDiagnostics(NULL);

  retcode = SQL_EXEC_GetRoutine(
       serializedInvocationInfo,
       invocationInfoLen,
       serializedPlanInfo,
       planInfoLen,
       language,
       paramStyle,
       externalName,
       containerName,
       externalPath,
       librarySqlName,
       handle);

  if (retcode != 0 && diags)
    {
      SQL_EXEC_MergeDiagnostics_Internal(*diags);
      SQL_EXEC_ClearDiagnostics(NULL);
    }

  return retcode;
}

Lng32 ExeCliInterface::invokeRoutine(
     /* 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,
     /* IN/OUT */ ComDiagsArea *diags)
{
  Lng32 retcode = 0;

  SQL_EXEC_ClearDiagnostics(NULL);

  retcode = SQL_EXEC_InvokeRoutine(
       handle,
       phaseEnumAsInt,
       serializedInvocationInfo,
       invocationInfoLen,
       invocationInfoLenOut,
       serializedPlanInfo,
       planInfoLen,
       planNum,
       planInfoLenOut,
       inputRow,
       inputRowLen,
       outputRow,
       outputRowLen);

  if (retcode != 0 && diags)
    {
      SQL_EXEC_MergeDiagnostics_Internal(*diags);
      SQL_EXEC_ClearDiagnostics(NULL);
    }

  return retcode;
}

Lng32 ExeCliInterface::getRoutineInvocationInfo(
     /* 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,
     /* IN/OUT */ ComDiagsArea *diags)
{
  Lng32 retcode = 0;

  SQL_EXEC_ClearDiagnostics(NULL);

  retcode = SQL_EXEC_GetRoutineInvocationInfo(
       handle,
       serializedInvocationInfo,
       invocationInfoMaxLen,
       invocationInfoLenOut,
       serializedPlanInfo,
       planInfoMaxLen,
       planNum,
       planInfoLenOut);

  if (retcode != 0 && diags)
    {
      SQL_EXEC_MergeDiagnostics_Internal(*diags);
      SQL_EXEC_ClearDiagnostics(NULL);
    }

  return retcode;
}

Lng32 ExeCliInterface::putRoutine(
     /* IN */     Int32         handle,
     /* IN/OUT */ ComDiagsArea *diags)
{
  Lng32 retcode = 0;

  SQL_EXEC_ClearDiagnostics(NULL);

  retcode = SQL_EXEC_PutRoutine(
       handle);

  if (retcode != 0 && diags)
    {
      SQL_EXEC_MergeDiagnostics_Internal(*diags);
      SQL_EXEC_ClearDiagnostics(NULL);
    }

  return retcode;
}
