/**********************************************************************
// @@@ 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:         SqlciCmd.C
 * Description:
 *
 * Created:      4/15/95
 * Language:     C++
 *
 *
 *
 *
 *****************************************************************************
 */

#include <errno.h>
#include <iostream>
#include <sstream>
#include <stdio.h>
#include <limits.h>
#include <ctype.h>
#include <stdlib.h>
#include <wchar.h>

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

#include "ComCextdecs.h"
#include "ComDiags.h"
#include "ComSmallDefs.h"
#include "ErrorMessage.h"
#include "GetErrorMessage.h"
#include "InputStmt.h"
#include "SqlciError.h"
#include "SqlciCmd.h"
#include "sqlcmd.h"
#include "ShellCmd.h"
#include "SqlciError.h"
#include "SqlciParser.h"
#include "str.h"
#include "charinfo.h"
#include "SqlciEnv.h"
#include "Sqlci.h"
#include "sql_id.h"
#include "ComRtUtils.h"
#include "ComUser.h"

extern ComDiagsArea sqlci_DA;

SqlciCmd::SqlciCmd(const sqlci_cmd_type cmd_type_)
                  : SqlciNode(SqlciNode::SQLCI_CMD_TYPE),
		    cmd_type(cmd_type_)
{
  arglen = 0;
  argument = 0;
}

SqlciCmd::SqlciCmd(const sqlci_cmd_type cmd_type_, char * argument_, Lng32 arglen_)
                  : SqlciNode(SqlciNode::SQLCI_CMD_TYPE),
		    cmd_type(cmd_type_)
{
  arglen = arglen_;

  if (argument_)
    {
      argument = new char[arglen_ + 1]; 
      strncpy(argument, argument_,arglen_);
      argument[arglen] = 0;
    }
  else
    {
      argument = 0;
    }
};

SqlciCmd::SqlciCmd(const sqlci_cmd_type cmd_type_, NAWchar * argument_, Lng32 arglen_)
                  : SqlciNode(SqlciNode::SQLCI_CMD_TYPE),
		    cmd_type(cmd_type_)
{
  arglen = 2*arglen_;

  if (argument_)
    {
      NAWchar* tgt = new NAWchar[arglen_ + 1]; // extra byte for NAWchar typed argument
      NAWstrncpy(tgt, argument_,arglen_);
      tgt[arglen_] = 0;
      argument = (char*) tgt;
    }
  else
    {
      argument = 0;
    }
};

SqlciCmd::SqlciCmd(const sqlci_cmd_type cmd_type_, Int32 argument_)
                  : SqlciNode(SqlciNode::SQLCI_CMD_TYPE),
		    cmd_type(cmd_type_)
{
  numeric_arg = argument_;
  argument = 0;
};

SqlciCmd::~SqlciCmd()
{
  delete [] argument;
};

FixCommand::FixCommand(char * argument_, Lng32 arglen_)
                 : SqlciCmd(SqlciCmd::FC_TYPE, argument_, arglen_)
{
  cmd = argument_;
};

FixCommand::FixCommand(Int32 argument_, short neg_num_)
                 : SqlciCmd(SqlciCmd::FC_TYPE, argument_)
{
  cmd_num = argument_;
  neg_num = neg_num_;
  cmd = 0;
};

Obey::Obey(char * argument_, Lng32 arglen_, char * section_name_)
                 : SqlciCmd(SqlciCmd::OBEY_TYPE, argument_, arglen_)
{
  if (section_name_)
    {
      section_name = new char[strlen(section_name_)+1];
      strcpy (section_name, section_name_);
    }
  else
    {
      section_name = 0;
    }
};

Log::Log(char * argument_, Lng32 arglen_, log_type type_, Int32 commands_only)
                 : SqlciCmd(SqlciCmd::LOG_TYPE, argument_, arglen_),
		   type(type_), commandsOnly_(commands_only)
{
};

Shape::Shape(NABoolean type, char * infile, char * outfile)
  : SqlciCmd(SqlciCmd::SHAPE_TYPE),
    type_(type), infile_(infile), outfile_(outfile)
{
};

Statistics::Statistics(char * argument_, Lng32 arglen_,StatsCmdType type, 
		       char * statsOptions)
  : SqlciCmd(SqlciCmd::STATISTICS_TYPE, argument_, arglen_),
    type_(type)
{
    if (statsOptions)
    {
      statsOptions_ = new char[strlen(statsOptions)+1];
      strcpy (statsOptions_, statsOptions);
    }
  else
    {
      statsOptions_ = NULL;
    }
};

Statistics::~Statistics()
{
  if (statsOptions_)
    delete [] statsOptions_;
};

QueryId::QueryId(char * argument_, Lng32 arglen_, 
                 NABoolean isSet, char * qidVal)
  : SqlciCmd(SqlciCmd::QUERYID_TYPE, argument_, arglen_),
    isSet_(isSet), qidVal_(NULL)
{
  if ((isSet_) && (qidVal))
    {
      qidVal_ = new char[strlen(qidVal) + 1];
      strcpy(qidVal_, qidVal);
    }
};

QueryId::~QueryId()
{
  if (qidVal_)
    delete qidVal_;
}

History::History(char * argument_, Lng32 arglen_)
                 : SqlciCmd(SqlciCmd::HISTORY_TYPE, argument_, arglen_)
{
};

ListCount::ListCount(char * argument_, Lng32 arglen_)
                 : SqlciCmd(SqlciCmd::LISTCOUNT_TYPE, argument_, arglen_)
{
};

Mode::Mode(ModeType type_, NABoolean value)
                 : SqlciCmd(SqlciCmd::MODE_TYPE),
				   value(value)
{
	type = type_;
};


Verbose::Verbose(char * argument_, Lng32 arglen_, VerboseCmdType type)
                 : SqlciCmd(SqlciCmd::VERBOSE_TYPE, argument_, arglen_),
                   type_(type)
{
};

ParserFlags::ParserFlags(ParserFlagsOperation opType_, Int32 param_)
                 : SqlciCmd(SqlciCmd::PARSERFLAGS_TYPE, param_)
{
  opType = opType_;
  param  = param_;
};

Error::Error(char * argument_, Lng32 arglen_, error_type type_)
             : SqlciCmd(SqlciCmd::ERROR_TYPE, argument_, arglen_)
{
  type = type_;
};

FCRepeat::FCRepeat(char * argument_, Lng32 arglen_)
                 : SqlciCmd(SqlciCmd::REPEAT_TYPE, argument_, arglen_)
{
  cmd = argument_;
};

FCRepeat::FCRepeat(Int32 argument_, short neg_num_)
                 : SqlciCmd(SqlciCmd::REPEAT_TYPE, argument_)
{
  cmd_num = argument_;
  neg_num = neg_num_;
  cmd = 0;
};

Exit::Exit(char * argument_, Lng32 arglen_)
                 : SqlciCmd(SqlciCmd::EXIT_TYPE, argument_, arglen_)
{
};

Reset::Reset(reset_type type_, char * argument_, Lng32 arglen_)
: SqlciCmd(SqlciCmd::SETPARAM_TYPE, argument_, arglen_),
  type(type_)
{
};

Reset::Reset(reset_type type_)
: SqlciCmd(SqlciCmd::SETPARAM_TYPE),
  type(type_)
{
};

SetParam::SetParam(char * param_name_, Lng32 namelen_, char * argument_, Lng32 arglen_, CharInfo::CharSet x)
                 : SqlciCmd(SqlciCmd::SETPARAM_TYPE, argument_, arglen_), 
                   cs(x), inSingleByteForm_(TRUE),
                   m_convUTF16ParamStrLit(NULL),
                   isQuotedStrWithoutCharSetPrefix_(FALSE),
                   m_termCS(CharInfo::UnknownCharSet)
{
  if (param_name_)
    {
      param_name = new char[namelen_+1];
      strcpy (param_name, param_name_);
      namelen = namelen_;
    }
  else
    {
      param_name = 0;
      namelen = 0;
    }
};

SetParam::SetParam(char * param_name_, Lng32 namelen_, NAWchar * argument_, Lng32 arglen_, CharInfo::CharSet x)
                 : SqlciCmd(SqlciCmd::SETPARAM_TYPE, argument_, arglen_), 
                   cs(x), inSingleByteForm_(FALSE),
                   m_convUTF16ParamStrLit(NULL),
                   isQuotedStrWithoutCharSetPrefix_(FALSE),
                   m_termCS(CharInfo::UnknownCharSet)
{
  if (param_name_)
    {
      param_name = new char[namelen_+1];
      strcpy (param_name, param_name_);
      namelen = namelen_;
    }
  else
    {
      param_name = 0;
      namelen = 0;
    }
};

SetPattern::SetPattern(char * pattern_name_, Lng32 namelen_, char * argument_, Lng32 arglen_)
                 : SqlciCmd(SqlciCmd::SETPATTERN_TYPE, argument_, arglen_)
{
  if (pattern_name_)
    {
      pattern_name = new char[namelen_+1];
      strcpy (pattern_name, pattern_name_);
      namelen = namelen_;
    }
  else
    {
      pattern_name = 0;
      namelen = 0;
    }
};

short SetTerminalCharset::process(SqlciEnv * sqlci_env)
{
  HandleCLIErrorInit();

  char* tcs = get_argument();
  Int32 tcs_len;

  if ( tcs != NULL && ((tcs_len=strlen(tcs)) <= 128) )
  {
     char tcs_uppercase[129];
     str_cpy_convert(tcs_uppercase, tcs, tcs_len, 1);
     tcs_uppercase[tcs_len] = 0;

     if ( CharInfo::isCharSetSupported(tcs_uppercase) == FALSE )
     {
      SqlciError (SQLCI_INVALID_TERMINAL_CHARSET_NAME_ERROR,
		  (ErrorParam *) 0
		 );
      return 0;
     }

     if ( CharInfo::isTerminalCharSetSupported(tcs_uppercase) == FALSE ) 
     {
      ErrorParam *ep = new ErrorParam(tcs);
      SqlciError (2038,
		  ep,
		  (ErrorParam *) 0
		 );
      delete ep;
      return 0;
     }

// The following code had been commented out but has been restored
//  for the charset project		CQD removed on 12/11/2007
/*
     char cqd_stmt[200]; // charset name can be up to 128 bytes long

     sprintf(cqd_stmt, "CONTROL QUERY DEFAULT TERMINAL_CHARSET '%s';",
                       tcs_uppercase
            );

     long retcode = SqlCmd::executeQuery(cqd_stmt, sqlci_env);

     if ( retcode == 0 )*/
       sqlci_env -> setTerminalCharset(
                     CharInfo::getCharSetEnum(tcs_uppercase)
                                      );
//     else
//       HandleCLIError(retcode, sqlci_env);


  } else 
      SqlciError (SQLCI_INVALID_TERMINAL_CHARSET_NAME_ERROR,
		  (ErrorParam *) 0
		 );

  return 0;
}

short SetIsoMapping::process(SqlciEnv * sqlci_env)
{
  HandleCLIErrorInit();


  char* omcs = get_argument();
  Int32 omcs_len;

  if ( omcs != NULL && ((omcs_len=strlen(omcs)) <= 128) )
  {
     char omcs_uppercase[129];
     str_cpy_convert(omcs_uppercase, omcs, omcs_len, 1);
     omcs_uppercase[omcs_len] = 0;

     if ( strcmp(omcs_uppercase, "ISO88591") != 0
          )
     {
       // 15001 42000 99999 BEGINNER MAJOR DBADMIN
       // A syntax error occurred at or before: $0~string0
       ErrorParam *ep = new ErrorParam(omcs);
       SqlciError (15001,
                   ep,
                   (ErrorParam *) 0
                  );
       delete ep;
       return 0;
     }


  } else {
    // 15001 42000 99999 BEGINNER MAJOR DBADMIN
    // A syntax error occurred at or before: $0~string0
    ErrorParam *ep;
    if (omcs)
      ep = new ErrorParam(omcs);
    else
      ep = new ErrorParam("ISO_MAPPING");
    SqlciError (15001,
                ep,
                (ErrorParam *) 0
                );
    delete ep;
  }

  return 0;
}

short SetDefaultCharset::process(SqlciEnv * sqlci_env)
{
  HandleCLIErrorInit();

  char* dcs = get_argument();
  Int32 dcs_len;

  if ( dcs != NULL && ((dcs_len=strlen(dcs)) <= 128) )
  {
     char dcs_uppercase[129];
     str_cpy_convert(dcs_uppercase, dcs, dcs_len, 1);
     dcs_uppercase[dcs_len] = 0;

     if ( strcmp(dcs_uppercase, "ISO88591") != 0 &&
          strcmp(dcs_uppercase, "UTF8"    ) != 0 &&
          strcmp(dcs_uppercase, "SJIS"    ) != 0
          )
     {
       // 15001 42000 99999 BEGINNER MAJOR DBADMIN
       // A syntax error occurred at or before: $0~string0
       ErrorParam *ep = new ErrorParam(dcs);
       SqlciError (15001,
                   ep,
                   (ErrorParam *) 0
                  );
       delete ep;
       return 0;
     }

     char cqd_stmt[200]; // charset name can be up to 128 bytes long

     sprintf(cqd_stmt, "CONTROL QUERY DEFAULT DEFAULT_CHARSET '%s';",
                       dcs_uppercase
            );

     Lng32 retcode = SqlCmd::executeQuery(cqd_stmt, sqlci_env);

     if ( retcode == 0 )
       sqlci_env -> setDefaultCharset(CharInfo::getCharSetEnum(dcs_uppercase));
     else
       HandleCLIError(retcode, sqlci_env);

  } else {
    // 15001 42000 99999 BEGINNER MAJOR DBADMIN
    // A syntax error occurred at or before: $0~string0
    ErrorParam *ep;
    if (dcs)
      ep = new ErrorParam(dcs);
    else
      ep = new ErrorParam("DEFAULT_CHARSET");
    SqlciError (15001,
                ep,
                (ErrorParam *) 0
                );
    delete ep;
  }

  return 0;
}

short SetInferCharset::process(SqlciEnv * sqlci_env)
{
  HandleCLIErrorInit();

  char* ics = get_argument();
  Int32 ics_len;

  if ( ics != NULL && ((ics_len=strlen(ics)) <= 128) )
  {
     char ics_uppercase[129];
     str_cpy_convert(ics_uppercase, ics, ics_len, 1);
     ics_uppercase[ics_len] = 0;

     if ( strcmp(ics_uppercase, "FALSE") != 0 &&
          strcmp(ics_uppercase, "TRUE" ) != 0 &&
          strcmp(ics_uppercase, "0"    ) != 0 &&
          strcmp(ics_uppercase, "1"    ) != 0 )
     {
       // 15001 42000 99999 BEGINNER MAJOR DBADMIN
       // A syntax error occurred at or before: $0~string0
       ErrorParam *ep = new ErrorParam(ics);
       SqlciError (15001,
                   ep,
                   (ErrorParam *) 0
                  );
       delete ep;
       return 0;
     }

     char cqd_stmt[200]; // charset name can be up to 128 bytes long

     sprintf(cqd_stmt, "CONTROL QUERY DEFAULT INFER_CHARSET '%s';",
                       ics_uppercase
            );

     Lng32 retcode = SqlCmd::executeQuery(cqd_stmt, sqlci_env);

     if ( retcode == 0 )
     {
       if ( ics_uppercase[0] == '1' || ics_uppercase[0] == 'T'/*RUE*/)
         sqlci_env -> setInferCharset(TRUE);
       else
         sqlci_env -> setInferCharset(FALSE);
     }
     else
       HandleCLIError(retcode, sqlci_env);

  } else {
    // 15001 42000 99999 BEGINNER MAJOR DBADMIN
    // A syntax error occurred at or before: $0~string0
    ErrorParam *ep;
    if (ics)
      ep = new ErrorParam(ics);
    else
      ep = new ErrorParam("INFER_CHARSET");
    SqlciError (15001,
                ep,
                (ErrorParam *) 0
                );
    delete ep;
  }

  return 0;
}



Show::Show(show_type type_, NABoolean allValues)
                 : SqlciCmd(SqlciCmd::SHOW_TYPE),
		   allValues_(allValues)
{
  type = type_;
};

Wait::Wait(char * argument_, Lng32 arglen_)
                 : SqlciCmd(SqlciCmd::WAIT_TYPE, argument_, arglen_)
{
};

//////////////////////////////////////////////////
short Exit::process(SqlciEnv * sqlci_env)
{
  // Default is to exit sqlci. In the special case of an
  // active transaction, the user may choose not to exit.
  short retval = -1;

 if (sqlci_env->statusTransaction())
    {
      // ## The following English text needs to come from the message file
      // ## so it can be translated, for I18N:

      sqlci_env->get_logfile()->WriteAll("\nThere is an active transaction.  Do you want to commit the transaction?");
      sqlci_env->get_logfile()->WriteAll("                 Y to commit transaction");
      sqlci_env->get_logfile()->WriteAll("                 N to abort transaction");
      sqlci_env->get_logfile()->WriteAllWithoutEOL("                 Any other key to resume in MXCI: ");

      char response[2];
      response[0] = 'N';			// noninteractive default
      response[1] = '\0';			// terminate string for WriteAll
      if (sqlci_env->isInteractiveSession())
        {
	  cin.clear(); clearerr(stdin);
	  cin.get(response[0]);
	  if (cin.eof())
	    {
	      // EOF encountered. Treat this as any key other than [YyNn]
	      response[0] = '\0';

	      // Output a '\n' since EOF keeps the cursor on the same line
	      cout << endl;

	      cin.clear(); clearerr(stdin);
	    }
	}

      // If not EOF and not simple ENTER/RETURN, then
      // display the character; if furthermore we're interactive, then
      // throw away the rest of the input line.
      if (response[0] == '\n')
	  sqlci_env->get_logfile()->WriteAll("", 0);	// write ONE endl, not 2
      else if (response[0])
	{
	  sqlci_env->get_logfile()->WriteAll(response, 1);
	  if (sqlci_env->isInteractiveSession())
	    {
	      InputStmt ignore(sqlci_env);
	      ignore.consumeLine();
	    }
	}

      // What if the executeQuery's below fail? should we still emit the
      // WriteAll "Transaction XXXed" message and proceed to exit?
      switch (response[0])
	{
	case 'y':
	case 'Y':
	  SqlCmd::executeQuery("COMMIT WORK WAITED;", sqlci_env);
	  sqlci_env->get_logfile()->WriteAll("Transaction committed."); //##I18N
	  retval = -1;
	  break;

	case 'n':
	case 'N':
	  SqlCmd::executeQuery("ROLLBACK WORK;", sqlci_env);
	  sqlci_env->get_logfile()->WriteAll("Transaction aborted.");  // ##I18N
	  retval = -1;
	  break;

	default:
	  sqlci_env->get_logfile()->WriteAll("Transaction state maintained.");	// ##I18N
	  retval = 0;
	  break;

	}

    } // if transaction is active

 // tell CLI that this user session is finished.
 SqlCmd::executeQuery("SET SESSION DEFAULT SQL_SESSION 'DROP';", sqlci_env);
 
  if (retval == -1)
    {
      sqlci_env->get_logfile()->WriteAll("\nEnd of MXCI Session\n"); // ##I18N
    }

  return retval;
}


//////////////////////////////////////////////
// Begin ERROR
////////////////////////////////////////////////
short Error::process(SqlciEnv * sqlci_env)
{
  NAWchar   *error_msg;
  Int32        codeE, codeW;
  char       stateE[10], stateW[10];
  NABoolean  msgNotFound;

  ostringstream omsg;

  #define GETERRORMESS(in, out, typ)	GetErrorMessage(in, (NAWchar *&)out, typ)

  codeW = ABS(atoi(get_argument()));	// >= 0, i.e. warning
  codeE = -codeW;			// <= 0, i.e. error

  // These calls must be done before any of the GETERRORMESS(),
  // as they all use (overwrite) the same static buffer in GetErrorMessage.cpp.
  ComSQLSTATE(codeE, stateE);
  ComSQLSTATE(codeW, stateW);
  msgNotFound = GETERRORMESS(codeE, error_msg, ERROR_TEXT);

  if (type == ENVCMD_)
    {
      if (msgNotFound)
        {
	  error_msg[0] = NAWchar('\n');
	  error_msg[1] = NAWchar('\0');
	}
      else
        {
	  // Extract the {braces-enclosed version string}
	  // that msgfileVrsn.ksh (called by GenErrComp.bat)
	  // has put into this ENVCMD_ message.
	  NAWchar *v = NAWstrchr(error_msg, NAWchar(']'));
	  if (v) error_msg = v;
	  v = NAWstrchr(error_msg, NAWchar('{'));
	  if (v) error_msg = v;
	  v = NAWstrchr(error_msg, NAWchar('}'));
	  if (v++ && *v == NAWchar('.')) *v = NAWchar(' ');
	}
      NAWriteConsole(error_msg, omsg, FALSE);
    }
  else if (!msgNotFound || codeE == 0)		// SQL "success", special case
    {
      omsg << "\n*** SQLSTATE (Err): " << stateE
           << " SQLSTATE (Warn): " << stateW;
      omsg << endl;
      NAWriteConsole(error_msg,omsg, TRUE);
    }
  else
    {
      // Msg not found.  
      ComDiagsArea diags;
      diags << DgSqlCode(codeW);
      NADumpDiags(omsg, &diags, TRUE/*newline*/);
    }

#if 0			// CAUSE/EFFECT/RECOVERY text not implemented yet!
  if (!msgNotFound && type == DETAIL_)
    {
      GETERRORMESS(codeE, error_msg, CAUSE_TEXT);
      NAWriteConsole(error_msg,omsg, TRUE);

      GETERRORMESS(codeE, error_msg, EFFECT_TEXT);
      NAWriteConsole(error_msg,omsg, TRUE);

      GETERRORMESS(codeE, error_msg, RECOVERY_TEXT);
      NAWriteConsole(error_msg,omsg, TRUE);

    }
#endif // 0		// CAUSE/EFFECT/RECOVERY text not implemented yet!

  omsg << ends;					// to tack on a null-terminator
  sqlci_env->get_logfile()->WriteAllWithoutEOL(omsg.str().c_str());
  return 0;
}


//////////////////////////////////////////////////
// Begin SHAPE
///////////////////////////////////////////////////
short Shape::process(SqlciEnv * sqlci_env)
{
  sqlci_env->showShape() = type_;

  if (! infile_)
    return 0;

  // open the infile to read Sql statements from
  FILE * fStream = 0;
  fStream = fopen(infile_, "r");
  if (!fStream)
    {
      ErrorParam *p1 = new ErrorParam (errno);
      ErrorParam *p2 = new ErrorParam (infile_);
      SqlciError (SQLCI_OBEY_FOPEN_ERROR,
	          p1,
		  p2,
		  (ErrorParam *) 0
		 );
      delete p1;
      delete p2;
      return 0;
    }
  
  // close and remember the current logfile
  char * logname = NULL;
  if (sqlci_env->get_logfile()->IsOpen())
    {
      logname = new char[strlen(sqlci_env->get_logfile()->Logname()) + 1];
      strcpy(logname, sqlci_env->get_logfile()->Logname());
      sqlci_env->get_logfile()->Close();
    }

  // if infile is the same as outfile, generate output into a temp
  // file(called outfile_ + __temp), and then rename it to infile. 
  // Also, rename infile to infile.bak.
  NABoolean tempFile = FALSE;
  char * tempOutfile = NULL;
  if (outfile_)
    {
      if (strcmp(infile_, outfile_) == 0)
	{
	  tempFile = TRUE;
	  tempOutfile = new char[strlen(outfile_) + 
				strlen("__temp") + 1];
	  strcpy(tempOutfile, outfile_);
	  strcat(tempOutfile, "__temp");
	}
      else
	tempOutfile = outfile_;

      sqlci_env->get_logfile()->Open(tempOutfile, Logfile::CLEAR_);
    }

  ////////////////////////////////////////////////////////////////
  // BEGIN PROCESS NEXT INPUT STMT
  ////////////////////////////////////////////////////////////////

  short retcode = processNextStmt(sqlci_env, fStream);
  if (retcode)
  {
    if(logname != NULL)
      delete [] logname;
    return retcode;
  }

  ////////////////////////////////////////////////////////////////
  // END PROCESS NEXT INPUT STMT
  ////////////////////////////////////////////////////////////////

  fclose(fStream);

  if (outfile_)
    {
      sqlci_env->get_logfile()->Close();

      char buf[200];
      if (tempFile)
	{
	  snprintf(buf, 200, "sh mv %s %s.bak", infile_, infile_);
	  ShellCmd * shCmd = new Shell(buf);
	  shCmd->process(sqlci_env);
	  delete shCmd;

	  snprintf(buf, 200, "sh mv %s %s", tempOutfile, infile_);
	  shCmd = new Shell(buf);
	  shCmd->process(sqlci_env);
	  delete shCmd;
	}
    }

  // reopen the original logfile
  if (logname)
    sqlci_env->get_logfile()->Open(logname, Logfile::APPEND_);

  delete [] logname;
  delete [] tempOutfile;
  tempOutfile = NULL;

  return 0;
}


short Shape::processNextStmt(SqlciEnv * sqlci_env, FILE * fStream)
{
  short retcode = 0;

  enum ShapeState 
   {
     PROCESS_STMT, DONE
   };

  Int32 done = 0;
  Int32 ignore_toggle = 0;
  ShapeState state;
  InputStmt * input_stmt;
  SqlciNode * sqlci_node = NULL;

  state = PROCESS_STMT;

  while (!done)
    {
      input_stmt = new InputStmt(sqlci_env);
      Int32 read_error = 0;
      if (state != DONE)
	{
	  read_error = input_stmt->readStmt(fStream, TRUE);
	  
	  if (feof(fStream) || read_error == -99)
	    {
	      if (!input_stmt->isEmpty() && read_error != -4)
		{
		  // Unterminated statement in obey file.
		  // Make the parser emit an error message.
		  input_stmt->display((UInt16)0, TRUE);
		  input_stmt->logStmt(TRUE);
		  input_stmt->syntaxErrorOnEof();
		}
	      state = DONE;
	    } // feof or error (=-99)
	}
      
      // if there is an eof directly after a statement
      // that is terminated with a semi-colon, process the
      // statement
      if (read_error == -4) state = PROCESS_STMT;
      
      switch (state)
	{
	case PROCESS_STMT:
	  {
	    Int32 ignore_stmt = input_stmt->isIgnoreStmt();
	    if (ignore_stmt)
	      ignore_toggle = ~ignore_toggle;
	    
	    if (ignore_stmt || ignore_toggle || input_stmt->ignoreJustThis())
	      {
		// ignore until stmt following the untoggling ?ignore
		sqlci_DA.clear();
	      }
	    else
	      {
		if (!read_error || read_error == -4)
		  {
		    sqlci_parser(input_stmt->getPackedString(),
				 input_stmt->getPackedString(),
				 &sqlci_node,sqlci_env);
		    if ((sqlci_node) &&
			(sqlci_node->getType() == SqlciNode::SQL_CMD_TYPE))
		      {
			delete sqlci_node;

			SqlCmd sqlCmd(SqlCmd::DML_TYPE, NULL);
			
			short retcode = sqlCmd.showShape(sqlci_env, 
							 input_stmt->getPackedString());
			if (retcode)
			{
			  delete input_stmt;
			  return retcode;
			}
		      }

		    input_stmt->display((UInt16)0, TRUE);
		    input_stmt->logStmt(TRUE);
		  }
		
		sqlci_env->displayDiagnostics() ;
		
		// Clear the DiagnosticsArea for the next command...
		sqlci_DA.clear();
		    
		// if an EXIT statement was seen, then a -1 will be returned
		// from process. We are done in that case.
		if (retcode == -1)
		  state = DONE;
	      }
	  }
	break;
	
	case DONE:
	  {
	    done = -1;
  	  }
	break;
	
	default:
	  {
	  }
	break;
	
	} // switch on state
      
      delete input_stmt;
      
    } // while not done

  return 0;
}

//////////////////////////////////////////////////
short Wait::process(SqlciEnv * sqlci_env)
{
  char buf[100];

  cout << "Enter a character + RETURN to continue: ";
  cin >> buf;

  return 0;
}

//////////////////////////////////////////////////
short ParserFlags::process(SqlciEnv * sqlci_env)
{
  Int32 retCode;

  if (!ComUser::isRootUserID())
  {    
    // Return - "not authorized" error 
    ComDiagsArea diags;
    diags << DgSqlCode(-1017);
    handleLocalError(&diags, sqlci_env);
    return -1;
  }

  if (opType == DO_SET)
  {
    if (param == 0)
    {
      // Warning 3190:
      // Please use "RESET PARSERFLAGS <value>" to reset the flags.
      ComDiagsArea diags;
      diags << DgSqlCode(3190);
      handleLocalError(&diags, sqlci_env);
    }
    retCode = SQL_EXEC_SetParserFlagsForExSqlComp_Internal2(param);
  }

  else
  {
    // It's DO_RESET
    retCode = SQL_EXEC_ResetParserFlagsForExSqlComp_Internal2(param);
  }

  if (retCode)
  {
    // This is most probably error 1017: 
    // You are not authorized to perform this operation.
    ComDiagsArea diags;
    diags << DgSqlCode(retCode);
    handleLocalError(&diags, sqlci_env);
  }
  return 0;
}


///////////////////////////////
//Process of the MODE Command//
///////////////////////////////

//   SQL is the normal mode in which MXCI executes.
short Mode::process(SqlciEnv * sqlci_env)
{
  short retcode = 1;
  switch (type)
  {
    case SQL_:
      retcode = process_sql(sqlci_env);
      break;
    default: 
      SqlciError(SQLCI_INVALID_MODE 
			,(ErrorParam *) 0 );
      break;
  }
  return retcode;
}

short Mode::process_sql(SqlciEnv * sqlci_env)
{
    if (SqlciEnv::SQL_ == sqlci_env->getMode())
    {
	SqlciError(SQLCI_RW_MODE_ALREADY_SQL 
			,(ErrorParam *) 0 );
       return 0;
    }
    
    sqlci_env->setMode(SqlciEnv::SQL_);

    return 0;
}

short QueryId::process(SqlciEnv * sqlci_env)
{
  Lng32 retcode = 0;

  HandleCLIErrorInit();
  
  char * stmtName = get_argument();

  PrepStmt * prep_stmt = NULL;
  if ((stmtName) &&
      (! (prep_stmt = sqlci_env->get_prep_stmts()->get(stmtName))))
    {
       sqlci_env->diagsArea() << DgSqlCode(-SQLCI_STMT_NOT_FOUND)
				 << DgString0(stmtName);
       return 0;
    }

  Logfile *log = sqlci_env->get_logfile();
  char sprintfBuf[225];    

  if (!stmtName)
  {
    //try to find the last executed statement if present
    if (sqlci_env->lastExecutedStmt() && sqlci_env->lastExecutedStmt()->getStmtNameLen() > 0)
      stmtName = sqlci_env->lastExecutedStmt()->getStmtName();
    //if not, try to find the last prepared statement if present
    else if (sqlci_env->getLastAllocatedStmt() && sqlci_env->getLastAllocatedStmt()->identifier_len > 0)
      stmtName = (char *) sqlci_env->getLastAllocatedStmt()->identifier;
  }

  if (!stmtName) 
  // no statement name found Display error.
  {
    sprintf(sprintfBuf, "No statement found. Enter command with valid statement name.");
    log->WriteAll(sprintfBuf);
    return 0;
  }

  SQLSTMT_ID stmt;
  SQLMODULE_ID module;
  init_SQLMODULE_ID(&module);
  init_SQLSTMT_ID(&stmt, SQLCLI_CURRENT_VERSION, 
		  stmt_name, &module);

  char * id = new char[strlen(stmtName) + 1];
  stmt.identifier_len = strlen(stmtName);
  str_cpy_all(id,stmtName, 
	 stmt.identifier_len);
  id[stmt.identifier_len] = 0;
  stmt.identifier = id;

  char queryId[200];
  Lng32 queryIdLen;
  
  if (isSet_)
    {
      // change query id in prep_stmt
      if (prep_stmt->uniqueQueryId())
        {
          delete prep_stmt->uniqueQueryId();
          prep_stmt->uniqueQueryIdLen() = 0;
        }
      
      prep_stmt->uniqueQueryIdLen() = strlen(qidVal_);
      prep_stmt->uniqueQueryId() = new char[prep_stmt->uniqueQueryIdLen() + 1];
      strcpy(prep_stmt->uniqueQueryId(), qidVal_);

      retcode = SQL_EXEC_SetStmtAttr(&stmt, SQL_ATTR_UNIQUE_STMT_ID,
                                     0, qidVal_);
      delete [] id;

      log->WriteAll("");

      return 0;
    }

  retcode = SQL_EXEC_GetStmtAttr(&stmt, SQL_ATTR_UNIQUE_STMT_ID,
                      NULL, queryId, 200, &queryIdLen); 
  delete [] id;

  if (queryIdLen < 200)
    queryId[queryIdLen] = 0;
  else
    queryId[199] = 0;

  HandleCLIError(retcode, sqlci_env);

  if (retcode == 0)
  {
    snprintf(sprintfBuf, 225, "QID is %s",queryId);
    log->WriteAll(sprintfBuf);
    log->WriteAll("");
  }  
    
  // display details of this query
  // for string attributes, use {type,maxLength,char[maxLength+1]}
  UNIQUEQUERYID_ATTR queryIdAttrs[11] =
  {
    {UNIQUEQUERYID_SEGMENTNUM, 0, 0},
    {UNIQUEQUERYID_SEGMENTNAME, 10, new char[11]},
    {UNIQUEQUERYID_CPU, 0, 0},
    {UNIQUEQUERYID_PIN, 0, 0},
    {UNIQUEQUERYID_EXESTARTTIME, 0, 0},
    {UNIQUEQUERYID_SESSIONNUM, 0, 0},
    {UNIQUEQUERYID_USERNAME, 24, new char[25]},
    {UNIQUEQUERYID_SESSIONNAME, 32, new char[33]},
    {UNIQUEQUERYID_QUERYNUM, 0, 0},
    {UNIQUEQUERYID_STMTNAME, 110, new char[111]},
    {UNIQUEQUERYID_SESSIONID, 104, new char[105]}
  };

  retcode = SQL_EXEC_GetUniqueQueryIdAttrs(queryId, queryIdLen,
                                           11, queryIdAttrs);
  HandleCLIError(retcode, sqlci_env);
  
  if (retcode == 0)
    {
      snprintf(sprintfBuf, 225, "QID details: ");
      log->WriteAll(sprintfBuf);
      log->WriteAll("============");

      // display UNIQUEQUERYID_SEGMENTNUM
      snprintf(sprintfBuf, 225, "  Segment Num:  " PFLL,queryIdAttrs[0].num_val_or_len);
      log->WriteAll(sprintfBuf);

      // display UNIQUEQUERYID_SEGMENTNAME
      snprintf(sprintfBuf, 225, "  Segment Name: %s",queryIdAttrs[1].string_val);
      log->WriteAll(sprintfBuf);

      // display UNIQUEQUERYID_CPU
      snprintf(sprintfBuf, 225, "  Cpu:          " PFLL,queryIdAttrs[2].num_val_or_len);
      log->WriteAll(sprintfBuf);

      // display UNIQUEQUERYID_PIN
      snprintf(sprintfBuf, 225, "  Pin:          " PFLL,queryIdAttrs[3].num_val_or_len);
      log->WriteAll(sprintfBuf);
 
      // UNIQUEQUERYID_EXESTARTTIME
      short startTimeArray[8];
      _int64 startTime = queryIdAttrs[4].num_val_or_len;
      short error;

      INTERPRETTIMESTAMP( CONVERTTIMESTAMP(startTime, 0, // GMT to LCT
                                                    -1, // use current node
                                                  &error), startTimeArray);
      sprintf(sprintfBuf, "  ExeStartTime: " PF64 "= %02d/%02d/%02d %02d:%02d:%02d.%03d%03d LCT",
                    startTime, startTimeArray[0],startTimeArray[1],startTimeArray[2],
                    startTimeArray[3], startTimeArray[4], startTimeArray[5],
                    startTimeArray[6], startTimeArray[7]);
      log->WriteAll(sprintfBuf);

      // display UNIQUEQUERYID_SESSIONNUM
      sprintf(sprintfBuf,"  SessionNum:   " PFLL,queryIdAttrs[5].num_val_or_len);
      log->WriteAll(sprintfBuf);

      // display UNIQUEQUERYID_USERNAME
      sprintf(sprintfBuf,"  UserName:     %s",queryIdAttrs[6].string_val);
      log->WriteAll(sprintfBuf);

      // display UNIQUEQUERYID_SESSIONNAME
      if (strlen(queryIdAttrs[7].string_val) > 0)
	sprintf(sprintfBuf,"  SessionName:  %s",queryIdAttrs[7].string_val);
      else
        sprintf(sprintfBuf,"  SessionName:  NULL");

      log->WriteAll(sprintfBuf);

      // display UNIQUEQUERYID_QUERYNUM
      sprintf(sprintfBuf,"  QueryNum:     " PFLL,queryIdAttrs[8].num_val_or_len);
      log->WriteAll(sprintfBuf);

      // display UNIQUEQUERYID_STMTNAME:
      sprintf(sprintfBuf,"  StmtName:     %s",queryIdAttrs[9].string_val);
      log->WriteAll(sprintfBuf);

      // display UNIQUEQUERYID_SESSIONID:
      sprintf(sprintfBuf,"  SessionId:    %s",queryIdAttrs[10].string_val);
      log->WriteAll(sprintfBuf);

      log->WriteAll("");
    }  
  
  return 0;
}








