/**********************************************************************
// @@@ 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:         Globals.cpp
 * Description:  CLI globals. For each process that uses the CLI there
 *               should be exactly one object of type CliGlobals.
 *               
 * Created:      7/10/95
 * Language:     C++
 *
 *
 *
 *
 *****************************************************************************
 */

// -----------------------------------------------------------------------

#include "Platform.h"


#include <stdlib.h>
#include <sys/syscall.h>
#include "cli_stdh.h"
#include "Ipc.h"
#include "ex_stdh.h"
#include "ex_frag_rt.h"
#include "memorymonitor.h"
#include "ExStats.h"
#include "ExUdrServer.h"
#include "ExSqlComp.h"
#include "ExControlArea.h"
#include "Context.h"
#include "ex_transaction.h"
#include "Statement.h"
#include "ex_root.h"
#include "ComRtUtils.h"
#include <semaphore.h>
#include <pthread.h>
#include "HBaseClient_JNI.h"
#include "HdfsClient_JNI.h"
#include "HiveClient_JNI.h"
#include "LmLangManagerC.h"
#include "LmLangManagerJava.h"
#include "CliSemaphore.h"

#include "ExCextdecs.h"
CliGlobals * cli_globals = NULL;

CLISemaphore globalSemaphore ;

#include "CmpContext.h"

CliGlobals::CliGlobals(NABoolean espProcess)
     : inConstructor_(TRUE),
       executorMemory_((const char *)"Global Executor Memory"),
       contextList_(NULL),
       envvars_(NULL),
       envvarsContext_(0),
       sharedArkcmp_(NULL),
       arkcmpInitFailed_(arkcmpIS_OK_),
       processIsStopping_(FALSE),
       totalCliCalls_(0),
       savedCompilerVersion_ (COM_VERS_COMPILER_VERSION),
       globalSbbCount_(0),
       priorityChanged_(FALSE),
       currRootTcb_(NULL),
       processStats_(NULL),
       savedPriority_(148), // Set it to some valid priority to start with
       tidList_(NULL),
       cliSemaphore_(NULL),
       defaultContext_(NULL),
       langManC_(NULL),
       langManJava_(NULL)
       , myVerifier_(-1)
       , espProcess_(espProcess)
{
  globalsAreInitialized_ = FALSE;
  executorMemory_.setThreadSafe();
  init(espProcess, NULL);
  globalsAreInitialized_ = TRUE;
}

void CliGlobals::init( NABoolean espProcess,
                       StatsGlobals *statsGlobals
                       )
{
  int threadCount = NAAssertMutexCreate();
  if (threadCount != 1) // The main executor thread must be first
    abort();
  SQLMXLoggingArea::init();

#if !(defined(__SSCP) || defined(__SSMP))
  sharedCtrl_ = new(&executorMemory_) ExControlArea(NULL /*context */,
						    &executorMemory_);
#else
  sharedCtrl_ = NULL;
#endif

  char *_sqptr = 0;
  _sqptr = new (&executorMemory_) char[10];

  numCliCalls_ = 0;
  nodeName_[0] = '\0';

  breakEnabled_ = FALSE;
  
  SPBreakReceived_ = FALSE;
  isESPProcess_ = FALSE;
 
  logReclaimEventDone_ = FALSE;

  // find and initialize the directory this program is being run from.
  // Max length of oss dirname is 1K (process_getinfolist_ limit).
  // Also initialize the node, cpu and pin my process is running at.
  
  programDir_ = new (&executorMemory_) char[1024 + 1];
  short nodeNameLen;
  Lng32 retcomrt = 0;
  retcomrt =  ComRtGetProgramInfo(programDir_, 1024, processType_,
				  myCpu_, myPin_, 
				  myNodeNumber_, myNodeName_, nodeNameLen, 
				  myStartTime_, myProcessNameString_,
				  parentProcessNameString_
                                  , &myVerifier_
                                 );

  if (retcomrt)
  {
    char errStr[128];
    sprintf (errStr, "Could not initialize CLI globals.ComRtGetProgramInfo returned an error :%d.", retcomrt);
    ex_assert(0,errStr);
  }

  ComRtGetProcessPriority(myPriority_);
  savedPriority_ = (short)myPriority_;
  myNumCpus_ = ComRtGetCPUArray(cpuArray_, (NAHeap *)&executorMemory_);

  // create global structures for IPC environment
#if !(defined(__SSCP) || defined(__SSMP))

  ipcHeap_ = new(&executorMemory_) NAHeap("IPC Heap",
                                     NAMemory::IPC_MEMORY, 2048 * 1024);
    ipcHeap_->setThreadSafe();
  if (! espProcess)
  {
    // Create the process global ARKCMP server.
    sharedArkcmp_ = NULL;
    nextUniqueContextHandle = DEFAULT_CONTEXT_HANDLE;
    lastUniqueNumber_ = 0;
    sessionUniqueNumber_ = 0;
    // It is not thread safe to set the globals cli_globals
    // before cli_globals is fully initialized, but it is being done
    // here because the code below expects it 
    cli_globals = this;
    int error;
    statsGlobals_ = (StatsGlobals *)shareStatsSegment(shmId_);
    if (statsGlobals_ == NULL
      || (statsGlobals_ != NULL && 
        statsGlobals_->getVersion() != StatsGlobals::CURRENT_SHARED_OBJECTS_VERSION_))
    {
      statsGlobals_ = NULL;
      statsHeap_ = new (getExecutorMemory()) 
        NAHeap("Process Stats Heap", getExecutorMemory(),
	       8192,
	       0);
      statsHeap_->setThreadSafe();
    }
    else
    {
      error = statsGlobals_->openStatsSemaphore(semId_);
      // Behave like as if stats is not available
      if (error != 0)
      {
	statsGlobals_ = NULL;
	statsHeap_ = getExecutorMemory();
      }
      else
      {
        error = statsGlobals_->getStatsSemaphore(semId_, myPin_);

        statsHeap_ = (NAHeap *)statsGlobals_->
               getStatsHeap()->allocateHeapMemory(sizeof *statsHeap_, FALSE);

        // The following assertion may be hit if the RTS shared memory
        // segment is full.  The stop catcher code will be responsible
        // for releasing the RTS semaphore.
        ex_assert(statsHeap_, "allocateHeapMemory returned NULL.");

        // This next allocation, a placement "new" will not fail.
	statsHeap_ = new (statsHeap_, statsGlobals_->getStatsHeap()) 
	  NAHeap("Process Stats Heap", statsGlobals_->getStatsHeap(),
		 8192,
		 0);
	statsGlobals_->addProcess(myPin_, statsHeap_);
        processStats_ = statsGlobals_->getExProcessStats(myPin_);
        processStats_->setStartTime(myStartTime_);
	statsGlobals_->releaseStatsSemaphore(semId_, myPin_);
      }
    }
    // create a default context and make it the current context
    cliSemaphore_ = new (&executorMemory_) CLISemaphore();
    defaultContext_ = new (&executorMemory_) ContextCli(this);
    contextList_  = new(&executorMemory_) HashQueue(&executorMemory_);
    tidList_  = new(&executorMemory_) HashQueue(&executorMemory_);
    SQLCTX_HANDLE ch = defaultContext_->getContextHandle();
    contextList_->insert((char*)&ch, sizeof(SQLCTX_HANDLE), (void*)defaultContext_);
    if (statsGlobals_ != NULL) 
       memMonitor_ = statsGlobals_->getMemoryMonitor();
    else
    {
       // create the process global memory monitor. For now with
       // defaults of 10 window entries and sampling every 1 second
       Lng32 memMonitorWindowSize = 10;
       Lng32 memMonitorSampleInterval = 1; // reduced from 10 (for M5 - May 2011)
       memMonitor_ = new (&executorMemory_) MemoryMonitor(memMonitorWindowSize,
						      memMonitorSampleInterval,
    						      &executorMemory_);
    }
  } // (!espProcess)

  else
  {
    // For ESPs do not create the default context here. At this point
    // the ESP has not created an IpcEnvironment object yet so the
    // result context will have an invalid ExSqlComp object that
    // points to a NULL IpcEnvironment. In bin/ex_esp_main.cpp, the
    // following objects are created at ESP startup time:
    //   - CliGlobals
    //   - IpcEnvironment
    //   - Default ContextCli in CliGlobals
    //   - MemoryMonitor
    //   - ExEspFragInstanceDir
    //   - ExEspControl Message
    //   - Global UDR server manager
    cliSemaphore_ = new (&executorMemory_) CLISemaphore();
    statsGlobals_ = NULL;
    semId_ = -1;
    statsHeap_ = NULL;
    lastUniqueNumber_ = 0;

  } // if (!espProcess) else ...

#else // (defined(__SSCP) || defined(__SSMP)) 
  cliSemaphore_ = new (&executorMemory_) CLISemaphore();
  statsGlobals_ = statsGlobals;
  semId_ = -1;
  statsHeap_ = NULL;
  lastUniqueNumber_ = 0;
#endif 

  inConstructor_ = FALSE;
  //
  // could initialize the program file name here but ...
  myProgName_[0] = '\0';
}
CliGlobals::~CliGlobals()
{
  arkcmpInitFailed_ = arkcmpERROR_; // (it's corrupt after deleting, anyway...)
  short error ;

  if (sharedArkcmp_)
  {
    delete sharedArkcmp_;
    sharedArkcmp_ = NULL;
  }
  if (statsGlobals_ != NULL)
  {
    error = statsGlobals_->getStatsSemaphore(semId_, myPin_);
    statsGlobals_->removeProcess(myPin_);
    statsGlobals_->releaseStatsSemaphore(semId_, myPin_);
    sem_close((sem_t *)semId_);
  }
}

Lng32 CliGlobals::getNextUniqueContextHandle()
{
    Lng32 contextHandle;
    cliSemaphore_->get();
    contextHandle = nextUniqueContextHandle++;
    cliSemaphore_->release();
    return contextHandle;
}

IpcPriority CliGlobals::myCurrentPriority()
{
  IpcPriority myPriority;
  
  Lng32 retcode = ComRtGetProcessPriority(myPriority);
  if (retcode)
    return -2;

  return myPriority;
}


// NOTE: Unlike REFPARAM_BOUNDSCHECK, this method does not verify that
//       the pointer "startAddress" actually points to a valid address
//       in the user address space (means that dereferencing the
//       pointer may cause a segmentation violation).
//
// Here are some DEFINEs from files DMEM and JMEMH in product T9050 that
// perform the PRIV address check:
// LOG2_BYTES_IN_T16PAGE      = 11,    ! 2048 bytes in a T16 page size
// LOG2_T16PAGES_IN_SEGMENT   =  6,    ! 64 T16 pages in a segment
// LOG2_BYTES_IN_SEGMENT      = LOG2_BYTES_IN_T16PAGE +
//                              LOG2_T16PAGES_IN_SEGMENT,
// SYSTEMDATASEG  = 1,  !  System Data Segment (always absolute segment 1)
//
// #define ADDR_IS_IN_KSEG0_1_2( a )         \
//    ( (int32) (a) < 0 )
//
// #define ADDR_IS_PRIV(a) (ADDR_IS_IN_KSEG0_1_2(a)               \
//              || ((vaddr_t)(a) >> LOG2_BYTES_IN_SEGMENT) == SYSTEMDATASEG)
//
// NOTE: we'll need to recompile if the NSK architecture changes, which
// should be infrequent as Charles Landau assures me.

Lng32 CliGlobals::boundsCheck(void          *startAddress,
			     ULng32 length,
			     Lng32          &retcode)
{
  // no bounds checking on NT because we're not PRIV
  return 0;
}

NAHeap *CliGlobals::getIpcHeap()
{
   return currContext()->getIpcHeap();
}

IpcEnvironment *CliGlobals::getEnvironment()
{
   ContextCli *currentContext = currContext();
   if (currentContext != NULL)
      return currentContext->getEnvironment();
   else
      return NULL;
}

ExEspManager *CliGlobals::getEspManager()
{
  return currContext()->getEspManager();
}

ExSsmpManager *CliGlobals::getSsmpManager()
{
  return currContext()->getSsmpManager();
}

LmLanguageManager * CliGlobals::getLanguageManager(ComRoutineLanguage language)
{
  switch (language)
    {
    case COM_LANGUAGE_JAVA:
      return getLanguageManagerJava();
      break;
    case COM_LANGUAGE_C:
    case COM_LANGUAGE_CPP:
      return getLanguageManagerC();
      break;
    default:
      ex_assert(0, "Invalid language in CliGlobals::getLanguageManager()");
    }
  return NULL;
}

LmLanguageManagerC * CliGlobals::getLanguageManagerC()
{
  if (!langManC_)
    {
      LmResult result;

      langManC_ = new(&executorMemory_)
        LmLanguageManagerC(result,
                           FALSE,
                           &(currContext()->diags()));

      if (result != LM_OK)
        {
          delete langManC_;
          langManC_ = NULL;
        }
    }

  return langManC_;
}

LmLanguageManagerJava * CliGlobals::getLanguageManagerJava()
{
  if (!langManJava_)
    {
      LmResult result;

      langManJava_ = new(&executorMemory_)
        LmLanguageManagerJava(result,
                              FALSE,
                              1,
                              NULL, // Java options should have been
                                    // provided for earlier JNI calls
                                    // in Trafodion
                              &(currContext()->diags()));

      if (result != LM_OK)
        {
          delete langManJava_;
          langManJava_ = NULL;
        }
    }

  return langManJava_;
}

ExeTraceInfo *CliGlobals::getExeTraceInfo()
{
  return currContext()->getExeTraceInfo();
}

ExSqlComp * CliGlobals::getArkcmp(short index)
{
  //return sharedArkcmp_;
  return currContext()->getArkcmp(index);
}

CliGlobals * CliGlobals::createCliGlobals(NABoolean espProcess)
{
  CliGlobals *result;

  result =  new CliGlobals(espProcess);
  //pthread_key_create(&thread_key, SQ_CleanupThread);
  cli_globals = result;
  return result;
}

void * CliGlobals::getSegmentStartAddrOnNSK()
{

  // this method should only be called on NSK, return NULL on other platforms
  return NULL;

}

CliGlobals *GetCliGlobals()
{ return cli_globals; }


// used by ESP only
void CliGlobals::initiateDefaultContext()
{
  // create a default context and make it the current context
  defaultContext_ = new (&executorMemory_) ContextCli(this);
  contextList_  = new(&executorMemory_) HashQueue(&executorMemory_);
  tidList_  = new(&executorMemory_) HashQueue(&executorMemory_);
  cliSemaphore_ = new (&executorMemory_) CLISemaphore();
  SQLCTX_HANDLE ch = defaultContext_->getContextHandle();
  contextList_->insert((char*)&ch, sizeof(SQLCTX_HANDLE),
                       (void*)defaultContext_);
}

ContextCli *CliGlobals::currContext()
{
  if (tsCurrentContextMap == NULL ||
               tsCurrentContextMap->context_ == NULL)
  {
    tsCurrentContextMap = getThreadContext(syscall(SYS_gettid));
    //pthread_setspecific(thread_key, tsCurrentContextMap);
    if (tsCurrentContextMap == NULL)
       return defaultContext_; 
  }
  return tsCurrentContextMap->context_; 
}


Lng32 CliGlobals::createContext(ContextCli* &newContext)
{
  newContext = new (&executorMemory_) ContextCli(this);
  SQLCTX_HANDLE ch = newContext->getContextHandle();
  cliSemaphore_->get();
  contextList_->insert((char*)&ch, sizeof(SQLCTX_HANDLE), (void*)newContext);
  cliSemaphore_->release();
   
  return 0;
}
Lng32 CliGlobals::dropContext(ContextCli* context)
{
  if (!context)
    return -1;

  if (context == getDefaultContext())
      return 0;

  CLISemaphore *tmpSemaphore = context->getSemaphore();
  tmpSemaphore->get();
  try
  {
     context->deleteMe();
  }
  catch (...)
  {
     tmpSemaphore->release();
     return -1;
  }
  tmpSemaphore->release();
  pid_t tid = syscall(SYS_gettid);
  cliSemaphore_->get();
  contextList_->remove((void*)context);
  tidList_->position();
  ContextTidMap *contextTidMap;
  while ((contextTidMap = (ContextTidMap *)tidList_->getNext()) != NULL)
  {
     if (contextTidMap->context_ == context)
     {
        if (contextTidMap->tid_  == tid)
        {
           tidList_->remove((char*)&contextTidMap->tid_, sizeof(pid_t), 
                          contextTidMap);
           NADELETE(contextTidMap, ContextTidMap, getExecutorMemory());
           tsCurrentContextMap = NULL; 
        }
        else
           contextTidMap->context_ = NULL;
     }
  } 
  delete context;
  cliSemaphore_->release();
  return 0;
}

ContextCli * CliGlobals::getContext(SQLCTX_HANDLE context_handle, 
                                    NABoolean calledFromDrop)
{
  ContextCli * context;
  cliSemaphore_->get();
  contextList_->position((char*)&context_handle, sizeof(SQLCTX_HANDLE));
  while ((context = (ContextCli *)contextList_->getNext()) != NULL)
  {
     if (context_handle == context->getContextHandle())
     {
        if (context->isDropInProgress())
           context = NULL;
        else if (calledFromDrop)
           context->setDropInProgress();
        cliSemaphore_->release();
        return context;
     }
  }
  cliSemaphore_->release();
  return NULL;
}

ContextTidMap * CliGlobals::getThreadContext(pid_t tid)
{
  SQLCTX_HANDLE ch;
  ContextTidMap *contextTidMap;

  if (tidList_ == NULL)
     return NULL;
  cliSemaphore_->get();
  tidList_->position((char*)&tid, sizeof(pid_t));
  while ((contextTidMap = (ContextTidMap *)tidList_->getNext()) != NULL)
  {
      if (contextTidMap->tid_ == tid)
      {
         if (contextTidMap->context_ == NULL)
         {
             NADELETE(contextTidMap, ContextTidMap, getExecutorMemory());
             tidList_->remove((char*)&tid, sizeof(pid_t), contextTidMap);
             contextTidMap = NULL;
         }
         cliSemaphore_->release();
         return contextTidMap;
      }
  }
  cliSemaphore_->release();
  return NULL;
}

Lng32 CliGlobals::switchContext(ContextCli * newContext)
{
  Lng32 retcode;

  pid_t tid;
  SQLCTX_HANDLE ch, currCh;

  tid = syscall(SYS_gettid);
  if (newContext != defaultContext_  && 
        tsCurrentContextMap != NULL && 
           newContext == tsCurrentContextMap->context_)
     return 0;
  retcode = currContext()->getTransaction()->suspendTransaction();
  if (retcode != 0)
     return retcode;
  cliSemaphore_->get();
  tidList_->position((char*)&tid, sizeof(pid_t));
  ContextTidMap *contextTidMap;
  NABoolean tidFound = FALSE;
  while ((contextTidMap = (ContextTidMap *)tidList_->getNext()) != NULL)
  {
     if (tid == contextTidMap->tid_)
     {
        contextTidMap->context_ = newContext;
        tidFound = TRUE;
        tsCurrentContextMap = contextTidMap;
        break;
     }
  } 
  if (! tidFound)
  {
     contextTidMap = new  (getExecutorMemory()) ContextTidMap(tid, newContext);
     tidList_->insert((char *)&tid, sizeof(pid_t), (void *)contextTidMap);
     tsCurrentContextMap = contextTidMap;
  }
  cliSemaphore_->release();
  retcode = currContext()->getTransaction()->resumeTransaction();
  return retcode;
}

Lng32 CliGlobals::sendEnvironToMxcmp()
{
  ComDiagsArea & diags = currContext()->diags();
  
  if (NOT getArkcmp()->isConnected())
    return 0;
  
  // send the current environment to mxcmp
  ExSqlComp::ReturnStatus sendStatus = 
    getArkcmp()->sendRequest(CmpMessageObj::ENVS_REFRESH, NULL,0);
  if (sendStatus != ExSqlComp::SUCCESS)
    {
      if (sendStatus == ExSqlComp::ERROR)
	{
	  diags << DgSqlCode(-CLI_SEND_REQUEST_ERROR) 
		<< DgString0("SET ENVIRON");
	  return -CLI_SEND_REQUEST_ERROR;
	  //	  return SQLCLI_ReturnCode(&currContext,-CLI_SEND_REQUEST_ERROR);
	}
      //else
      //  retcode = WARNING;
    }
  
  if (getArkcmp()->status() != ExSqlComp::FINISHED)
    {
      diags << DgSqlCode(-CLI_IO_REQUESTS_PENDING)
	    << DgString0("SET ENVIRON");
      return -CLI_IO_REQUESTS_PENDING;
      //return SQLCLI_ReturnCode(&currContext,-CLI_IO_REQUESTS_PENDING); 
    }
  
  return 0;
}

Lng32 CliGlobals::setEnvVars(char ** envvars)
{
  if ((! envvars) || (isESPProcess_))
    return 0;

  Int32 nEnvs = 0;
  if (envvars_)
    {
      // deallocate the current set of envvars
      ipcHeap_->deallocateMemory(envvars_);
      envvars_ = NULL;
    }

  for (nEnvs=0; envvars[nEnvs]; nEnvs++);

  // one extra to null terminate envvar list
  Lng32 envvarsLen = (nEnvs + 1) * sizeof(char*);

  Int32 count;
  for (count=0; count < nEnvs; count++) 
    { 
      envvarsLen += str_len(envvars[count])+1;
    } 

  // allocate contiguous space for envvars
  envvars_ = (char**)(new(ipcHeap_) char[envvarsLen]);

  char * envvarsValue = (char *)envvars_ + (nEnvs + 1) * sizeof(char*);

  // and copy input envvars to envvars_
  for (count=0; count < nEnvs; count++) 
    { 
      envvars_[count] = envvarsValue;
      Lng32 l = str_len(envvars[count])+1;
      str_cpy_all(envvarsValue, envvars[count], l);
      envvarsValue = envvarsValue + l;
    } 

  envvars_[nEnvs] = 0;

  // also set it in IpcEnvironment so it could be used to send
  // it to mxcmp.
  getEnvironment()->setEnvVars(envvars_);
  getEnvironment()->setEnvVarsLen(envvarsLen);

  envvarsContext_++;

  return sendEnvironToMxcmp();
}

Lng32 CliGlobals::setEnvVar(const char * name, const char * value,
			   NABoolean reset)
{
  if ((! name) || (! value) || (isESPProcess_))
    return 0;

  NABoolean found = FALSE;
  Lng32 envvarPos = -1;
  if (ComRtGetEnvValueFromEnvvars((const char**)envvars_, name, &envvarPos))
    found = TRUE;

  if ((NOT found) && (reset))
    return 0;

  Int32 nEnvs = 0;
  if (envvars_)
    {
      for (nEnvs=0; envvars_[nEnvs]; nEnvs++);
    }

  if (reset)
    {
      //      nEnvs--;
    }
  else if (NOT found)
    {
      envvarPos = nEnvs;
      nEnvs++;
    }

  // one extra entry, if envvar not found.
  // one extra to null terminate envvar list.
  //  long envvarsLen = (nEnvs + (NOT found ? 1 : 0) + 1) * sizeof(char*);
  Lng32 newEnvvarsLen = (nEnvs + 1) * sizeof(char*);

  Int32 count;
  for (count=0; count < nEnvs; count++) 
    { 
      if (count == envvarPos)
	//      if ((found) && (count == envvarPos))
	{
	  if (NOT reset)
	    newEnvvarsLen += strlen(name) + strlen("=") + strlen(value) + 1;
	}
      else if (NULL != envvars_)
	newEnvvarsLen += str_len(envvars_[count])+1;
    } 
  
  /*  if (NOT found)
    {
      nEnvs++;
      newEnvvarsLen += strlen(name) + strlen("=") + strlen(value) + 1;
    }
    */

  // allocate contiguous space for envvars
  char ** newEnvvars = (char**)(new(ipcHeap_) char[newEnvvarsLen]);

  char * newEnvvarsValue = 
    (char*)(newEnvvars + 
	    ((reset ? (nEnvs-1) : nEnvs) + 1));

  // and copy envvars_ to newEnvvars
  Int32 tgtCount = 0;
  for (count=0; count < nEnvs; count++) 
    { 
      newEnvvars[tgtCount] = newEnvvarsValue;
      Lng32 l = 0;
      if (count == envvarPos)
	{
	  if (NOT reset)
	    {
	      strcpy(newEnvvarsValue, name);
	      strcat(newEnvvarsValue, "=");
	      strcat(newEnvvarsValue, value);
	      l = strlen(name) + strlen("=") + strlen(value) + 1;

	      tgtCount++;
	    }
	}
      else if (NULL != envvars_)
	{
	  l = str_len(envvars_[count])+1;
	  str_cpy_all(newEnvvarsValue, envvars_[count], l);
	  tgtCount++;
	}
      newEnvvarsValue = newEnvvarsValue + l;
    } 

  if (reset)
    {
      nEnvs--;
    }

  newEnvvars[nEnvs] = 0;

  if (envvars_)
    {
      // deallocate the current set of envvars
      ipcHeap_->deallocateMemory(envvars_);
      envvars_ = NULL;
    }
  envvars_ = newEnvvars;

  // set or reset this envvar in SessionDefaults.
  SessionEnvvar * se = 
    new(ipcHeap_) SessionEnvvar(ipcHeap_, (char*)name, (char*)value);

  // remove if an entry exists
  currContext()->getSessionDefaults()->sessionEnvvars()->remove(*se);
  
  // insert a new entry, if this is not a RESET operation.
  if (NOT reset)
    {
      currContext()->getSessionDefaults()->sessionEnvvars()->insert(*se);
    }

  delete se;

  // also set it in IpcEnvironment so it could be used to send
  // it to mxcmp.
  getEnvironment()->setEnvVars(envvars_);
  getEnvironment()->setEnvVarsLen(newEnvvarsLen);

  envvarsContext_++;

  // need to set the env to the embedded compiler too
  if (currContext()->isEmbeddedArkcmpInitialized())
    {
      currContext()->getEmbeddedArkcmpContext()
                   ->setArkcmpEnvDirect(name, value, reset);
    }

  return sendEnvironToMxcmp();
}

char * CliGlobals::getEnv(const char * name)
{
  return (char*)ComRtGetEnvValueFromEnvvars((const char**)envvars_, name);
}
//
Lng32 CliGlobals::resetContext(ContextCli *theContext, void *contextMsg)
{
    theContext->reset(contextMsg);  
    return SUCCESS;
}

NAHeap *CliGlobals::getCurrContextHeap()
{
   return currContext()->exHeap();
}


ExUdrServerManager *CliGlobals::getUdrServerManager()
{ return currContext()->getUdrServerManager(); }

NABoolean CliGlobals::getUdrErrorChecksEnabled() 
{ return currContext()->getUdrErrorChecksEnabled(); }

Lng32 CliGlobals::getUdrSQLAccessMode() 
{ return currContext()->getUdrSQLAccessMode(); }

NABoolean CliGlobals::getUdrAccessModeViolation() 
{ return currContext()->getUdrAccessModeViolation(); }

NABoolean CliGlobals::getUdrXactViolation() 
{ return currContext()->getUdrXactViolation(); }

NABoolean CliGlobals::getUdrXactAborted() 
{ return currContext()->getUdrXactAborted(); }

void CliGlobals::setUdrErrorChecksEnabled(NABoolean b) 
{ currContext()->setUdrErrorChecksEnabled(b); }

void CliGlobals::setUdrSQLAccessMode(Lng32 mode) 
{ currContext()->setUdrSQLAccessMode(mode); }

void CliGlobals::setUdrAccessModeViolation(NABoolean b) 
{ currContext()->setUdrAccessModeViolation(b); }

void CliGlobals::setUdrXactViolation(NABoolean b)
{ currContext()->setUdrXactViolation(b); }

void CliGlobals::setUdrXactAborted(Int64 currTransId, NABoolean b)
{ currContext()->setUdrXactAborted(currTransId, b); }

void CliGlobals::clearUdrErrorFlags()
{ currContext()->clearUdrErrorFlags(); }

NABoolean CliGlobals::sqlAccessAllowed() 
{ return currContext()->sqlAccessAllowed(); }

void CliGlobals::getUdrErrorFlags(NABoolean &sqlViolation,
                         NABoolean &xactViolation,
                        NABoolean &xactAborted) 
{
    currContext()->getUdrErrorFlags(sqlViolation, xactViolation,
                                  xactAborted);
}

void CliGlobals::updateTransMode(TransMode *transMode)
{
  currContext()->getTransaction()->getTransMode()->
           updateTransMode(transMode);
}


void CliGlobals::initMyProgName()
{
  char    statusFileName[128];
  FILE    *status_file = 0;
  size_t  bytesRead, bytesCopy;
  char    buf[1024];
  char    *beginPtr, *endPtr;

  sprintf(statusFileName, "/proc/%d/status",getpid());
  status_file = fopen(statusFileName, "r");
  if (status_file == NULL)
    return;  //ignore error and return

  buf[0] = 0;
  if (fseek(status_file, 0, SEEK_SET))
  {
    fclose(status_file);
    return;  //ignore error and return
  }
  bytesRead = fread(buf, 1, 1024, status_file);
  if (ferror(status_file))
  {
    fclose(status_file);
    return;  //ignore error and return
  }
  fclose(status_file);
  beginPtr = strstr(buf, "Name:\t");
  if (!beginPtr)
    return;  //not found, return
  beginPtr += 6;
  endPtr = strstr(beginPtr, "\n");
  if (!endPtr || beginPtr == endPtr)
    return;  //no name found, return
  // myProgName_ is 64 bytes long, see Globals.h
  bytesCopy = (endPtr - beginPtr) < PROGRAM_NAME_LEN ?
               (endPtr - beginPtr) : PROGRAM_NAME_LEN - 1;
  memcpy(myProgName_, beginPtr, bytesCopy);
  *(myProgName_ + bytesCopy) = '\0';  // null terminates
}

#ifdef _DEBUG
// Delete the default context and all associated embedded CMP contexts
// This eventually causes dumping of all heap debug info if enabled
// Should ONLY be called right before process exits
void CliGlobals::deleteContexts()
{
  if (defaultContext_)
    {
      defaultContext_->deleteMe();
      delete defaultContext_;
      defaultContext_ = NULL;
    }
}
#endif  // _DEBUG

// The unused BMO memory quota can now be utilized by the other
// BMO instances from the same or different fragment
// In case of ESP process, the unused memory quota is maintained
// at the default context. In case of master process, the ununsed
// memory quota is maintained in statement globals

NABoolean CliGlobals::grabMemoryQuotaIfAvailable(ULng32 size)
{
  ContextCli *context;
  if (espProcess_)
     context = defaultContext_;
  else
     context = currContext();
  return context->grabMemoryQuotaIfAvailable(size);
}

void CliGlobals::resetMemoryQuota() 
{
  ContextCli *context;
  if (espProcess_)
     context = defaultContext_;
  else
     context = currContext();
  return context->resetMemoryQuota();
}

ULng32 CliGlobals::unusedMemoryQuota() 
{ 
  ContextCli *context;
  if (espProcess_)
     context = defaultContext_;
  else
     context = currContext();
  return context->unusedMemoryQuota();
}

void CliGlobals::yieldMemoryQuota(ULng32 size)
{
  ContextCli *context;
  if (espProcess_)
     context = defaultContext_;
  else
     context = currContext();
  return context->yieldMemoryQuota(size);
}

void SQ_CleanupThread(void *arg)
{
  HBaseClient_JNI::deleteInstance();
  HiveClient_JNI::deleteInstance();
}


