/**********************************************************************
// @@@ 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:         ComDiags.cpp (previously under /common)
* Description:
*
* Created:      5/6/98
* Language:     C++
*
*
****************************************************************************
*/

#include "Platform.h"



#include "NAStdlib.h"

#include "ComDiags.h"
#include "IpcMessageObj.h"
#include "str.h"
#include "Int64.h"
#include "ExpError.h"

#ifndef __EID
#include "seabed/ms.h"
#include <stdlib.h>
#include <unistd.h>
extern void releaseRTSSemaphore();  // Functions implemented in SqlStats.cpp
#include "logmxevent.h"
#endif

#include <byteswap.h>

#include "ComRtUtils.h"

#ifdef NA_DEBUG_C_RUNTIME
#include <time.h>
#include <sys/time.h>
#include "PortProcessCalls.h"
#endif


// This is a "helper" function that factors out a bunch of code
// from the packedLength() routines.

NA_EIDPROC static
inline void advanceSize(IpcMessageObjSize &size, const char * const buffPtr)
{
  const Int32 lenSize = sizeof(  Lng32);
  size += lenSize;
  if (buffPtr != NULL)
    size += str_len(buffPtr) + 1; // 1 is for the buffer's null-terminator
}

//UR2
NA_EIDPROC static
inline void advanceSize(IpcMessageObjSize &size, const NAWchar * const buffPtr)
{
  const Int32 lenSize = sizeof(  Lng32);  
  size += lenSize;
  if (buffPtr != NULL)
    size += (na_wcslen(buffPtr) + 1)*sizeof(NAWchar); // 1 is for null-terminator
}



// NA_EIDPROC
// static NABoolean isValidIsoMappingCharSet(CharInfo::CharSet cs)
// {
//   if (cs == CharInfo::ISO88591 ||
//       cs == CharInfo::SJIS     ||
//       cs == CharInfo::UTF8)
//     return TRUE;
//   else
//     return FALSE;
// }

NA_EIDPROC
static NABoolean isSingleByteCharSet(CharInfo::CharSet cs)
{
  if (cs == CharInfo::ISO88591) return TRUE;
  if (cs == CharInfo::UTF8) return TRUE; // is variable-length/width multi-byte char-set but treat it as a C/C++ string
  if (cs == CharInfo::SJIS) return TRUE; // is variable-length/width multi-byte char-set but treat it as a C/C++ string
  if (cs == CharInfo::UNICODE)  return FALSE;
#if defined(NA_NO_C_RUNTIME) || defined(__EID)
  return TRUE;	     // in exe and DP2, everything else is a single-byte cs
#else

  // a "mini-cache" to avoid proc call, for performance.
  static THREAD_P CharInfo::CharSet cachedCS    = CharInfo::UnknownCharSet;
  static THREAD_P Int32               cachedSByte = TRUE;

  if (cachedCS != cs) {
    cachedCS = cs;
    cachedSByte = (CharInfo::maxBytesPerChar(cs) == 1);
  }
  return cachedSByte;
#endif
}


// The type of message is IPC_SQL_DIAG_AREA, and the version
// is hard coded to zero here.
//
// What should the version of IpcMessageObj be set to?

ComCondition::ComCondition (CollHeap* heapPtr) :
                                         IpcMessageObj(IPC_SQL_CONDITION,0),
                                         serverName_(NULL),
                                         connectionName_(NULL),
                                         constraintCatalog_(NULL),
                                         constraintSchema_(NULL),
                                         constraintName_(NULL),
                                         triggerCatalog_(NULL),
                                         triggerSchema_(NULL),
                                         triggerName_(NULL),
                                         catalogName_(NULL),
                                         schemaName_(NULL),
                                         tableName_(NULL),
					 customSQLState_(NULL),
                                         columnName_(NULL),
                                         sqlID_(NULL),
                                         messageText_(NULL),
                                         messageLen_(0),
                                         conditionNumber_(0),
					 usageMap_(0),
                                         rowNumber_(ComCondition::INVALID_ROWNUMBER),
					 nskCode_(0),
					 numStringParamsUsed_(0),
					 numIntParamsUsed_(0),
					 flagsTBS_(0),
                                         theSQLCODE_(0),
                                         emsEventVisits_(0),
                                         // iso88591MappingCharSet_(CharInfo::UnknownCharSet),
                                         collHeapPtr_(heapPtr),
                                         isLocked_(FALSE)
{
   // Set optional string parameters to NULL
   // and optional integers to a theoretically recognizably bad value.
   for (Int32 i=NumOptionalParms; i--; ) {
      optionalString_[i]=NULL;
      optionalStringCharSet_[i]=CharInfo::UTF8;
      optionalInteger_[i]=ComDiags_UnInitialized_Int;
   }
   // Initialize fillers space to 0
   memset(fillers_, 0, sizeof(fillers_));
   // Make sure the size of ComCondition remains constant
   // If you hit this after change or add new member, adjust the fillers_ size
   Int32 classSize = sizeof(ComCondition);
#ifdef NA_64BIT
   assert(classSize == 376);
#else
   assert(classSize == 264);
#endif
}

ComCondition::ComCondition () :
                                         IpcMessageObj(IPC_SQL_CONDITION,0),
                                         serverName_(NULL),
                                         connectionName_(NULL),
                                         constraintCatalog_(NULL),
                                         constraintSchema_(NULL),
                                         constraintName_(NULL),
                                         triggerCatalog_(NULL),
                                         triggerSchema_(NULL),
                                         triggerName_(NULL),
                                         catalogName_(NULL),
                                         schemaName_(NULL),
                                         tableName_(NULL),
					 customSQLState_(NULL),
                                         columnName_(NULL),
                                         sqlID_(NULL),
                                         messageText_(NULL),
                                         messageLen_(0),
                                         conditionNumber_(0),
					 usageMap_(0),
                                         rowNumber_(ComCondition::INVALID_ROWNUMBER),
					 nskCode_(0),
					 numStringParamsUsed_(0),
					 numIntParamsUsed_(0),
					 flagsTBS_(0),
                                         theSQLCODE_(0),
                                         emsEventVisits_(0),
                                         // iso88591MappingCharSet_(CharInfo::UnknownCharSet),
                                         collHeapPtr_(NULL),
                                         isLocked_(FALSE)
{
   // Set optional string parameters to NULL
   // and optional integers to a theoretically recognizably bad value.
   for (Int32 i=NumOptionalParms; i--; ) {
      optionalString_[i]=NULL;
      optionalStringCharSet_[i]=CharInfo::UTF8;
      optionalInteger_[i]=ComDiags_UnInitialized_Int;
   }
   // Initialize fillers space to 0
   memset(fillers_, 0, sizeof(fillers_));
   // Make sure the size of ComCondition remains constant
   // If you hit this after change or add new member, adjust the fillers_ size
   Int32 classSize = sizeof(ComCondition);
#ifdef NA_64BIT
   assert(classSize == 376);
#else
   assert(classSize == 264);
#endif
}

// The destructor must free all of the char buffers which
// this object owns, and it must do so using the proper heap.

ComCondition::~ComCondition ()
{
   clear();
   collHeapPtr_=NULL;
}

// The assignment operator pretty much just copies each of
// the members over ``by hand.''

ComCondition& ComCondition::operator=(const ComCondition& c)
{
    this->IpcMessageObj::operator=(c);

    assignStringMember(serverName_,         c.serverName_);
    assignStringMember(connectionName_,     c.connectionName_);
    assignStringMember(constraintCatalog_,  c.constraintCatalog_);
    assignStringMember(constraintSchema_,   c.constraintSchema_);
    assignStringMember(constraintName_,     c.constraintName_);
    assignStringMember(triggerCatalog_,     c.triggerCatalog_);
    assignStringMember(triggerSchema_,      c.triggerSchema_);
    assignStringMember(triggerName_,        c.triggerName_);
    assignStringMember(catalogName_,        c.catalogName_);
    assignStringMember(schemaName_,         c.schemaName_);
    assignStringMember(tableName_,          c.tableName_);
    assignStringMember(customSQLState_,     c.customSQLState_);
    assignStringMember(columnName_,         c.columnName_);
    assignStringMember(sqlID_,              c.sqlID_);
    assignStringMember(messageText_,        c.messageText_);

    for (Int32 i=NumOptionalParms; i--; ) {
      if ( isSingleByteCharSet(c.optionalStringCharSet_[i]) )
         assignStringMember((char* &)optionalString_[i], (char*)c.optionalString_[i]);
      else
         assignStringMember((NAWchar*&)optionalString_[i], (NAWchar*)c.optionalString_[i]);

      optionalStringCharSet_[i] = c.optionalStringCharSet_[i];
      optionalInteger_[i] = c.optionalInteger_[i];
    }

                messageLen_ = c.messageLen_;
//           conditionNumber_ = c.conditionNumber_;
                  usageMap_ = c.usageMap_;
                 rowNumber_ = c.rowNumber_;
		   nskCode_ = c.nskCode_;
       numStringParamsUsed_ = c.numStringParamsUsed_;
	  numIntParamsUsed_ = c.numIntParamsUsed_;
                  flagsTBS_ = c.flagsTBS_;
                theSQLCODE_ = c.theSQLCODE_;
                  isLocked_ = c.isLocked_;
            emsEventVisits_ = c.emsEventVisits_;
            // iso88591MappingCharSet_ = c.iso88591MappingCharSet_;

    return *this;
}

// The clear function resets this ComCondition object to what it
// would be just after construction, EXCEPT, that the collHeapPtr_
// member is left as is.

void ComCondition::clear()
{
   if (collHeapPtr_==NULL) {

      // We delete the individual buffers, and then the elements of
      // the array of the optional string parameters.
      delete [] serverName_;
      delete [] connectionName_;
      delete [] constraintCatalog_;
      delete [] constraintSchema_;
      delete [] constraintName_;
      delete [] triggerCatalog_;
      delete [] triggerSchema_;
      delete [] triggerName_;
      delete [] catalogName_;
      delete [] schemaName_;
      delete [] tableName_;
      delete [] customSQLState_;
      delete [] columnName_;
      delete [] sqlID_;
      delete [] messageText_;

      for (Int32 i=NumOptionalParms; i--; ) {
        if (optionalString_[i])
          if ( isSingleByteCharSet(optionalStringCharSet_[i]) )
	    delete (char*)optionalString_[i];
          else
	    delete (NAWchar*)optionalString_[i];
      }
   }
   else {

     // Deallocate space for all buffers: these are simple char arrays
     // so there is no destructor to call.

     collHeapPtr_->deallocateMemory(serverName_);
     collHeapPtr_->deallocateMemory(connectionName_);
     collHeapPtr_->deallocateMemory(constraintCatalog_);
     collHeapPtr_->deallocateMemory(constraintSchema_);
     collHeapPtr_->deallocateMemory(constraintName_);
     collHeapPtr_->deallocateMemory(triggerCatalog_);
     collHeapPtr_->deallocateMemory(triggerSchema_);
     collHeapPtr_->deallocateMemory(triggerName_);
     collHeapPtr_->deallocateMemory(catalogName_);
     collHeapPtr_->deallocateMemory(schemaName_);
     collHeapPtr_->deallocateMemory(tableName_);
     collHeapPtr_->deallocateMemory(customSQLState_);
     collHeapPtr_->deallocateMemory(columnName_);
     collHeapPtr_->deallocateMemory(sqlID_);
     collHeapPtr_->deallocateMemory(messageText_);

     // Deallocate space for optional string parameters: no
     // destructor need be called.

     for (Int32 i=NumOptionalParms; i--; ) {
       if (optionalString_[i])
	 if ( isSingleByteCharSet(optionalStringCharSet_[i]) )
	    collHeapPtr_->deallocateMemory(optionalString_[i]);
	 else
	    collHeapPtr_->deallocateMemory((NAWchar*)optionalString_[i]);
     }
   }

   // Set pointers to NULL for safety, in case anybody's using
   // these pointers and shouldn't be.

   serverName_ = NULL;
   connectionName_ = NULL;
   constraintCatalog_ = NULL;
   constraintSchema_ = NULL;
   constraintName_ = NULL;
   triggerCatalog_ = NULL;
   triggerSchema_ = NULL;
   triggerName_ = NULL;
   catalogName_ = NULL;
   schemaName_ = NULL;
   tableName_ = NULL;
   customSQLState_ = NULL;
   columnName_ = NULL;
   sqlID_ = NULL;
   messageText_ = NULL;

   // set optional string parameters to NULL
   // and optional integers to a theoretically recognizably bad value.

   for (Int32 i=NumOptionalParms; i--; ) {
     optionalString_[i]=NULL;
     optionalStringCharSet_[i]=CharInfo::UTF8;
     optionalInteger_[i]=ComDiags_UnInitialized_Int;
   }

   messageLen_ = 0;
   rowNumber_ = INVALID_ROWNUMBER;
   nskCode_ = 0;
   flagsTBS_ = 0;
   conditionNumber_ = 0;
   usageMap_ = 0;
   theSQLCODE_ = 0;
   isLocked_ = FALSE;
   emsEventVisits_ = 0;
   // iso88591MappingCharSet_ = CharInfo::UnknownCharSet;

   // Reset the filler_ space to 0
   memset(fillers_, 0, sizeof(fillers_));
}

IpcMessageRefCount ComDiagsArea::decrRefCount()
{
  if (getRefCount() == 1)
    {
      deAllocate();
      return 0;
    }

  // Let base class do the work.
  return this->IpcMessageObj::decrRefCount();
}

// These IPC functions are definitions for virtual functions.
// We do not currently make (any) use of most of the
// arguments of unpackObj().

void ComCondition::unpackObj(IpcMessageObjType objType,
			     IpcMessageObjVersion objVersion,
			     NABoolean sameEndianness,
			     IpcMessageObjSize objSize,
			     IpcConstMessageBufferPtr buffer)
{
  // NOTE: changes to any of the following methods also require
  // corresponding changes in the others:
  // - packedLength()
  // - packObjIntoMessage()
  // - unpackObj()
  // - checkObj()

  NABoolean foundUprevFieldsInBuffer = FALSE;

  unpackBaseClass(buffer);
  // unconditional fields
  unpackBuffer(buffer,conditionNumber_);
  unpackBuffer(buffer,usageMap_);
  unpackBuffer(buffer,emsEventVisits_);

  // fields that are sent conditionally
  if (usageMap_ & USED_FLAGS)
    unpackBuffer(buffer,flagsTBS_);
  if (usageMap_ & USED_SQLCODE)
    unpackBuffer(buffer,theSQLCODE_);
  else
    assert(0); // should never have a missing SQLCODE field
  if (usageMap_ & USED_SERVER_NAME)
    unpackBuffer(buffer,serverName_,collHeapPtr_);
  if (usageMap_ & USED_CONNECTION_NAME)
    unpackBuffer(buffer,connectionName_,collHeapPtr_);
  if (usageMap_ & USED_CONSTRAINT_CATALOG)
    unpackBuffer(buffer,constraintCatalog_,collHeapPtr_);
  if (usageMap_ & USED_CONSTRAINT_SCHEMA)
    unpackBuffer(buffer,constraintSchema_,collHeapPtr_);
  if (usageMap_ & USED_CONSTRAINT_NAME)
    unpackBuffer(buffer,constraintName_,collHeapPtr_);
  if (usageMap_ & USED_TRIGGER_CATALOG)
    unpackBuffer(buffer,triggerCatalog_,collHeapPtr_);
  if (usageMap_ & USED_TRIGGER_SCHEMA)
    unpackBuffer(buffer,triggerSchema_,collHeapPtr_);
  if (usageMap_ & USED_TRIGGER_NAME)
    unpackBuffer(buffer,triggerName_,collHeapPtr_);
  if (usageMap_ & USED_CATALOG_NAME)
    unpackBuffer(buffer,catalogName_,collHeapPtr_);
  if (usageMap_ & USED_SCHEMA_NAME)
    unpackBuffer(buffer,schemaName_,collHeapPtr_);
  if (usageMap_ & USED_TABLE_NAME)
    unpackBuffer(buffer,tableName_,collHeapPtr_);
  if (usageMap_ & USED_COLUMN_NAME)
    unpackBuffer(buffer,columnName_,collHeapPtr_);
  if (usageMap_ & USED_SQLID)
    unpackBuffer(buffer,sqlID_,collHeapPtr_);
  if (usageMap_ & USED_ROW_NUMBER)
    unpackBuffer(buffer,rowNumber_);
  if (usageMap_ & USED_NSK_CODE)
    unpackBuffer(buffer,nskCode_);
  if (usageMap_ & USED_CUSTOM_SQLSTATE)
    unpackBuffer(buffer,customSQLState_,collHeapPtr_);
  // if (usageMap_ & USED_ISO_MAPPING_CHARSET)
  //   unpackBuffer(buffer,iso88591MappingCharSet_);

  if (usageMap_ & USED_NUM_STRING_PARAMS)
    {
      Lng32 charSet;

      unpackBuffer(buffer,numStringParamsUsed_);

      for (Int32 i=0; i < numStringParamsUsed_; i++)
	{
	  if (i < NumOptionalParms)
	    {
	      unpackBuffer(buffer, (char*&)optionalString_[i],collHeapPtr_);
	  
	      unpackBuffer(buffer,charSet);
	      optionalStringCharSet_[i] = (CharInfo::CharSet)charSet;
	    }
	  else
	    {
	      // Some future release might increase NumOptionalParms.
	      // In this case, ignore those additional parameters
	      // and set a flag indicating this.
	      skipCharStarInBuffer(buffer);
	      unpackBuffer(buffer,charSet);
	      foundUprevFieldsInBuffer = TRUE;
	    }
	}
    }

  if (usageMap_ & USED_NUM_INT_PARAMS)
    {
      Lng32 dummy;

      unpackBuffer(buffer,numIntParamsUsed_);

      for (Int32 i=0; i < numIntParamsUsed_; i++)
	{
	  if (i < NumOptionalParms)
	    {
	      unpackBuffer(buffer,optionalInteger_[i]);
	    }
	  else
	    {
	      // Some future release might increase NumOptionalParms.
	      // In this case, ignore those additional parameters
	      // and set a flag indicating this.
	      unpackBuffer(buffer,dummy);
	      foundUprevFieldsInBuffer = TRUE;
	    }
	}
    }

  // Check whether there are more fields than we expect. For certain
  // simple additions, we will not increase the version number of
  // the diagnostics area or of the ComCondition object.
  if ((usageMap_ & USED_FUTURE_FIELDS) || foundUprevFieldsInBuffer)
    flagsTBS_ |= FLAGS_TBS_SUPPRESSED_UPREV_FIELDS;
}

// These IPC functions are definitions for virtual functions.
// We do not currently make (any) use of most of the
// arguments of unpackObj().

void ComCondition::unpackObj32(IpcMessageObjType objType,
			       IpcMessageObjVersion objVersion,
			       NABoolean sameEndianness,
			       IpcMessageObjSize objSize,
			       IpcConstMessageBufferPtr buffer)
{
  // NOTE: changes to any of the following methods also require
  // corresponding changes in the others:
  // - packedLength()
  // - packObjIntoMessage()
  // - unpackObj()
  // - checkObj()

  NABoolean foundUprevFieldsInBuffer = FALSE;

  unpackBaseClass32(buffer);
  // unconditional fields
  unpackBuffer(buffer,conditionNumber_);
  unpackBuffer(buffer,usageMap_);
  unpackBuffer(buffer,emsEventVisits_);

  // fields that are sent conditionally
  if (usageMap_ & USED_FLAGS)
    unpackBuffer(buffer,flagsTBS_);
  if (usageMap_ & USED_SQLCODE)
    unpackBuffer(buffer,theSQLCODE_);
  else
    assert(0); // should never have a missing SQLCODE field
  if (usageMap_ & USED_SERVER_NAME)
    unpackBuffer(buffer,serverName_,collHeapPtr_);
  if (usageMap_ & USED_CONNECTION_NAME)
    unpackBuffer(buffer,connectionName_,collHeapPtr_);
  if (usageMap_ & USED_CONSTRAINT_CATALOG)
    unpackBuffer(buffer,constraintCatalog_,collHeapPtr_);
  if (usageMap_ & USED_CONSTRAINT_SCHEMA)
    unpackBuffer(buffer,constraintSchema_,collHeapPtr_);
  if (usageMap_ & USED_CONSTRAINT_NAME)
    unpackBuffer(buffer,constraintName_,collHeapPtr_);
  if (usageMap_ & USED_TRIGGER_CATALOG)
    unpackBuffer(buffer,triggerCatalog_,collHeapPtr_);
  if (usageMap_ & USED_TRIGGER_SCHEMA)
    unpackBuffer(buffer,triggerSchema_,collHeapPtr_);
  if (usageMap_ & USED_TRIGGER_NAME)
    unpackBuffer(buffer,triggerName_,collHeapPtr_);
  if (usageMap_ & USED_CATALOG_NAME)
    unpackBuffer(buffer,catalogName_,collHeapPtr_);
  if (usageMap_ & USED_SCHEMA_NAME)
    unpackBuffer(buffer,schemaName_,collHeapPtr_);
  if (usageMap_ & USED_TABLE_NAME)
    unpackBuffer(buffer,tableName_,collHeapPtr_);
  if (usageMap_ & USED_COLUMN_NAME)
    unpackBuffer(buffer,columnName_,collHeapPtr_);
  if (usageMap_ & USED_SQLID)
    unpackBuffer(buffer,sqlID_,collHeapPtr_);
  if (usageMap_ & USED_ROW_NUMBER)
    unpackBuffer(buffer,rowNumber_);
  if (usageMap_ & USED_NSK_CODE)
    unpackBuffer(buffer,nskCode_);
  if (usageMap_ & USED_CUSTOM_SQLSTATE)
    unpackBuffer(buffer,customSQLState_,collHeapPtr_);
  // if (usageMap_ & USED_ISO_MAPPING_CHARSET)
  //   unpackBuffer(buffer,iso88591MappingCharSet_);

  if (usageMap_ & USED_NUM_STRING_PARAMS)
    {
      Lng32 charSet;

      unpackBuffer(buffer,numStringParamsUsed_);

      for (Int32 i=0; i < numStringParamsUsed_; i++)
	{
	  if (i < NumOptionalParms)
	    {
	      unpackBuffer(buffer, (char*&)optionalString_[i],collHeapPtr_);
	  
	      unpackBuffer(buffer,charSet);
	      optionalStringCharSet_[i] = (CharInfo::CharSet)charSet;
	    }
	  else
	    {
	      // Some future release might increase NumOptionalParms.
	      // In this case, ignore those additional parameters
	      // and set a flag indicating this.
	      skipCharStarInBuffer(buffer);
	      unpackBuffer(buffer,charSet);
	      foundUprevFieldsInBuffer = TRUE;
	    }
	}
    }

  if (usageMap_ & USED_NUM_INT_PARAMS)
    {
      Lng32 dummy;

      unpackBuffer(buffer,numIntParamsUsed_);

      for (Int32 i=0; i < numIntParamsUsed_; i++)
	{
	  if (i < NumOptionalParms)
	    {
	      unpackBuffer(buffer,optionalInteger_[i]);
	    }
	  else
	    {
	      // Some future release might increase NumOptionalParms.
	      // In this case, ignore those additional parameters
	      // and set a flag indicating this.
	      unpackBuffer(buffer,dummy);
	      foundUprevFieldsInBuffer = TRUE;
	    }
	}
    }

  // Check whether there are more fields than we expect. For certain
  // simple additions, we will not increase the version number of
  // the diagnostics area or of the ComCondition object.
  if ((usageMap_ & USED_FUTURE_FIELDS) || foundUprevFieldsInBuffer)
    flagsTBS_ |= FLAGS_TBS_SUPPRESSED_UPREV_FIELDS;
}

// So for each
// integer, we take its size.  For each string, we add sizeof(long)
// to the length of the string plus 1 (except in the case of empty
// strings, that plus 1 is omitted, since NULL strings are considered
// empty and so have no buffers).
//
// Note that "long" is the type we use within the buffer
// to represent the length of a null-terminted buffer array.
//
// collHeapPtr_ is never passed via IPC; it gets setup in the constructor
// and the IPC unpack method fills in the other data using the heap
// specified in collHeapPtr_ to allocate string buffers as needed.

IpcMessageObjSize ComCondition::packedLength(void)
{
  // NOTE: changes to any of the following methods also require
  // corresponding changes in the others:
  // - packedLength()
  // - packObjIntoMessage()
  // - unpackObj()
  // - checkObj()

  IpcMessageObjSize  size=baseClassPackedLength();

  // for now we set the usageMap_ flags here, but they
  // could also be set in the accessor methods. This fields is needed
  // in method packObjIntoMessage()
  usageMap_ = 0;

  // the first two fields get sent unconditionally
  size += sizeof(conditionNumber_);
  size += sizeof(usageMap_);
  size += sizeof(emsEventVisits_);

  // all other fields get sent only when needed
  if (flagsTBS_)
    {
      size += sizeof(flagsTBS_);
      usageMap_ += USED_FLAGS;
    }
  if (theSQLCODE_)
    {
      size += sizeof(theSQLCODE_);
      usageMap_ |= USED_SQLCODE;
    }
  if (serverName_)
    {
      advanceSize(size,serverName_);
      usageMap_ |= USED_SERVER_NAME;
    }
  if (connectionName_)
    {
      advanceSize(size,connectionName_);
      usageMap_ |= USED_CONNECTION_NAME;
    }
  if (constraintCatalog_)
    {
      advanceSize(size,constraintCatalog_);
      usageMap_ |= USED_CONSTRAINT_CATALOG;
    }
  if (constraintSchema_)
    {
      advanceSize(size,constraintSchema_);
      usageMap_ |= USED_CONSTRAINT_SCHEMA;
    }
  if (constraintName_)
    {
      advanceSize(size,constraintName_);
      usageMap_ |= USED_CONSTRAINT_NAME;
    }
  if (triggerCatalog_)
    {
      advanceSize(size,triggerCatalog_);
      usageMap_ |= USED_TRIGGER_CATALOG;
    }
  if (triggerSchema_)
    {
      advanceSize(size,triggerSchema_);
      usageMap_ |= USED_TRIGGER_SCHEMA;
    }
  if (triggerName_)
    {
      advanceSize(size,triggerName_);
      usageMap_ |= USED_TRIGGER_NAME;
    }
  if (catalogName_)
    {
      advanceSize(size,catalogName_);
      usageMap_ |= USED_CATALOG_NAME;
    }
  if (schemaName_)
    {
      advanceSize(size,schemaName_);
      usageMap_ |= USED_SCHEMA_NAME;
    }
  if (tableName_)
    {
      advanceSize(size,tableName_);
      usageMap_ |= USED_TABLE_NAME;
    }
  if (columnName_)
    {
      advanceSize(size,columnName_);
      usageMap_ |= USED_COLUMN_NAME;
    }
  if (sqlID_)
    {
      advanceSize(size,sqlID_);
      usageMap_ |= USED_SQLID;
    }
  if (rowNumber_ != INVALID_ROWNUMBER)
    {
      size += sizeof(rowNumber_);
      usageMap_ |= USED_ROW_NUMBER;
    }
  if (nskCode_)
    {
      size += sizeof(nskCode_);
      usageMap_ += USED_NSK_CODE;
    }
  if (customSQLState_)
  {
    advanceSize(size,customSQLState_);
    usageMap_ |= USED_CUSTOM_SQLSTATE;
  }
//   if (isValidIsoMappingCharSet(iso88591MappingCharSet_))
//   {
//     size += sizeof(iso88591MappingCharSet_);
//     usageMap_ |= USED_ISO_MAPPING_CHARSET;
//   }
  
  // set these two variables for later use in packObjIntoMessage()
  numStringParamsUsed_  = 0;
  numIntParamsUsed_ = 0;
  for (Int32 i=NumOptionalParms; i--; )
    {
      if (optionalString_[i] && numStringParamsUsed_ == 0)
	{
	  // found the last string parameter used
	  numStringParamsUsed_ = i+1;
	  usageMap_ |= USED_NUM_STRING_PARAMS;
	  size += sizeof(numStringParamsUsed_);
	}
      if (optionalInteger_[i] != ComDiags_UnInitialized_Int &&
	  numIntParamsUsed_ == 0)
	{
	  // found the last integer parameter used
	  numIntParamsUsed_ = i+1;
	  usageMap_ |= USED_NUM_INT_PARAMS;
	  size += sizeof(numIntParamsUsed_);
	}

      if (numStringParamsUsed_ > i)
	{
	  // this string parameter needs to be sent
	  if ( isSingleByteCharSet(optionalStringCharSet_[i]) )
	    advanceSize(size,(char*)optionalString_[i]);
	  else
	    advanceSize(size,(NAWchar*)optionalString_[i]);
	  size += sizeof(Lng32); // for optionalStringCharSet_[];
	}
      if (numIntParamsUsed_ > i)
	{
	  // this integer parameter needs to be sent
	  size += sizeof(optionalInteger_[0]);
	}
    }

  return size;
}

IpcMessageObjSize ComCondition::packedLength32(void)
{
  IpcMessageObjSize size = packedLength();
  // packed items should not include Longs or pointers
  return size - (baseClassPackedLength() - baseClassPackedLength32());
}

IpcMessageObjSize ComCondition::packObjIntoMessage(char* buffer)
{
  return packObjIntoMessage(buffer, FALSE);
}

// Let us observe consistency (and thereby, hopefully, simplicity) by
// packing this object following the same order of visiting member data
// as we did in the packedLength() member function above.

IpcMessageObjSize ComCondition::packObjIntoMessage(char* buffer,
                          NABoolean swapBytes)
{
  // NOTE: changes to any of the following methods also require
  // corresponding changes in the others:
  // - packedLength()
  // - packObjIntoMessage()
  // - unpackObj()
  // - checkObj()

  IpcMessageObjSize  size=packBaseClassIntoMessage(buffer, swapBytes);

  // should have been set by packedLength()
  assert(usageMap_);

  // pack some fields unconditionally
  size += packIntoBuffer(buffer,conditionNumber_, swapBytes);
  size += packIntoBuffer(buffer,usageMap_, swapBytes);
  size += packIntoBuffer(buffer,emsEventVisits_, swapBytes);

  // fields packed conditionally
  if (usageMap_ & USED_FLAGS)
    size += packIntoBuffer(buffer,flagsTBS_, swapBytes);
  if (usageMap_ & USED_SQLCODE)
    size += packIntoBuffer(buffer,theSQLCODE_, swapBytes);
  if (usageMap_ & USED_SERVER_NAME)
    size += packCharStarIntoBuffer(buffer,serverName_, swapBytes);
  if (usageMap_ & USED_CONNECTION_NAME)
    size += packCharStarIntoBuffer(buffer,connectionName_, swapBytes);
  if (usageMap_ & USED_CONSTRAINT_CATALOG)
    size += packCharStarIntoBuffer(buffer,constraintCatalog_, swapBytes);
  if (usageMap_ & USED_CONSTRAINT_SCHEMA)
    size += packCharStarIntoBuffer(buffer,constraintSchema_, swapBytes);
  if (usageMap_ & USED_CONSTRAINT_NAME)
    size += packCharStarIntoBuffer(buffer,constraintName_, swapBytes);
  if (usageMap_ & USED_TRIGGER_CATALOG)
    size += packCharStarIntoBuffer(buffer,triggerCatalog_, swapBytes);
  if (usageMap_ & USED_TRIGGER_SCHEMA)
    size += packCharStarIntoBuffer(buffer,triggerSchema_, swapBytes);
  if (usageMap_ & USED_TRIGGER_NAME)
    size += packCharStarIntoBuffer(buffer,triggerName_, swapBytes);
  if (usageMap_ & USED_CATALOG_NAME)
    size += packCharStarIntoBuffer(buffer,catalogName_, swapBytes);
  if (usageMap_ & USED_SCHEMA_NAME)
    size += packCharStarIntoBuffer(buffer,schemaName_, swapBytes);
  if (usageMap_ & USED_TABLE_NAME)
    size += packCharStarIntoBuffer(buffer,tableName_, swapBytes);
  if (usageMap_ & USED_COLUMN_NAME)
    size += packCharStarIntoBuffer(buffer,columnName_, swapBytes);
  if (usageMap_ & USED_SQLID)
    size += packCharStarIntoBuffer(buffer,sqlID_, swapBytes);
  if (usageMap_ & USED_ROW_NUMBER)
    size += packIntoBuffer(buffer,rowNumber_, swapBytes);
  if (usageMap_ & USED_NSK_CODE)
    size += packIntoBuffer(buffer,nskCode_, swapBytes);
  if (usageMap_ & USED_CUSTOM_SQLSTATE)
    size += packCharStarIntoBuffer(buffer,customSQLState_, swapBytes);
  // if (usageMap_ & USED_ISO_MAPPING_CHARSET)
  //   size += packIntoBuffer(buffer,iso88591MappingCharSet_);
 
  // pack string parameters up to the last used one
  if (usageMap_ & USED_NUM_STRING_PARAMS)
  {
      size += packIntoBuffer(buffer,numStringParamsUsed_, swapBytes);

      for (Int32 i=0; i < numStringParamsUsed_; i++)
	{
	  if ( isSingleByteCharSet(optionalStringCharSet_[i]) )
	    size += packCharStarIntoBuffer(buffer,
                      (char*)optionalString_[i], swapBytes);
	  else
	    size += packCharStarIntoBuffer(buffer,
			   (NAWchar*)optionalString_[i], swapBytes);
	  
	  size += packIntoBuffer(buffer,(Lng32)optionalStringCharSet_[i], swapBytes);
	}
    }

  // pack integer parameters up to the last used one
  if (usageMap_ & USED_NUM_INT_PARAMS)
    {
      size += packIntoBuffer(buffer, numIntParamsUsed_, swapBytes);
      for (Int32 i=0; i < numIntParamsUsed_; i++)
	{
	  size += packIntoBuffer(buffer,optionalInteger_[i], swapBytes);
	}
    }

  return size;
}

IpcMessageObjSize ComCondition::packObjIntoMessage32(char* buffer)
{
  return packObjIntoMessage32(buffer, FALSE);
}

// Let us observe consistency (and thereby, hopefully, simplicity) by
// packing this object following the same order of visiting member data
// as we did in the packedLength() member function above.

IpcMessageObjSize ComCondition::packObjIntoMessage32(char* buffer,
                          NABoolean swapBytes)
{
  // NOTE: changes to any of the following methods also require
  // corresponding changes in the others:
  // - packedLength32()
  // - packObjIntoMessage32()
  // - unpackObj()
  // - checkObj()

  IpcMessageObjSize  size=packBaseClassIntoMessage32(buffer, swapBytes);

  // should have been set by packedLength()
  assert(usageMap_);

  // pack some fields unconditionally
  size += packIntoBuffer(buffer,conditionNumber_, swapBytes);
  size += packIntoBuffer(buffer,usageMap_, swapBytes);
  size += packIntoBuffer(buffer,emsEventVisits_, swapBytes);

  // fields packed conditionally
  if (usageMap_ & USED_FLAGS)
    size += packIntoBuffer(buffer,flagsTBS_, swapBytes);
  if (usageMap_ & USED_SQLCODE)
    size += packIntoBuffer(buffer,theSQLCODE_, swapBytes);
  if (usageMap_ & USED_SERVER_NAME)
    size += packCharStarIntoBuffer(buffer,serverName_, swapBytes);
  if (usageMap_ & USED_CONNECTION_NAME)
    size += packCharStarIntoBuffer(buffer,connectionName_, swapBytes);
  if (usageMap_ & USED_CONSTRAINT_CATALOG)
    size += packCharStarIntoBuffer(buffer,constraintCatalog_, swapBytes);
  if (usageMap_ & USED_CONSTRAINT_SCHEMA)
    size += packCharStarIntoBuffer(buffer,constraintSchema_, swapBytes);
  if (usageMap_ & USED_CONSTRAINT_NAME)
    size += packCharStarIntoBuffer(buffer,constraintName_, swapBytes);
  if (usageMap_ & USED_TRIGGER_CATALOG)
    size += packCharStarIntoBuffer(buffer,triggerCatalog_, swapBytes);
  if (usageMap_ & USED_TRIGGER_SCHEMA)
    size += packCharStarIntoBuffer(buffer,triggerSchema_, swapBytes);
  if (usageMap_ & USED_TRIGGER_NAME)
    size += packCharStarIntoBuffer(buffer,triggerName_, swapBytes);
  if (usageMap_ & USED_CATALOG_NAME)
    size += packCharStarIntoBuffer(buffer,catalogName_, swapBytes);
  if (usageMap_ & USED_SCHEMA_NAME)
    size += packCharStarIntoBuffer(buffer,schemaName_, swapBytes);
  if (usageMap_ & USED_TABLE_NAME)
    size += packCharStarIntoBuffer(buffer,tableName_, swapBytes);
  if (usageMap_ & USED_COLUMN_NAME)
    size += packCharStarIntoBuffer(buffer,columnName_, swapBytes);
  if (usageMap_ & USED_SQLID)
    size += packCharStarIntoBuffer(buffer,sqlID_, swapBytes);
  if (usageMap_ & USED_ROW_NUMBER)
    size += packIntoBuffer(buffer,rowNumber_, swapBytes);
  if (usageMap_ & USED_NSK_CODE)
    size += packIntoBuffer(buffer,nskCode_, swapBytes);
  if (usageMap_ & USED_CUSTOM_SQLSTATE)
    size += packCharStarIntoBuffer(buffer,customSQLState_, swapBytes);
  // if (usageMap_ & USED_ISO_MAPPING_CHARSET)
  //   size += packIntoBuffer(buffer,iso88591MappingCharSet_);
 
  // pack string parameters up to the last used one
  if (usageMap_ & USED_NUM_STRING_PARAMS)
  {
      size += packIntoBuffer(buffer,numStringParamsUsed_, swapBytes);

      for (Int32 i=0; i < numStringParamsUsed_; i++)
	{
	  if ( isSingleByteCharSet(optionalStringCharSet_[i]) )
	    size += packCharStarIntoBuffer(buffer,
                      (char*)optionalString_[i], swapBytes);
	  else
	    size += packCharStarIntoBuffer(buffer,
			   (NAWchar*)optionalString_[i], swapBytes);
	  
	  size += packIntoBuffer(buffer,(Lng32)optionalStringCharSet_[i], swapBytes);
	}
    }

  // pack integer parameters up to the last used one
  if (usageMap_ & USED_NUM_INT_PARAMS)
    {
      size += packIntoBuffer(buffer, numIntParamsUsed_, swapBytes);
      for (Int32 i=0; i < numIntParamsUsed_; i++)
	{
	  size += packIntoBuffer(buffer,optionalInteger_[i], swapBytes);
	}
    }

  return size;
}

NABoolean ComCondition::checkObj(IpcMessageObjType objType,
                                 IpcMessageObjVersion objVersion,
                                 NABoolean sameEndianness,
                                 IpcMessageObjSize objSize,
                                 IpcConstMessageBufferPtr buffer) const
{
  // NOTE: changes to any of the following methods also require
  // corresponding changes in the others:
  // - packedLength()
  // - packObjIntoMessage()
  // - unpackObj()
  // - checkObj()

  const IpcConstMessageBufferPtr lastByte = buffer + objSize - 1;

  if (!checkBaseClass(objType, objVersion, sameEndianness, objSize, buffer))
    return FALSE;

  // Some fields are packed unconditionally
  if (!checkBuffer(buffer, sizeof(conditionNumber_), lastByte))
    return FALSE;

  Int32  map = 0;
  if (!checkAndUnpackBuffer(buffer, sizeof(map), (char *) &map, lastByte))
    return FALSE;
  if (!sameEndianness)
    swapFourBytes(map);
  
  if (!checkBuffer(buffer, sizeof(emsEventVisits_), lastByte))
    return FALSE;

  // Some fields are packed conditionally
  if (map & USED_FLAGS)
    if (!checkBuffer(buffer, sizeof(flagsTBS_), lastByte))
      return FALSE;
  
  if (map & USED_SQLCODE)
  {
    if (!checkBuffer(buffer, sizeof(theSQLCODE_), lastByte))
      return FALSE;
  }
  else
  {
    return FALSE;
  }
  
  if (map & USED_SERVER_NAME)
    if (!checkCharStarInBuffer(buffer, sameEndianness, lastByte))
      return FALSE;
  if (map & USED_CONNECTION_NAME)
    if (!checkCharStarInBuffer(buffer, sameEndianness, lastByte))
      return FALSE;
  if (map & USED_CONSTRAINT_CATALOG)
    if (!checkCharStarInBuffer(buffer, sameEndianness, lastByte))
      return FALSE;
  if (map & USED_CONSTRAINT_SCHEMA)
    if (!checkCharStarInBuffer(buffer, sameEndianness, lastByte))
      return FALSE;
  if (map & USED_CONSTRAINT_NAME)
    if (!checkCharStarInBuffer(buffer, sameEndianness, lastByte))
      return FALSE;
  if (map & USED_TRIGGER_CATALOG)
    if (!checkCharStarInBuffer(buffer, sameEndianness, lastByte))
      return FALSE;
  if (map & USED_TRIGGER_SCHEMA)
    if (!checkCharStarInBuffer(buffer, sameEndianness, lastByte))
      return FALSE;
  if (map & USED_TRIGGER_NAME)
    if (!checkCharStarInBuffer(buffer, sameEndianness, lastByte))
      return FALSE;
  if (map & USED_CATALOG_NAME)
    if (!checkCharStarInBuffer(buffer, sameEndianness, lastByte))
      return FALSE;
  if (map & USED_SCHEMA_NAME)
    if (!checkCharStarInBuffer(buffer, sameEndianness, lastByte))
      return FALSE;
  if (map & USED_TABLE_NAME)
    if (!checkCharStarInBuffer(buffer, sameEndianness, lastByte))
      return FALSE;
  if (map & USED_COLUMN_NAME)
    if (!checkCharStarInBuffer(buffer, sameEndianness, lastByte))
      return FALSE;
  if (map & USED_SQLID)
    if (!checkCharStarInBuffer(buffer, sameEndianness, lastByte))
      return FALSE;
  if (map & USED_ROW_NUMBER)
    if (!checkBuffer(buffer, sizeof(rowNumber_), lastByte))
      return FALSE;
  if (map & USED_NSK_CODE)
    if (!checkBuffer(buffer, sizeof(nskCode_), lastByte))
      return FALSE;
  if (map & USED_CUSTOM_SQLSTATE)
    if (!checkCharStarInBuffer(buffer, sameEndianness, lastByte))
      return FALSE;
  // if (map & USED_ISO_MAPPING_CHARSET)
  //   if (!checkBuffer(buffer, sizeof(iso88591MappingCharSet_), lastByte))
  //     return FALSE;

  // Optional string parameters
  if (map & USED_NUM_STRING_PARAMS)
  {
    Int32  numParams = 0;
    if (!checkAndUnpackBuffer(buffer, sizeof(numParams),
                              (char *) &numParams, lastByte))
      return FALSE;
    if (!sameEndianness)
      swapFourBytes(numParams);
    
    for (Lng32 i = 0; i < numParams; i++)
    {
      if (!checkCharStarInBuffer(buffer, sameEndianness, lastByte))
        return FALSE;
      if (!checkBuffer(buffer, sizeof(Lng32), lastByte)) // character set
        return FALSE;
    }
  }
  
  // Optional integer parameters
  if (map & USED_NUM_INT_PARAMS)
  {
    Int32  numParams = 0;
    if (!checkAndUnpackBuffer(buffer, sizeof(numParams),
                              (char *) &numParams, lastByte))
      return FALSE;
    if (!sameEndianness)
      swapFourBytes(numParams);
    
    for (Lng32 i = 0; i < numParams; i++)
      if (!checkBuffer(buffer, sizeof(Lng32), lastByte))
        return FALSE;
  }
  
  return TRUE;
}

// The set methods.
//
// Questions
//
// * Since each of these member functions is so similar, how about
//   using C++ templates, or some mechanism, to factor the code?
//
// * Would the ``properties'' trick, shown in C++ Report magazine do the
//   job?
//
// The pattern for how set strings

void ComCondition::setServerName         (const char *const name)
{
   assert(!isLocked_);
   assignStringMember(serverName_,name);
}

// We can use this function in each of the char* ``set'' routines
// of the ComCondition class.

// UR2
void ComCondition::assignStringMember(NAWchar *& memberBuff,const NAWchar *const src)
{
   if (collHeapPtr_ != NULL) {
      // Just a char array, so no destructor call.
      collHeapPtr_->deallocateMemory(memberBuff);
   }
   else
      delete [] memberBuff;
   memberBuff=NULL;  // now memberBuff is cleared...

   // if src is non-NULL then we need to create a buff, copy it over...
   if (src != NULL) {
     UInt32 sourceLen = na_wcslen(src);       // length in wide characters
     UInt32 buffsize = (sourceLen + 1) * sizeof(NAWchar); // length in bytes
     if (collHeapPtr_ != NULL) {
       // Just a char array, so no construction needed.
       memberBuff = (NAWchar*) (collHeapPtr_->allocateMemory(buffsize));
       assert(memberBuff != NULL);
     }
     else {
       memberBuff = new NAWchar[sourceLen + 1];
       assert(memberBuff != NULL);
     }
     na_wcscpy(memberBuff,src);
     memberBuff[sourceLen] = 0;
   }
}

void ComCondition::assignStringMember(char *& memberBuff,const char *const src)
{
   if (collHeapPtr_ != NULL) {
      // Just a char array, so no destructor call.
      collHeapPtr_->deallocateMemory(memberBuff);
   }
   else
      delete [] memberBuff;
   memberBuff=NULL;  // now memberBuff is cleared...

   // if src is non-NULL then we need to create a buff, copy it over...
   if (src != NULL) {
     UInt32     buffsize = str_len(src) + 1;
     if (collHeapPtr_ != NULL) {
       // Just a char array, so no construction needed.
       memberBuff = (char*) (collHeapPtr_->allocateMemory(buffsize));
       assert(memberBuff != NULL);
     }
     else {
       memberBuff = new char[buffsize];
       assert(memberBuff != NULL);
     }
#pragma nowarn(1506)   // warning elimination 
     str_cpy(memberBuff,src,buffsize);
#pragma warn(1506)  // warning elimination 
     memberBuff[buffsize-1]=0;
   }
}

// Now we continue with the rest of the code for implementing the
// string-set functions.

void ComCondition::setConnectionName     (const char *const name)
{
   assert(!isLocked_);
   assert(name != NULL);
   assignStringMember(connectionName_,name);
}

void ComCondition::setConstraintCatalog  (const char *const catalog)
{
   assert(!isLocked_);
   assert(catalog != NULL);
   assignStringMember(constraintCatalog_,catalog);
}

void ComCondition::setConstraintSchema   (const char *const schema)
{
   assert(!isLocked_);
   assert(schema != NULL);
   assignStringMember(constraintSchema_,schema);
}

void ComCondition::setConstraintName     (const char *const name)
{
   assert(!isLocked_);
   assert(name != NULL);
   assignStringMember(constraintName_,name);
}

void ComCondition::setTriggerCatalog  (const char *const catalog)
{
   assert(!isLocked_);
   assert(catalog != NULL);
   assignStringMember(triggerCatalog_,catalog);
}

void ComCondition::setTriggerSchema   (const char *const schema)
{
   assert(!isLocked_);
   assert(schema != NULL);
   assignStringMember(triggerSchema_,schema);
}

void ComCondition::setTriggerName     (const char *const name)
{
   assert(!isLocked_);
   assert(name != NULL);
   assignStringMember(triggerName_,name);
}

void ComCondition::setCatalogName        (const char *const name)
{
   assert(!isLocked_);
   assert(name != NULL);
   assignStringMember(catalogName_,name);
}

void ComCondition::setSchemaName         (const char *const name)
{
   assert(!isLocked_);
   assert(name != NULL);
   assignStringMember(schemaName_,name);
}

void ComCondition::setTableName          (const char *const name)
{
   assert(!isLocked_);
   assert(name != NULL);
   assignStringMember(tableName_,name);
}

void ComCondition::setCustomSQLState     (const char *const customSQLState)
{
   assert(!isLocked_);
   assert(customSQLState != NULL);
   assignStringMember(customSQLState_,customSQLState);
}

void ComCondition::setColumnName         (const char *const name)
{
   assert(!isLocked_);
   assert(name != NULL);
   assignStringMember(columnName_,name);
}

void ComCondition::setSqlID         (const char *const name)
{
   assert(!isLocked_);
   assert(name != NULL);
   assignStringMember(sqlID_,name);
}

// Now we have three members which are concerned with setting intlike
// values.

void ComCondition::setConditionNumber(ComDiagBigInt newCondition)
{
   conditionNumber_ = newCondition;
}

#ifndef __EID
#endif // no __EID

void ComCondition::setSQLCODE (Lng32 newSQLCODE)
{
  theSQLCODE_ = newSQLCODE;

#ifndef __EID

  if ( ! (theSQLCODE_ < 0) ) return; // if not an error return

  Lng32 theError = (theSQLCODE_ < 0) ? -theSQLCODE_ : theSQLCODE_;
  
  char  *reqErrorStr = NULL;  // user requested error to loop/abort on
  Lng32  reqError = 0;

  if ( reqErrorStr = getenv("LOOP_ON_ERROR") ) {
    reqError = strtol( reqErrorStr, (char **)NULL, 10) ;
    if ( reqError > INT_MIN && reqError < INT_MAX &&  // no error in env var
	 reqError == theError ) // and this one is the requested error 
      {
	UInt32 timeDelay = 3 ; // 3 seconds
	short loopCount = 60; // 60 * 3 seconds = 3 minutes
	Lng32 loopError = 1;
      
	while ( loopError ) // To exit loop in gdb do: set var loopError=0
	  {
#ifdef NA_DEBUG_C_RUNTIME
            // In the debug build, notify the user we are looping by
            // printing to stdout every 60 seconds
            if (loopCount % 20 == 0)
            {
              NAProcessHandle myPhandle;
              myPhandle.getmine();
              myPhandle.decompose();
              int pid = (int) myPhandle.getPin();
              int node = (int) myPhandle.getNodeNumber();
              
              char timeString[40];
              timeval tv;
              tm tx;
              gettimeofday(&tv, NULL);
              localtime_r(&tv.tv_sec, &tx);
              snprintf(timeString, 40, "%04d-%02d-%02d %02d:%02d:%02d.%06d",
                      tx.tm_year + 1900, tx.tm_mon + 1, tx.tm_mday,
                      tx.tm_hour, tx.tm_min, tx.tm_sec, (int) tv.tv_usec);
              
              printf("(%d,%d) %s LOOP_ON_ERROR %d\n",
                     node, pid, timeString, (int) theError);
              fflush(stdout);
            }
#endif

	    // log a message (with the process ID) every three minutes
	    if ( loopCount == 60 )
	      SQLMXLoggingArea::logSQLMXDebugEvent("Loop on error", reqError,__LINE__);

	    // Suspend the process for 'timeDelay'
	    sleep( timeDelay );
	    
	    loopCount = (loopCount == 1) ? 60 : --loopCount;
	  }
      }
  }

  if ( reqErrorStr = getenv("ABORT_ON_ERROR") ) {
    reqError = strtol( reqErrorStr, (char **)NULL, 10) ;
    if ( reqError > INT_MIN && reqError < INT_MAX &&  // no error in env var
	 reqError == theError ) // and this one is the requested error 
      {
	releaseRTSSemaphore();

	// log a message
	SQLMXLoggingArea::logSQLMXDebugEvent("Abort on error", reqError,__LINE__);

	abort();  // dump core
      }
  }

// LCOV_EXCL_START
// This code has been unit tested and most is also tested by
// executor/TEST082
  if ((theError == CLI_TCB_EXECUTE_ERROR) ||  // 8816
      (theError == CLI_INTERNAL_ERROR   ) ||  // 8898
      (theError == EXE_INTERNAL_ERROR   ))    // 8001
  {
     // make a core-file to help understand this scenario.  But do 
     // return the error to the user.  Notice that this Linux-only
     // code is not compiled for EID.  If this behavior make problems,
     // it can be controlled by setting envvars .
     static bool InternErrorMakesCorefileInitialized = false;
     static bool corefile8816 = false;
     static bool corefile8898 = false;
     static bool corefile8001 = false;
     if (!InternErrorMakesCorefileInitialized)
     {
       InternErrorMakesCorefileInitialized = true;
       char *envvar = NULL;
       envvar = getenv("SQLMX_COREFILE_8816");
       if (envvar && envvar[0] == '1')
         corefile8816 = true;
       envvar = getenv("SQLMX_COREFILE_8898");
       if (envvar && envvar[0] == '1')
         corefile8898 = true;
       envvar = getenv("SQLMX_COREFILE_8001");
       if (envvar && envvar[0] == '1')
         corefile8001 = true;
     }
     if ( (corefile8816 && theError == CLI_TCB_EXECUTE_ERROR) ||
          (corefile8898 && theError == CLI_INTERNAL_ERROR   ) ||
          (corefile8001 && theError == EXE_INTERNAL_ERROR   ) )
       genLinuxCorefile( (char *)
         "Generating core-file to capture internal error scenario.");
  }
// LCOV_EXCL_STOP

#endif // no __EID
}

void ComCondition::setRowNumber(  Lng32 newRowNumber)
{
   rowNumber_ = newRowNumber;
}

void ComCondition::setNskCode(  Lng32 newNskCode)
{
   nskCode_ = newNskCode;

#ifndef __EID
   // LCOV_EXCL_START
   char *reqErrorStr = NULL;
   Lng32 reqError = 0;

   if ( reqErrorStr = getenv("LOOP_ON_NSK_ERROR") )
   {
     reqError = strtol(reqErrorStr, (char **)NULL, 10);
     if ( reqError > INT_MIN && reqError < INT_MAX &&  // no error in env var
          reqError == newNskCode ) // and this one is the requested NSK error
     {
       UInt32 timeDelay = 3; // 3 seconds
       short loopCount = 60; // 60 * 3 seconds = 3 minutes
       Lng32 loopError = 1;
      
       while ( loopError ) // To exit loop in gdb do: set var loopError=0
       {
         // log a message (with the process ID) every three minutes
         if ( loopCount == 60 )
           SQLMXLoggingArea::logSQLMXDebugEvent("Loop on error", reqError,__LINE__);

         // Suspend the process for 'timeDelay'
         sleep( timeDelay );

         loopCount = (loopCount == 1) ? 60 : --loopCount;
       }
     }
   }

   if ( reqErrorStr = getenv("ABORT_ON_NSK_ERROR") )
   {
     reqError = strtol(reqErrorStr, (char **)NULL, 10);
     if ( reqError > INT_MIN && reqError < INT_MAX &&  // no error in env var
          reqError == newNskCode ) // and this one is the requested NSK error 
     {
       releaseRTSSemaphore();

       // log a message
       SQLMXLoggingArea::logSQLMXDebugEvent("Abort on NSK error", reqError,__LINE__);

       abort();  // dump core
     }
   }
   // LCOV_EXCL_STOP
#endif // no __EID
}

// Getting and Setting the Optional Parameters

Lng32 ComCondition::getOptionalInteger(Lng32     index) const
{
   assert(index < NumOptionalParms);
   // add the following to prevent false alarm on "index"
   // without considering the above assert
   // coverity[overrun_local]
   return optionalInteger_[index];
}

void ComCondition::setOptionalInteger(Lng32     index, Lng32 newValue)
{
   assert(index < NumOptionalParms);
   // add the following to prevent false alarm on "index"
   // without considering the above assert
   // coverity[overrun_local]
   optionalInteger_[index] = newValue;
}

CharInfo::CharSet 
ComCondition::getOptionalStringCharSet(Lng32 index) const
{
   assert(index < NumOptionalParms);
   // add the following to prevent false alarm on "index"
   // without considering the above assert
   // coverity[overrun_local]
   return optionalStringCharSet_[index];
}

NABoolean ComCondition::hasOptionalString(Lng32 index) const
{
   assert(index < NumOptionalParms);

   return optionalString_[index] != NULL;
}

const char * ComCondition::getOptionalString(Lng32 index) const
{
   assert(index < NumOptionalParms);
   // add the following to prevent false alarm on "index"
   // without considering the above assert
   // coverity[overrun_local]
   if (isSingleByteCharSet(optionalStringCharSet_[index]))
     return (const char*)optionalString_[index];
   return NULL;
}

const NAWchar *
ComCondition::getOptionalWString(Lng32 index) const
{
   assert(index < NumOptionalParms);
   // add the following to prevent false alarm on "index"
   // without considering the above assert
   // coverity[overrun_local]
   if (optionalString_[index] == NULL)
     return NULL;
   if (! isSingleByteCharSet(optionalStringCharSet_[index]))
     return (const NAWchar*)optionalString_[index];
   return NULL;
}

void ComCondition::setOptionalString(Lng32 index,
	const char* const source,
	CharInfo::CharSet cs)
{
   if (isSingleByteCharSet(cs)) {
     // Do NOT "assert(source != NULL);" -- it's ok to pass in a NULL string
     assert(index < NumOptionalParms);
     // add the following to prevent false alarm on "index"
     // without considering the above assert
     // coverity[overrun_local]
     optionalStringCharSet_[index] = cs;
     assignStringMember((char*&)optionalString_[index],source);
   }
   else
     setOptionalWString(index, (NAWchar*)source);
}

void ComCondition::setOptionalWString(Lng32 index,
	const NAWchar* const source)
	// CharInfo::CharSet cs)		##hardcoded for now
{
   CharInfo::CharSet cs = CharInfo::UNICODE;	//hardcoded
   // if (! isSingleByteCharSet(cs)) { ...as above...

   // Do NOT "assert(source != NULL);" -- it's ok to pass in a NULL string
   assert(index < NumOptionalParms);
   // add the following to prevent false alarm on "index"
   // without considering the above assert
   // coverity[overrun_local]
   optionalStringCharSet_[index] = cs;
   assignStringMember((NAWchar*&)optionalString_[index],source);
}

// CharInfo::CharSet
// ComCondition::getIso88591MappingCharSet() const
// {
//   // Return CharInfo::UnknownCharSet if the data member not set yet
//   if ((usageMap_ & USED_ISO_MAPPING_CHARSET) &&
//       isValidIsoMappingCharSet(iso88591MappingCharSet_))
//     return iso88591MappingCharSet_;
//   else
//     return CharInfo::UnknownCharSet;
// }

// void ComCondition::setIso88591MappingCharSet(CharInfo::CharSet cs)
// {
//   // assert(isValidIsoMappingCharSet(cs));
//   usageMap_ |= USED_ISO_MAPPING_CHARSET;
//   iso88591MappingCharSet_ = cs;
// }

//  ComDiags Methods Implemented
//

ComDiagsArea::ComDiagsArea (CollHeap* ptr): IpcMessageObj(IPC_SQL_DIAG_AREA,0),
                                            collHeapPtr_(ptr),
                                            errors_(ptr),
                                            warnings_(ptr),
                                            newCondition_(NULL),
					    lengthLimit_(30),
                                            areMore_(ComCondition::NO_MORE),
                                            maxDiagsId_(0),
                                            rowCount_(0),
                                            avgStreamWaitTime_(-1),
                                            cost_(0),
                                            theSQLFunction_(NULL_FUNCTION),
                                            flags_(0),
					    rowsetRowCountArray_(NULL)
{
   // Initialize fillers space to 0
   memset(fillers_, 0, sizeof(fillers_));
   // Make sure the size of ComDiagsArea remains constant
   // If you hit this after change or add new member, adjust the fillers_ size
   Int32 classSize = sizeof(ComDiagsArea);
#ifdef NA_64BIT
   // dg64 - size changed
   assert(classSize == 328);
#else
   assert(classSize == 240);
#endif
}

ComDiagsArea::ComDiagsArea () :             IpcMessageObj(IPC_SQL_DIAG_AREA,0),
                                            collHeapPtr_(NULL),
                                            errors_(NULL),
                                            warnings_(NULL),
                                            newCondition_(NULL),
					    lengthLimit_(30),
                                            areMore_(ComCondition::NO_MORE),
                                            maxDiagsId_(0),
                                            rowCount_(0),
                                            avgStreamWaitTime_(-1),
                                            cost_(0),
                                            theSQLFunction_(NULL_FUNCTION),
                                            flags_(0),
					    rowsetRowCountArray_(NULL)
{
   // Initialize fillers space to 0
   memset(fillers_, 0, sizeof(fillers_));
   // Make sure the size of ComDiagsArea remains constant
   // If you hit this after change or add new member, adjust the fillers_ size
   Int32 classSize = sizeof(ComDiagsArea);


#ifndef NA_64BIT
   assert(classSize == 240);
#else
   // if (classSize != 320) printf("classSize=%d @ %d\n", classSize, __LINE__);
   // dg64 - size changed
   assert(classSize == 328);
#endif
}


// We want to clear out the errors and warnings lists, and free
// the objects contained therein.  We want to set collHeapPtr_ to
// NULL (just in case!).
//
// Questions
//
// * Is there a better way to iterate over all members of a LIST?

ComDiagsArea::~ComDiagsArea ()
{
   CollIndex i=0;
   while (i!=errors_.entries())        errors_[i++]->deAllocate();
   i=0;
   while (i!=warnings_.entries())      warnings_[i++]->deAllocate();
   if (newCondition_ != NULL) {
      newCondition_->deAllocate();
      newCondition_=NULL;
   }
   errors_.clear();
   warnings_.clear();
   flags_ = 0;
   if (rowsetRowCountArray_ != NULL) {
    rowsetRowCountArray_->deallocate();
    rowsetRowCountArray_ = NULL;
   }
}

void ComDiagsArea::enforceLengthLimit()
{
   const Lng32     currentCount = getNumber();
   if ((lengthLimit_ != ComCondition::NO_LIMIT_ON_ERROR_CONDITIONS) &&
	(currentCount > lengthLimit_)) {
        Lng32 numToDiscard = currentCount - lengthLimit_;
	// soln:10-050204-4441 : maxDiagsId_ member needs to be updated so as to 
        // maintain consistency between count(error) + count(warnings) and maxDiagsId_
        // upon exceeding lengthLimit_.This is done here as numToDiscard is modified 
	// in this function.
        maxDiagsId_ = maxDiagsId_ - numToDiscard;
      if (numToDiscard > (Lng32) warnings_.entries()) {
         assert(errors_.entries() >= (numToDiscard-warnings_.entries()));

         // First, drop all warnings.
         CollIndex i=0;
         while (i!=warnings_.entries())      warnings_[i++]->deAllocate();
         warnings_.clear();

         // Second, drop the proper number of errors from the end of the list.
         // make errors a sequence 1..j, where j = errors_.entries() -
         //                             (numToDiscard-warnings_.entries())

#pragma nowarn(1506)   // warning elimination 
         numToDiscard =  numToDiscard - warnings_.entries();
#pragma warn(1506)  // warning elimination 
         CollIndex j = errors_.entries() - numToDiscard;
         while (numToDiscard-- != 0) {
            errors_[j]->deAllocate();// remove near end and slide towards front
            NABoolean removeResult = errors_.removeAt(j);
            assert(removeResult);  // sanity check
         }
	 areMore_ = ComCondition::MORE_ERRORS ;
      }
      else {
         // make warnings a sequence 1..j, where j = warnings_.entries() -
         //                                          numToDiscard
         CollIndex j = warnings_.entries() - numToDiscard;
         while (numToDiscard-- != 0) {
            warnings_[j]->deAllocate();// remove near end and slide towards front
            NABoolean removeResult = warnings_.removeAt(j);
            assert(removeResult);  // sanity check
         }
	 areMore_ = ComCondition::MORE_WARNINGS ;
      }
   }
}


void ComDiagsArea::unpackObj(IpcMessageObjType objType,
                             IpcMessageObjVersion objVersion,
                             Int32  sameEndianness,
                             IpcMessageObjSize objSize,
                             const char* buffer)
{
  // NOTE: changes to any of the following methods also require
  // corresponding changes in the others:
  // - packedLength()
  // - packObjIntoMessage()
  // - unpackObj()
  // - checkObj()

  short extraFieldsLen;

  assert(newCondition_ == NULL);
  // rowsetRowCountArray should be null as it is shipped across process boundaries.
  assert(rowsetRowCountArray_ == NULL);
  unpackBaseClass(buffer);
  unpackBuffer(buffer,areMore_);
  unpackBuffer(buffer,lengthLimit_);
  unpackBuffer(buffer,rowCount_);
  unpackBuffer(buffer,avgStreamWaitTime_);
  unpackBuffer(buffer,cost_);
  unpackBuffer(buffer,theSQLFunction_);
  unpackBuffer(buffer,maxDiagsId_);
  unpackBuffer(buffer,flags_);
  // length of fields added in a later version, just skip them
  unpackBuffer(buffer,extraFieldsLen);
  buffer += extraFieldsLen;

    short  num;
  unpackBuffer(buffer,num);
  CollIndex index=0;
  while (index!=(CollIndex)num) {
     // don't forget to append a new object...created on which heap
     // is the right one!
     DiagsCondition  *newObject = DiagsCondition::allocate(collHeapPtr_);
     assert(newObject != NULL);
     newObject->unpackDependentObjFromBuffer(buffer, sameEndianness);
     errors_.insert(newObject);
     index++;
  }
  unpackBuffer(buffer,num);
  index = 0;
  while (index!=(CollIndex) num) {
     // don't forget to append a new object...created on which heap
     // is the right one!  And, yes, it's true that this loop body
     // is a copy/paste of the loop body of the above while loop.
     DiagsCondition  *newObject = DiagsCondition::allocate(collHeapPtr_);
     assert(newObject != NULL);
     newObject->unpackDependentObjFromBuffer(buffer, sameEndianness);
     warnings_.insert(newObject);
     index++;
  }
  if (lengthLimit_ != ComCondition::NO_LIMIT_ON_ERROR_CONDITIONS)
    assert( getNumber() <= lengthLimit_ );

  // unpack fillers_ part
  unpackStrFromBuffer(buffer, fillers_, sizeof(fillers_));
}


// unpack ComDiagsArea sent from 32-bit (BDR) server
void ComDiagsArea::unpackObj32(IpcMessageObjType objType,
                               IpcMessageObjVersion objVersion,
                               Int32  sameEndianness,
                               IpcMessageObjSize objSize,
                               const char* buffer)
{
  // NOTE: changes to any of the following methods also require
  // corresponding changes in the others:
  // - packedLength()
  // - packObjIntoMessage()
  // - unpackObj()
  // - checkObj()

  short extraFieldsLen;

  assert(newCondition_ == NULL);
  // rowsetRowCountArray should be null as it is shipped across process boundaries.
  assert(rowsetRowCountArray_ == NULL);
  unpackBaseClass32(buffer);
  unpackBuffer(buffer,areMore_);
  unpackBuffer(buffer,lengthLimit_);
  unpackBuffer(buffer,rowCount_);
  unpackBuffer(buffer,avgStreamWaitTime_);
  unpackBuffer(buffer,cost_);
  unpackBuffer(buffer,theSQLFunction_);
  unpackBuffer(buffer,maxDiagsId_);
  unpackBuffer(buffer,flags_);
  // length of fields added in a later version, just skip them
  unpackBuffer(buffer,extraFieldsLen);
  buffer += extraFieldsLen;

    short  num;
  unpackBuffer(buffer,num);
  CollIndex index=0;
  while (index!=(CollIndex)num) {
     // don't forget to append a new object...created on which heap
     // is the right one!
     DiagsCondition  *newObject = DiagsCondition::allocate(collHeapPtr_);
     assert(newObject != NULL);
     newObject->unpackDependentObjFromBuffer32(buffer, sameEndianness);
     errors_.insert(newObject);
     index++;
  }
  unpackBuffer(buffer,num);
  index = 0;
  while (index!=(CollIndex) num) {
     // don't forget to append a new object...created on which heap
     // is the right one!  And, yes, it's true that this loop body
     // is a copy/paste of the loop body of the above while loop.
     DiagsCondition  *newObject = DiagsCondition::allocate(collHeapPtr_);
     assert(newObject != NULL);
     newObject->unpackDependentObjFromBuffer32(buffer, sameEndianness);
     warnings_.insert(newObject);
     index++;
  }
  if (lengthLimit_ != ComCondition::NO_LIMIT_ON_ERROR_CONDITIONS)
    assert( getNumber() <= lengthLimit_ );

  // unpack fillers_ part
  unpackStrFromBuffer(buffer, fillers_, sizeof(fillers_));
}


// The packed length of a ComDiagsObject is the sum of the sizes
// of the integer members plus the sum of the sizes of the string
// members (see the comments for ComCondition::packedLength() to see
// how string length is determined).  We omit the collHeapPtr_ since
// it is not transferred via IPC (see comments for
// ComCondition::packedLength).
//
// We must include the length of the warning and error lists as well.
// the length of a list is the sum of the size of an   short
// (which tells number of elements) and the sum of the sizes of the
// individual member ComCondition objects.
//
// Let us not forget the size of the base class.
//
// We do not pack newCondition_.
#pragma nowarn(770)   // warning elimination 
IpcMessageObjSize ComDiagsArea::packedLength(void)
{
  // NOTE: changes to any of the following methods also require
  // corresponding changes in the others:
  // - packedLength()
  // - packObjIntoMessage()
  // - unpackObj()
  // - checkObj()

  IpcMessageObjSize  size=baseClassPackedLength();

  short extraFieldsLen = 0; // no extra fields yet in Release 1.5 

  // rowsetRowCountArray was added in after R2. It does not need
  // to be packed/unpacked as it is used only in the master. Just 
  // skip this data member during pack/unpack.
  extraFieldsLen = sizeof(rowsetRowCountArray_);

  size += sizeof(areMore_);
  size += sizeof(lengthLimit_);
  size += sizeof(rowCount_);
  size += sizeof(avgStreamWaitTime_);
  size += sizeof(cost_);
  size += sizeof(theSQLFunction_);
  size += sizeof(maxDiagsId_);
  size += sizeof(flags_);
  size += sizeof(extraFieldsLen);
  size += sizeof(rowsetRowCountArray_);

  // For the error and warning list (in that order) we add the size
  // for two shorts, for lengths, then we visit all
  // DiagsCondition objects and sum their sizes as well.

  size += sizeof(short);
  CollIndex  index = 0;
  while (index != errors_.entries()) {
     alignSizeForNextObj(size);
     size += (errors_[index])->packedLength();
     index++;
  }
  size += sizeof(short);
  index = 0;
  while (index != warnings_.entries()) {
     alignSizeForNextObj(size);
     size += (warnings_[index])->packedLength();
     index++;
  }

  // Add the fillers_ size too
  size += sizeof(fillers_);

  return size;
}


IpcMessageObjSize ComDiagsArea::packedLength32(void)
{
  // NOTE: changes to any of the following methods also require
  // corresponding changes in the others:
  // - packedLength32()
  // - packObjIntoMessage32()
  // - unpackObj()
  // - checkObj()

  IpcMessageObjSize  size=baseClassPackedLength32();

  short extraFieldsLen = 0; // no extra fields yet in Release 1.5 

  // rowsetRowCountArray was added in after R2. It does not need
  // to be packed/unpacked as it is used only in the master. Just 
  // skip this data member during pack/unpack.
  extraFieldsLen = sizeof(rowsetRowCountArray_);

  size += sizeof(areMore_);
  size += sizeof(lengthLimit_);
  size += sizeof(rowCount_);
  size += sizeof(avgStreamWaitTime_);
  size += sizeof(cost_);
  size += sizeof(theSQLFunction_);
  size += sizeof(maxDiagsId_);
  size += sizeof(flags_);
  size += sizeof(extraFieldsLen);
  size += sizeof(rowsetRowCountArray_);

  // For the error and warning list (in that order) we add the size
  // for two shorts, for lengths, then we visit all
  // DiagsCondition objects and sum their sizes as well.

  size += sizeof(short);
  CollIndex  index = 0;
  while (index != errors_.entries()) {
     alignSizeForNextObj(size);
     size += (errors_[index])->packedLength32();
     index++;
  }
  size += sizeof(short);
  index = 0;
  while (index != warnings_.entries()) {
     alignSizeForNextObj(size);
     size += (warnings_[index])->packedLength32();
     index++;
  }

  // Add the fillers_ size too
  size += sizeof(fillers_);

  return size;
}
#pragma warn(770)   // warning elimination 

IpcMessageObjSize ComDiagsArea::packObjIntoMessage(char *buffer)
{
  return packObjIntoMessage(buffer, FALSE);
}

IpcMessageObjSize ComDiagsArea::packObjIntoMessage(char* buffer,
                                NABoolean swapBytes)
{
  // NOTE: changes to any of the following methods also require
  // corresponding changes in the others:
  // - packedLength()
  // - packObjIntoMessage()
  // - unpackObj()
  // - checkObj()
  IpcMessageObjSize  size=packBaseClassIntoMessage(buffer, swapBytes);
  
 
  short extraFieldsLen = 0; // no extra fields yet in Release 1.5

  // rowsetRowCountArray was added in after R2. It does not need
  // to be packed/unpacked as it is used only in the master. Just 
  // skip this data member during pack/unpack.
  extraFieldsLen = sizeof(rowsetRowCountArray_);

  size += packIntoBuffer(buffer,areMore_, swapBytes);
  size += packIntoBuffer(buffer,lengthLimit_, swapBytes);
  size += packIntoBuffer(buffer,rowCount_, swapBytes);
  size += packIntoBuffer(buffer,avgStreamWaitTime_, swapBytes);
  double tempCost = cost_;
  // Double scalar data type will not work with bswap_64
  // hence doing it here by casting it Int64
  if (swapBytes)
      tempCost = bswap_64((Int64)cost_);
  size += packIntoBuffer(buffer,tempCost);
  size += packIntoBuffer(buffer,theSQLFunction_, swapBytes);
  size += packIntoBuffer(buffer,maxDiagsId_, swapBytes);
  size += packIntoBuffer(buffer,flags_, swapBytes);
  size += packIntoBuffer(buffer,extraFieldsLen, swapBytes);

  // If fields get added after Release 1.5 without wanting to do
  // major versioning changes, add them here and set extraFieldsLen
  // to their length. Release 1.5 code will then simply ignore the extra
  // fields.

  // rowsetRowCountArray should be null as it is shipped across process boundaries.
  assert(rowsetRowCountArray_ == NULL);
  size += packIntoBuffer(buffer,rowsetRowCountArray_);

  short num = (short) errors_.entries();
  short numToPack = num;

#ifdef NA_DEBUG_C_RUNTIME
  // In the debug build we allow the UDR server to generate a corrupt
  // packed object. This allows us to test error handling in the
  // executor. The MXUDR_DEBUG_BUILD variable is always set by the
  // debug UDR server and we only test it once. We test
  // MXUDR_CORRUPT_DIAGS_REPLY every time we come here in the UDR
  // server.
  static NABoolean inUdrServer = (getenv("MXUDR_DEBUG_BUILD") != NULL);
  if (inUdrServer)
  {
    char *val = getenv("MXUDR_CORRUPT_DIAGS_REPLY");
    if (val && val[0])
    {
      numToPack++;
    }
  }
#endif
  
  size += packIntoBuffer(buffer, numToPack, swapBytes);
 

  CollIndex index=0;
  while (index!= (CollIndex) num) {
     IpcMessageObjSize temp =
       (errors_[index])->packDependentObjIntoMessage(buffer, swapBytes);
     size += temp;
     buffer += temp;
     index++;
  }
  num = (  short) warnings_.entries();
  size += packIntoBuffer(buffer,num, swapBytes);
  index = 0;
  while (index!= (CollIndex) num) {
     IpcMessageObjSize temp =
       (warnings_[index])->packDependentObjIntoMessage(buffer, swapBytes);
     size += temp;
     buffer += temp;
     index++;
  }

  // Pack the fillers part too
  size += packStrIntoBuffer(buffer, fillers_, sizeof(fillers_));

  return size;
}


// pack object to buffer to be read by 32-bit (BDR) client
IpcMessageObjSize ComDiagsArea::packObjIntoMessage32(char *buffer)
{
  return packObjIntoMessage32(buffer, FALSE);
}

IpcMessageObjSize ComDiagsArea::packObjIntoMessage32(char* buffer,
                                NABoolean swapBytes)
{
  // NOTE: changes to any of the following methods also require
  // corresponding changes in the others:
  // - packedLength32()
  // - packObjIntoMessage32()
  // - unpackObj()
  // - checkObj()
  IpcMessageObjSize  size=packBaseClassIntoMessage32(buffer, swapBytes);
  
 
  short extraFieldsLen = 0; // no extra fields yet in Release 1.5

  // rowsetRowCountArray was added in after R2. It does not need
  // to be packed/unpacked as it is used only in the master. Just 
  // skip this data member during pack/unpack.
  extraFieldsLen = sizeof(rowsetRowCountArray_);

  size += packIntoBuffer(buffer,areMore_, swapBytes);
  size += packIntoBuffer(buffer,lengthLimit_, swapBytes);
  size += packIntoBuffer(buffer,rowCount_, swapBytes);
  size += packIntoBuffer(buffer,avgStreamWaitTime_, swapBytes);
  double tempCost = cost_;
  // Double scalar data type will not work with bswap_64
  // hence doing it here by casting it Int64
  if (swapBytes)
      tempCost = bswap_64((Int64)cost_);
  size += packIntoBuffer(buffer,tempCost);
  size += packIntoBuffer(buffer,theSQLFunction_, swapBytes);
  size += packIntoBuffer(buffer,maxDiagsId_, swapBytes);
  size += packIntoBuffer(buffer,flags_, swapBytes);
  size += packIntoBuffer(buffer,extraFieldsLen, swapBytes);

  // If fields get added after Release 1.5 without wanting to do
  // major versioning changes, add them here and set extraFieldsLen
  // to their length. Release 1.5 code will then simply ignore the extra
  // fields.

  // rowsetRowCountArray should be null as it is shipped across process boundaries.
  assert(rowsetRowCountArray_ == NULL);
  size += packIntoBuffer(buffer,rowsetRowCountArray_);

  short num = (short) errors_.entries();
  short numToPack = num;

#ifdef NA_DEBUG_C_RUNTIME
  // In the debug build we allow the UDR server to generate a corrupt
  // packed object. This allows us to test error handling in the
  // executor. The MXUDR_DEBUG_BUILD variable is always set by the
  // debug UDR server and we only test it once. We test
  // MXUDR_CORRUPT_DIAGS_REPLY every time we come here in the UDR
  // server.
  static NABoolean inUdrServer = (getenv("MXUDR_DEBUG_BUILD") != NULL);
  if (inUdrServer)
  {
    char *val = getenv("MXUDR_CORRUPT_DIAGS_REPLY");
    if (val && val[0])
    {
      numToPack++;
    }
  }
#endif
  
  size += packIntoBuffer(buffer, numToPack, swapBytes);
 

  CollIndex index=0;
  while (index!= (CollIndex) num) {
     IpcMessageObjSize temp =
       (errors_[index])->packDependentObjIntoMessage32(buffer, swapBytes);
     size += temp;
     buffer += temp;
     index++;
  }
  num = (  short) warnings_.entries();
  size += packIntoBuffer(buffer,num, swapBytes);
  index = 0;
  while (index!= (CollIndex) num) {
     IpcMessageObjSize temp =
       (warnings_[index])->packDependentObjIntoMessage32(buffer, swapBytes);
     size += temp;
     buffer += temp;
     index++;
  }

  // Pack the fillers part too
  size += packStrIntoBuffer(buffer, fillers_, sizeof(fillers_));

  return size;
}

NABoolean ComDiagsArea::checkObj(IpcMessageObjType objType,
                                 IpcMessageObjVersion objVersion,
                                 NABoolean sameEndianness,
                                 IpcMessageObjSize objSize,
                                 IpcConstMessageBufferPtr buffer) const
{
  // NOTE: changes to any of the following methods also require
  // corresponding changes in the others:
  // - packedLength()
  // - packObjIntoMessage()
  // - unpackObj()
  // - checkObj()

  const IpcConstMessageBufferPtr lastByte = buffer + objSize - 1;

  if (!checkBaseClass(objType, objVersion, sameEndianness, objSize, buffer))
    return FALSE;

  if (!checkBuffer(buffer, sizeof(areMore_), lastByte))
    return FALSE;

  Int32 lengthLimit = 0;
  if (!checkAndUnpackBuffer(buffer, sizeof(lengthLimit),
                            (char *) &lengthLimit, lastByte))
    return FALSE;
  if (!sameEndianness)
    swapFourBytes(lengthLimit);

  if (!checkBuffer(buffer,
                   sizeof(rowCount_)
                   + sizeof(avgStreamWaitTime_)
                   + sizeof(cost_)
                   + sizeof(theSQLFunction_)
                   + sizeof(maxDiagsId_)
                   + sizeof(flags_)
                   , lastByte))
    return FALSE;
  
  short extraFieldsLen = 0;
  if (!checkAndUnpackBuffer(buffer, sizeof(extraFieldsLen),
                            (char *) &extraFieldsLen, lastByte))
    return FALSE;
  if (!sameEndianness)
    swapTwoBytes(extraFieldsLen);

  // from NEO/Coyote releases extraFieldsLen should include
  // sizeof(rowsetRowCountArray_). There is no unpacking
  // to be done here as this data member is NULL at this point.
  if (!checkBuffer(buffer, extraFieldsLen, lastByte))
    return FALSE;

  short i;
  short numErrors = 0;
  short numWarnings = 0;
  DiagsCondition cond;

  // Error conditions
  if (!checkAndUnpackBuffer(buffer, sizeof(numErrors),
                            (char *) &numErrors, lastByte))
    return FALSE;
  if (!sameEndianness)
    swapTwoBytes(numErrors);

  for (i = 0; i < numErrors; i++)
    if (!cond.checkDependentObj(buffer, sameEndianness))
      return FALSE;
  
  // Warning conditions
  if (!checkAndUnpackBuffer(buffer, sizeof(numWarnings),
                            (char *) &numWarnings, lastByte))
    return FALSE;
  if (!sameEndianness)
    swapTwoBytes(numWarnings);

  for (i = 0; i < numWarnings; i++)
    if (!cond.checkDependentObj(buffer, sameEndianness))
      return FALSE;
  
  if ((numErrors + numWarnings) > lengthLimit)
  {
    ipcIntegrityCheckEpilogue(FALSE);
    return FALSE;
  }
  
  // Check fillers_ part
  if (!checkBuffer(buffer, sizeof(fillers_), lastByte))
    return FALSE;

  return TRUE;
}

// Accessors for Basic Info
//
// This returns the sum of the number of
// elements in errors_ and warnings_.

Lng32     ComDiagsArea::getNumber () const
{
#pragma nowarn(1506)   // warning elimination 
   return errors_.entries() + warnings_.entries();
#pragma warn(1506)  // warning elimination 
}

Lng32     ComDiagsArea::getNumber (DgSqlCode::ErrorOrWarning type) const
{
   switch (type) {
#pragma nowarn(1506)   // warning elimination 
     case DgSqlCode::ERROR_:	return errors_.entries();
#pragma warn(1506)  // warning elimination 
#pragma nowarn(1506)   // warning elimination 
     case DgSqlCode::WARNING_:	return warnings_.entries();
#pragma warn(1506)  // warning elimination 
     default:			return -1;
   }
}


NABoolean ComDiagsArea::areMore () const
{
  return (areMore_ != ComCondition::NO_MORE);
}

NABoolean ComDiagsArea::canAcceptMoreErrors () const
{
  return (areMore_ != ComCondition::MORE_ERRORS);
}


Int64 ComDiagsArea::getRowCount () const
{
   return rowCount_;
}

void ComDiagsArea::addRowCount (Int64 newRowCount)
{
   rowCount_ += newRowCount;
}

void ComDiagsArea::setRowCount (Int64 newRowCount)
{
   rowCount_ = newRowCount;
}

ComDiagBigInt ComDiagsArea::getAvgStreamWaitTime () const
{
   return avgStreamWaitTime_;
}

void ComDiagsArea::setAvgStreamWaitTime (ComDiagBigInt avgStreamWaitTime )
{
   avgStreamWaitTime_ = avgStreamWaitTime;
}

double ComDiagsArea::getCost () const
{
   return cost_;
}

void ComDiagsArea::setCost (double newCost)
{
   cost_ = newCost;
}

//
// setAllSqlID
//
// Traverse through the conditions from the latest to the earliest and
// set any unknown sql ids.  Stop at the first one that is already set
// since we've already seen it in a past execution.  (This functions
// the same way as setAllRowNumber.)
//

void ComDiagsArea::setAllSqlID (char *sqlID)
{
  if (!sqlID) return;

  Lng32 errorCount = getNumber(DgSqlCode::ERROR_);
  Int32 i = 0;
  for(i=0; i < errorCount; i++) {
    ComCondition* errCond = getErrorEntry(errorCount-i);
    if (errCond->getSqlID() == NULL)
      errCond->setSqlID(sqlID); 
    else
      break ;
  }
  Lng32 warnCount = getNumber(DgSqlCode::WARNING_);
  for(i=0; i < warnCount; i++) {
    ComCondition* warnCond = getWarningEntry(warnCount-i);
    if (warnCond->getSqlID() == NULL)
      warnCond->setSqlID(sqlID); 
    else
      break ;
  }
}

void ComDiagsArea::setAllRowNumber (Lng32 rowNum, DgSqlCode::ErrorOrWarning errOrWarn)
{
  if (errOrWarn != DgSqlCode::WARNING_)
  {
    Lng32 errorCount = getNumber(DgSqlCode::ERROR_);
    for(Int32 i=0; i < errorCount; i++) {
      ComCondition* errCond = getErrorEntry(errorCount-i);
      if (errCond->getRowNumber() < 0)
        errCond->setRowNumber(rowNum); 
      else
        break ;
    }
  }
  else
  {
    Lng32 warnCount = getNumber(DgSqlCode::WARNING_);
    for(Int32 i=0; i < warnCount; i++) {
      ComCondition* warnCond = getWarningEntry(warnCount-i);
      if (warnCond->getRowNumber() < 0)
        warnCond->setRowNumber(rowNum); 
      else
        break ;
    }
  }
}


Lng32 ComDiagsArea::getNextRowNumber (Lng32 indexValue) const
{
  Lng32 errorCount = getNumber(DgSqlCode::ERROR_);
  Lng32 nextRowNumber = ComCondition::INVALID_ROWNUMBER;

  for(Int32 i=0; i < errorCount; i++) {
    ComCondition* errCond = ((ComDiagsArea *) this)->getErrorEntry(i+1);
    if ((errCond->getRowNumber() != ComCondition::INVALID_ROWNUMBER) &&
	(errCond->getRowNumber() >= indexValue)) {
	  if ((nextRowNumber == ComCondition::INVALID_ROWNUMBER) ||
	      (errCond->getRowNumber() < nextRowNumber)) {
		nextRowNumber = errCond->getRowNumber();
	  }
    }
  }
  return nextRowNumber ;
}


NABoolean ComDiagsArea::hasValidRowsetRowCountArray () const
{
  return (rowsetRowCountArray_ != NULL);
}


Lng32  ComDiagsArea::numEntriesInRowsetRowCountArray () const
{
  if (rowsetRowCountArray_)
    return (Lng32) rowsetRowCountArray_->entries();
  else
    return 0;
}

void  ComDiagsArea::insertIntoRowsetRowCountArray (Lng32 index, Int64 value, 
					    Lng32 arraySize, CollHeap* heapPtr)
{
  if (rowsetRowCountArray_ == NULL)
  {
    if (heapPtr)
      rowsetRowCountArray_ = new (heapPtr) NAArray<Int64>(heapPtr,arraySize);
    else
      rowsetRowCountArray_ = new (collHeapPtr_) NAArray<Int64>(collHeapPtr_, arraySize);
  }
  // index is assumed to be zero based. It is also assumed to be non-negative
  // it is OK if index is > arraySize, though this should 
  // not happen as arraySize is expected to be maximum rowset size
  rowsetRowCountArray_->insertAt((CollIndex)index, value);
}

Int64 ComDiagsArea::getValueFromRowsetRowCountArray (Lng32 index) const
{
  if ((rowsetRowCountArray_ == NULL) ||
      (index < 0) ||
      (!((rowsetRowCountArray_->used((CollIndex) index))))) {
    return -1;
  }

  return (*rowsetRowCountArray_)[(CollIndex) index];
}


// The Function Name
//
// Now we provide implementation for the functions that get and set
// the ``function name.''

void ComDiagsArea::setFunction(FunctionEnum newFunction)
{
   theSQLFunction_=newFunction;
}

ComDiagsArea::FunctionEnum ComDiagsArea::getFunction() const
{
   return (ComDiagsArea::FunctionEnum) theSQLFunction_;
}

// For the purpose of returning a function name, depending
// on the value of theSQLFunction_, we shall declare an
// array static (or private) to this source file.  This
// array has entries, one each, giving a char* that
// is the name of the SQL function represented by each of the
// FunctionEnum values.
//
// WARNING:  The entries in this array must correspond
//           with the definitions of the members of FunctionEnum.

static const char *const functionNames[ComDiagsArea::MAX_FUNCTION_ENUM] = {
    "NULL_FUNCTION",
    "ALLOCATE_CURSOR",
    "ALLOCATE_DESCRIPTOR",
    "ALTER_DOMAIN",
    "ALTER_TABLE",
    "CREATE_ASSERTION",
    "CREATE_CHARACTER_SET",
    "CLOSE_CURSOR",
    "CREATE_COLLATION",
    "COMMIT_WORK",
    "CONNECT",
    "DEALLOCATE_DESCRIPTOR",
    "DEALLOCATE_PREPARE",
    "DELETE_CURSOR",
    "DELETE_WHERE",
    "DESCRIBE",
    "SELECT",
    "DISCONNECT",
    "CREATE_DOMAIN",
    "DROP_ASSERTION",
    "DROP_CHARACTER_SET",
    "DROP_COLLATION",
    "DROP_DOMAIN",
    "DROP_SCHEMA",
    "DROP_TABLE",
    "DROP_TRANSLATION",
    "DROP_VIEW",
    "DYNAMIC_CLOSE",
    "DYNAMIC_DELETE_CURSOR",
    "DYNAMIC_FETCH",
    "DYNAMIC_OPEN",
    "DYNAMIC_UPDATE_CURSOR",
    "EXECUTE_IMMEDIATE",
    "EXECUTE",
    "FETCH",
    "GET_DESCRIPTOR",
    "GET_DIAGNOSTICS",
    "GRANT",
    "INSERT",
    "OPEN",
    "PREPARE",
    "REVOKE",
    "ROLLBACK_WORK",
    "CREATE_SCHEMA",
    "SET_CATALOG",
    "SET_CONNECTION",
    "SET_CONSTRAINT",
    "SET_DESCRIPTOR",
    "SET_TIME_ZONE",
    "SET_NAMES",
    "SET_SCHEMA",
    "SET_TRANSACTION",
    "SET_SESSION_AUTHORIZATION",
    "CREATE_TABLE",
    "CREATE_TRANSLATION",
    "UPDATE_CURSOR",
    "UPDATE_WHERE",
    "CREATE_VIEW"
};


const char * ComDiagsArea::getFunctionName () const
{
   return functionNames[theSQLFunction_];
}

// Class DiagsCondition Implementation
// ...is very simple indeed.  A very simple constructor
// and destructor, and some get/get methods for the diagsId_.

ComDiagsArea::DiagsCondition::DiagsCondition (CollHeap* ptr) :
                   ComCondition(ptr)
{ }

ComDiagsArea::DiagsCondition::DiagsCondition () :
                   ComCondition()
{ }

ComDiagsArea::DiagsCondition::~DiagsCondition ()
{
}

// And for the set/get methods:


void ComDiagsArea::DiagsCondition::setDiagsId(Lng32     newDiagsId)
{
   diagsId_ = newDiagsId;
}

Lng32     ComDiagsArea::DiagsCondition::getDiagsId () const
{
   return diagsId_;
}


// Finally, the IPC methods:

IpcMessageObjSize ComDiagsArea::DiagsCondition::packedLength ()
{
  // NOTE: changes to any of the following methods also require
  // corresponding changes in the others:
  // - packedLength()
  // - packObjIntoMessage()
  // - unpackObj()
  // - checkObj()

  return ComCondition::packedLength()+sizeof(diagsId_);
}

IpcMessageObjSize ComDiagsArea::DiagsCondition::packedLength32()
{
  return ComCondition::packedLength32()+sizeof(diagsId_);
}

IpcMessageObjSize ComDiagsArea::DiagsCondition::packObjIntoMessage (
          IpcMessageBufferPtr buffer)
{
  return packObjIntoMessage(buffer, FALSE);
}
// To pack a DiagsCondition object, you just pack the
// the base class --- a ComCondition object --- and then pack in the
// diagsId_ member.  Easy, no?

IpcMessageObjSize ComDiagsArea::DiagsCondition::packObjIntoMessage (
          IpcMessageBufferPtr buffer, NABoolean swapBytes)
{
  // NOTE: changes to any of the following methods also require
  // corresponding changes in the others:
  // - packedLength()
  // - packObjIntoMessage()
  // - unpackObj()
  // - checkObj()

  IpcMessageObjSize  size = ComCondition::packObjIntoMessage(buffer, swapBytes);
  buffer += size;
  size += packIntoBuffer(buffer,diagsId_, swapBytes);
  return size;
}

IpcMessageObjSize ComDiagsArea::DiagsCondition::packObjIntoMessage32 (
          IpcMessageBufferPtr buffer)
{
  return packObjIntoMessage32(buffer, FALSE);
}
IpcMessageObjSize ComDiagsArea::DiagsCondition::packObjIntoMessage32 (
          IpcMessageBufferPtr buffer, NABoolean swapBytes)
{
  // NOTE: changes to any of the following methods also require
  // corresponding changes in the others:
  // - packedLength32()
  // - packObjIntoMessage32()
  // - unpackObj()
  // - checkObj()

  IpcMessageObjSize  size = ComCondition::packObjIntoMessage32(buffer, swapBytes);
  buffer += size;
  size += packIntoBuffer(buffer,diagsId_, swapBytes);
  return size;
}

void ComDiagsArea::DiagsCondition::unpackObj(IpcMessageObjType objType,
				    IpcMessageObjVersion objVersion,
				    NABoolean sameEndianness,
				    IpcMessageObjSize objSize,
				    IpcConstMessageBufferPtr buffer)
{
  // NOTE: changes to any of the following methods also require
  // corresponding changes in the others:
  // - packedLength()
  // - packObjIntoMessage()
  // - unpackObj()
  // - checkObj()

  ComCondition::unpackObj(objType,objVersion,sameEndianness,
			  objSize,buffer);
  buffer += objSize - sizeof(diagsId_);
  unpackBuffer(buffer,diagsId_);
}

void ComDiagsArea::DiagsCondition::unpackObj32(IpcMessageObjType objType,
				    IpcMessageObjVersion objVersion,
				    NABoolean sameEndianness,
				    IpcMessageObjSize objSize,
				    IpcConstMessageBufferPtr buffer)
{
  // NOTE: changes to any of the following methods also require
  // corresponding changes in the others:
  // - packedLength()
  // - packObjIntoMessage()
  // - unpackObj()
  // - checkObj()

  ComCondition::unpackObj32(objType,objVersion,sameEndianness,
			    objSize,buffer);
  buffer += objSize - sizeof(diagsId_);
  unpackBuffer(buffer,diagsId_);
}

NABoolean
ComDiagsArea::DiagsCondition::checkObj(IpcMessageObjType t,
                                       IpcMessageObjVersion v,
                                       NABoolean sameEndianness,
                                       IpcMessageObjSize objSize,
                                       IpcConstMessageBufferPtr buffer) const
{
  // NOTE: changes to any of the following methods also require
  // corresponding changes in the others:
  // - packedLength()
  // - packObjIntoMessage()
  // - unpackObj()
  // - checkObj()

  const IpcConstMessageBufferPtr lastByte = buffer + objSize - 1;

  if (!ComCondition::checkObj(t, v, sameEndianness, objSize, buffer))
    return FALSE;

  if (!checkBuffer(buffer, sizeof(diagsId_), lastByte))
    return FALSE;

  return TRUE;
}

// Condition Addition
// The code in this section is the implementation for the ComDiagsArea
// members that allow the user to create and insert ComCondition
// objects.
//
// To create a new ComCondition we allocate a new DiagsCondition
// object on the proper heap.
//
// Note that the first condition's diagsId will be 1 (not 0).
//

ComCondition * ComDiagsArea::makeNewCondition()
{
   assert(newCondition_==NULL);
   newCondition_ = DiagsCondition::allocate(collHeapPtr_);
   assert(newCondition_ != NULL);
   newCondition_->setDiagsId(++maxDiagsId_);		// PREincrement
   newCondition_->setConditionNumber(newCondition_->getDiagsId());
   return newCondition_;
}

// All that this chunk's function must do is to free
// the current DiagsCondition object using the proper heap.
//

void ComDiagsArea::discardNewCondition()
{
    assert(newCondition_ != NULL);
    newCondition_->deAllocate();
    newCondition_ = NULL;
    maxDiagsId_--;
}

void ComDiagsArea::insertNewWarning()
{
  warnings_.insert(newCondition_);
}

void ComDiagsArea::insertNewEODWarning()
{
  warnings_.insert(newCondition_);
}

void ComDiagsArea::insertNewError()
{
  errors_.insert(newCondition_);
  // for non-atomic inserts, if any error is inserted after NonFatalErrorSeen flag
  // is set, then we want to unset the flag so that mainSQLCODE does not return 30022.
  if (getNonFatalErrorSeen())
    setNonFatalErrorSeen(FALSE);
}

// What we do here is:
// Make sure that newCondition_ is not NULL.
// If *newCondition_ is for SQLCODE of zero, assert a failure.
// If *newCondition_ is for a positive SQLCODE, add it to warnings_.
// Otherwise, *newCondition_ is for a negative SQLCODE, and
// add it to errors_.
// Set *newCondition_ to NULL.

void ComDiagsArea::acceptNewCondition()
{
   assert(newCondition_!=NULL);
   assert(newCondition_->getSQLCODE()!=0);
   if (newCondition_->getSQLCODE() < 0)
     insertNewError();
   else if (newCondition_->getSQLCODE() == 100)
     insertNewEODWarning();
   else
     insertNewWarning();

   newCondition_=NULL;
   enforceLengthLimit();
}

// Access to sequence of DiagsCondition (ComCondition plus diagsId sequencenum)
//
// This operator makes it look like ComDiagsAreas are indexed 1..getNumber()
// while the internal errors_/warnings_ lists are indexed from 0..entries()-1.
//
// This function used to return all errors entries before all warnings,
// regardless of their actual arrival sequence; this was motivated by the
// desire to be able to output completed conditions by severity.
// Unfortunately, this led to problems when in the midst of assembling a
// *new* (not yet complete) condition when previous conditions were an
// interleaved mixture of warnings and errors:  the current condition's
// DgBase parameters are assigned to the comDiags[comDiags.getNumber()]
// condition, which would not necessarily be the current condition,
// but the last warning in the area.
//
// Now, this function returns entries by arrival sequence,
// *even if this means a warning is returned (to be output) before an error*.
// (Contrast this behavior to mainSQLCode().)
//

ComCondition &ComDiagsArea::operator[] (Lng32 index) const
{
   CollIndex numErrors   = errors_.entries();
   CollIndex numWarnings = warnings_.entries();
   assert(index > 0);
   assert((CollIndex)index <= numErrors + numWarnings);
   index--; // convert to 0 based
   // If only one of the lists is populated, fast lookup of index'th condition.
   if (numErrors == 0)
     return *warnings_[index];
   else if (numWarnings == 0)
     return *errors_[index];

   // diagsId is unique among all conditions
   // the conditions in errors_[] warnings_[] are sorted on diags Id
   // respectively, because conditions are created with a incrementing
   // diags Id counter and appended to the array.
   // sometimes, the conditions are removed, so their assigned diags Id is no
   // more continuous. This is why we need to find the right condition
   // by searching through the two arrays, relying on the diags Id in
   // the conditions as the order.
   CollIndex errorIdx = 0;
   CollIndex warnIdx = 0;
   Lng32 pos = 0;

   while(pos < index){
     if(errorIdx == numErrors)
       warnIdx++;
     else if(warnIdx == numWarnings)
       errorIdx++;
     else{
       if(errors_[errorIdx]->getDiagsId() < 
	  warnings_[warnIdx]->getDiagsId())
	 errorIdx++;
       else if(errors_[errorIdx]->getDiagsId() > 
	       warnings_[warnIdx]->getDiagsId())
	 warnIdx++;
       else {
	 //assert("duplicated diagsId" == 0);
	 //return *errors_[0];
	 warnIdx++;
       }
     }
     pos++;
   }
   
   if(errorIdx == numErrors)
     return *warnings_[warnIdx];
   else if(warnIdx == numWarnings)
     return *errors_[errorIdx];
   else{
     if(errors_[errorIdx]->getDiagsId() < 
	warnings_[warnIdx]->getDiagsId())
       return *errors_[errorIdx];
     else if(errors_[errorIdx]->getDiagsId() > 
	     warnings_[warnIdx]->getDiagsId())
       return *warnings_[warnIdx];
     else {
       //assert("duplicated diagsId" == 0);
       //return *errors_[0];
       return *warnings_[warnIdx];
     }
   }
}

// the following 2 methods retrieve the warning/error ComCondition at 
// warnings_[index] or errors_[index]
// index ranges from 1..getNumber(DgSqlCode::WARNING_ or ERROR_)
// MARIA
ComCondition*  ComDiagsArea::getWarningEntry(Lng32 index) {
  assert((warnings_.entries() >= (CollIndex)index) && (index > 0));
  return warnings_[--index]; 
}

ComCondition* ComDiagsArea::getErrorEntry(Lng32 index) {
  assert((errors_.entries() >= (CollIndex)index) && (index > 0));
  return errors_[--index];
}

ComCondition* ComDiagsArea::findCondition(Lng32 sqlCode, Lng32 *entryNumber)
{
  if (sqlCode == 0)
    return NULL;

  ComCondition * c = NULL;
  CollIndex i = 0;

  if (sqlCode > 0)
    {
      for (i = 0; i < warnings_.entries(); ++i)
        if (warnings_[i]->getSQLCODE() == sqlCode)
          {
            c = warnings_[i];
            if (entryNumber != NULL)
                *entryNumber = i;
            break;
          }
      return c;
    }

  // sqlCode < 0

  for (i = 0; i < errors_.entries(); ++i)
    if (errors_[i]->getSQLCODE() == sqlCode)
      {
        c = errors_[i];
        if (entryNumber != NULL)
           *entryNumber = i;
        break;
      }
 return c;
}



// The clearConditionsOnly method just deletes and clears each element of
// both sequences (errors_ and warnings_), and resets the maxDiagsId_.

void ComDiagsArea::clearConditionsOnly()
{
   DiagsCondition  *ptr;
   while (errors_.getFirst(ptr))   ptr->deAllocate();
   while (warnings_.getFirst(ptr)) ptr->deAllocate();
   maxDiagsId_ = 0;
}

// The clear method just deletes and clears each element of
// both sequences (errors_ and warnings_) and additionally sets things
// like areMore_ to false (NO_MORE).

void ComDiagsArea::clear()
{
   clearConditionsOnly();
   areMore_=ComCondition::NO_MORE;
   flags_ = 0;
   rowCount_ = 0;
   avgStreamWaitTime_ = -1;
   cost_ = 0.0;
   if (rowsetRowCountArray_ != NULL) {
    rowsetRowCountArray_->deallocate();
    rowsetRowCountArray_ = NULL;
   }

}

void ComDiagsArea::clearErrorConditionsOnly()
{
   DiagsCondition  *ptr;
   while (errors_.getFirst(ptr)) 
   {
     ptr->deAllocate();
     --maxDiagsId_;
   }
}

// Returnes the SQLSTATE value of the last SIGNAL statement.
// Assumes the SIGNAL condition is the highest priority error.
const char *ComDiagsArea::getSignalSQLSTATE() const
{
  if (errors_.entries() > 0) {
    ComCondition *signal = errors_[0];

    if (signal->getSQLCODE() == -ComDiags_SignalSQLCODE)
      return signal->getOptionalString(0);
  }
  return NULL;
}
  
// The code for mainSQLCODE is rather straightforward
// (see the .h file for a specification).
// This value is what GET DIAGNOSTICS CONDITION_NUMBER=1 should return
// (all other conditionNumber's are implementation-dependent, so can be random).

Lng32 ComDiagsArea::mainSQLCODE() const
{
   if (errors_.entries() > 0) {
      if (containsError(-EXE_CANCELED))
        return -EXE_CANCELED;
      else if (errors_[0]->getSQLCODE() == -EXE_INTERNALLY_GENERATED_COMMAND && errors_.entries() > 1)
        return errors_[1]->getSQLCODE();
      else if (errors_[errors_.entries()-1]->getSQLCODE() == -EXE_NONATOMIC_FAILURE_LIMIT_EXCEEDED)
        return -EXE_NONATOMIC_FAILURE_LIMIT_EXCEEDED;
      else if (getNonFatalErrorSeen()) {
	if (containsWarning(EXE_NONFATAL_ERROR_SEEN))
	  return EXE_NONFATAL_ERROR_SEEN;
	else
	  return EXE_NONFATAL_ERROR_ON_ALL_ROWS;
      }
      else
		return errors_[0]->getSQLCODE();
   }
   else if (warnings_.entries() > 1 && warnings_[0]->getSQLCODE() == EXE_INTERNALLY_GENERATED_COMMAND)
      return warnings_[1]->getSQLCODE();
   else if (warnings_.entries() > 0)
      return warnings_[0]->getSQLCODE();
   else
      return 0L;
}

// Negation of ComConditions
//
// Negation of a condition in a ComDiagsArea is somewhat tricky,
// and definitely possible.  Here's the algorithm we implement:
//
// Assert that the index is in range.
//
// Assert that the ComCondition, c, referenced by index
// is not locked yet.
//
// Remove c from the list (errors, warnings) that it is currently
// resident in.
//
// Negate the value of the SQLCODE member of c.
//
// Insert c into the other list (warnings,errors) than the one
// from which it came.  Do the insertion preserving the ascending
// ordering of the list based on the DiagsId as a key.
//
// It is the insertion into the ordered list that is the trickiest part ---
// but definitely possible.

void ComDiagsArea::negateCondition(CollIndex index)
{
   CollIndex numErrorEntries = errors_.entries();
   CollIndex numWarningEntries = warnings_.entries();
   assert(numErrorEntries+numWarningEntries != 0);//index invalid if this fails
   assert(index < numErrorEntries+numWarningEntries);
   NABoolean sourceIsWarning =
                  (numErrorEntries==0 || (index > numErrorEntries-1));
   LIST(DiagsCondition*)   &source = sourceIsWarning ? warnings_ : errors_;
   LIST(DiagsCondition*)   &dest   = sourceIsWarning ? errors_ : warnings_;
   if (sourceIsWarning) index -= numErrorEntries;

   // We declare ptr and do a lookup, and then a removeAt to
   // extract the pointer to the ComCondition in question from
   // the source list.
   //

   DiagsCondition   *ptr = source[index];

   NABoolean removed = source.removeAt(index);
   assert(removed);

   assert(ptr);
   ptr->isLocked_   = FALSE;
   ptr->theSQLCODE_ = -ptr->theSQLCODE_;

   // We presume/know that dest is ordered in an ascending order
   // by DiagsId.  We want to add ptr to dest preserving this ordering.
   //
   // We can use a loop to determine an index such that an insertion will
   // preserve ordering.  Then, we simply insert.
   //
   // Fortunately (for us in this chunk) the insertAt of NAList
   // does indeed ``slide down'' all members of the list that
   // are beyond the insertion point.
   //
   // When the loop terminates, we want that all of the elements
   // of dest which have a DiagsId less than the DiagsId of
   // *ptr are before the place where insertionPoint points.
   // Note that no two DiagsConditions should have the same DiagsId
   // value, if they are resident in the same ComDiagsArea.

   CollIndex insertionPoint = 0;
   while (insertionPoint != dest.entries() &&
          dest[insertionPoint]->getDiagsId() < ptr->getDiagsId())
            insertionPoint++;
   dest.insertAt(insertionPoint,ptr);
}

// Merging of ComDiagsAreas
// See the header file for the specification for what this
// function does.
//
// Steps
// =====
// Assert that the function enums are the same for this and source.
//
// Copy conditions from source into this object in source insertion sequence,
// using the [] operator.
//
// Add source's rowCount_ to this rowCount_.
// 
// Replace avgStreamWaitTime_ with source's, if valid.

void ComDiagsArea::mergeAfter(const ComDiagsArea& source)
{
  Lng32 nfMark = -1;
   if (this == &source) return;
  
   // if NAR errors are flowing up the tree avoid merging them if
   // they are the same.
   if (((source.mainSQLCODE() == EXE_NONFATAL_ERROR_SEEN)  &&
	(mainSQLCODE() == EXE_NONFATAL_ERROR_SEEN)) ||
       ((source.mainSQLCODE() == EXE_NONFATAL_ERROR_ON_ALL_ROWS)  &&
	 (mainSQLCODE() == EXE_NONFATAL_ERROR_ON_ALL_ROWS)))     
     {
       if ((source.getNumber() <= getNumber()))
	 return ;
       else	
	 nfMark = ((ComDiagsArea *)&source)->markDupNFConditions();
     }
   
   assert(   newCondition_ == NULL );

   // I, (Bill), am commenting this out because with our current
   // interfaces between subcomponents of the architecture it is
   // not always desirable to perform a gratuitous SQL-FUNCTION change
   // just to keep this assert from failing.  Conceptually, however,
   // it makes sense to me that merging two diags areas only should
   // work if they apply to the same SQL-FUNCTION. :-)
   //
   //   assert( theSQLFunction_ == source.theSQLFunction_);

#ifndef __EID
   // if lengthLimit of source is greater than that of target
   // then the  target lengthLimit is assigned that of the source. 
   // Note that NO_LIMIT_ON_ERROR_CONDITIONS
   // is the largest value lengthLimit can have, even though this enum = -1.
   if (source.lengthLimit_ == ComCondition::NO_LIMIT_ON_ERROR_CONDITIONS) {
     lengthLimit_ = ComCondition::NO_LIMIT_ON_ERROR_CONDITIONS;
   }
   else if ((lengthLimit_ != ComCondition::NO_LIMIT_ON_ERROR_CONDITIONS) && 
	    (source.lengthLimit_ > lengthLimit_)) {
    lengthLimit_ = source.lengthLimit_ ;
   }
#endif

   // VO, Feb 2004:
   //    changed to preserve insertion order of the conditions

   for (Int32 index = (((nfMark != -1) ? (nfMark+1):1)); index <= source.getNumber(); index++)
   {
      ComCondition * newCondition = this->makeNewCondition();
      
      *newCondition = source[index];
      this->acceptNewCondition();
   }

   rowCount_ += source.rowCount_;

   if (source.avgStreamWaitTime_ != -1)
    avgStreamWaitTime_ = source.avgStreamWaitTime_ ;

   if (areMore_ == ComCondition::NO_MORE)
     areMore_ = source.areMore_;

   enforceLengthLimit();

   flags_ = source.flags_;

   assert((rowsetRowCountArray_ == NULL) || (source.rowsetRowCountArray_ == NULL));
   if (source.rowsetRowCountArray_) {
     rowsetRowCountArray_ = new (collHeapPtr_) 
       NAArray<Int64>(*(source.rowsetRowCountArray_), collHeapPtr_);
   }

}

//
// Helper routine to copy a zero-terminated string to
// particular heap.
//
/*
static char *copyStringMember(char* src, CollHeap *heap)
{
  if (src==NULL) return src;

  char *copy;
  unsigned buffsize = str_len(src) + 1;

  copy = (char*) heap->allocateMemory(buffsize);
  assert(copy!=NULL);

#pragma nowarn(1506)   // warning elimination 
  str_cpy(copy,src,buffsize);
#pragma warn(1506)  // warning elimination 
  copy[buffsize-1]=0;

  return copy;
}
*/

ComDiagsArea::DiagsCondition* ComDiagsArea::DiagsCondition::copy()
{
  DiagsCondition *diagsCond = DiagsCondition::allocate(collHeapPtr_);
  assert(diagsCond!=NULL);

  *diagsCond = *this;

  return diagsCond;
}

ComDiagsArea* ComDiagsArea::copy()
{
  ComDiagsArea* diagsArea = ComDiagsArea::allocate(collHeapPtr_);
  assert(diagsArea!=NULL);

  diagsArea->collHeapPtr_ = collHeapPtr_;
  diagsArea->newCondition_ = newCondition_;
  diagsArea->areMore_ = areMore_;
  diagsArea->rowCount_ = rowCount_;
  diagsArea->avgStreamWaitTime_ = avgStreamWaitTime_;
  diagsArea->cost_ = cost_;
  diagsArea->theSQLFunction_ = theSQLFunction_;
  diagsArea->maxDiagsId_ = maxDiagsId_;
  diagsArea->flags_ = flags_;

  CollIndex i = 0;
  for (i=0; i < warnings_.entries(); i++)
    diagsArea->warnings_.insert(warnings_[i]->copy());

  for (i=0; i < errors_.entries(); i++)
    diagsArea->errors_.insert(errors_[i]->copy());

  if (rowsetRowCountArray_) {
     diagsArea->rowsetRowCountArray_ = new (collHeapPtr_) 
       NAArray<Int64>(*(rowsetRowCountArray_), collHeapPtr_);
   }
  else
    diagsArea->rowsetRowCountArray_ = NULL;


  return diagsArea;
}





// Marking and Rewinding
//
// The marking function can actually do what it is really supposed to:
// just return the value of the maxDiagsId_ member function.
// In the case that there is a current newCondition_ object (i.e.,
// that pointer is not NULL) then the returned value should be
// maxDiagsId_ - 1.

Lng32 ComDiagsArea::mark() const
{
   if (newCondition_ == NULL)
     return maxDiagsId_;
   else
     return maxDiagsId_-1;
}

// It iterates over the two linked lists,
// and deletes the tail portions that are ComConditioins
// with diags-id values greater
// than the given mark value.
//
// Alternative:  Under the category of ``road not taken''
// we have the following idea.  Have a data member of ComDiagsArea
// that is a stack of markValues, where the top is the most recently
// obtained mark.  When rewind is called, it checks the stack
// to see if the stack contains the given mark value.  If the the mark value
// is found to be valid (by being on the stack) then
// the stack is popped to just below the given mark value, and
// the deletion is performed.  Otherwise (and this is the big reason
// for having the stack in any case) we assertion fail since the mark
// is invalid.
//
// One more twist on this scheme that might be a further improvement
// would be to make the mark value an index into the sequence which
// is the stack.
//

void ComDiagsArea::rewind(Lng32 markValue, NABoolean decId)
{
   CollIndex  maxError = errors_.entries()-1;
#pragma nowarn(161)   // warning elimination 
   while (maxError != -1 && errors_[maxError]->getDiagsId() > markValue) {
#pragma warn(161)  // warning elimination 
       errors_[maxError]->deAllocate();
       NABoolean removed = errors_.removeAt(maxError--); 
       assert(removed);
       if (decId) --maxDiagsId_; // This is the merged line
   }
   CollIndex maxWarning = warnings_.entries()-1;
#pragma nowarn(161)   // warning elimination 
   while (maxWarning != -1 && warnings_[maxWarning]->getDiagsId() > markValue){
#pragma warn(161)  // warning elimination 
       warnings_[maxWarning]->deAllocate();
       NABoolean removed = warnings_.removeAt(maxWarning--);
       assert(removed);
       if (decId) --maxDiagsId_;
   }
}

// The algorithm for this function is two steps:
//   1) if the destPtr validly does not point to *this, then append/copy
//      the to-be-discarded ComConditions from this to *destPtr,
//      preserving order (and not reversing it, which would be easy to do).
//   2) perform the rewind of "this," discarding certain ComCondition objects.
//
// For step 1 we use a pair of for loops, the first for errors and the
// second for warnings.  Not that it should matter, but this WILL result
// in the ComCondition objects of *destPtr having a different chronological
// ordering than the ComConditions have originally in *this.  However,
// that should be of no consequence since, to those outside a ComDiagsArea,
// the ComConditions are always ordered by priority, with all errors before
// all warnings.

void ComDiagsArea::rewindAndMergeIfDifferent(Lng32 markValue,
					     ComDiagsArea  *destPtr)
{
  if (destPtr != NULL && destPtr != this) {
    CollIndex     i;
    for (i=0; i!=errors_.entries();i++)
      if (errors_[i]->getDiagsId() > markValue) {
	// copy/append errors_[i] to destPtr->errors_

	DiagsCondition *newPtr =
	  DiagsCondition::allocate(destPtr->collHeapPtr_);

	*newPtr = *(errors_[i]);
        newPtr->setDiagsId(++destPtr->maxDiagsId_);
	destPtr->errors_.insert(newPtr);
      }
    for (i=0; i!=warnings_.entries();i++)
      if (warnings_[i]->getDiagsId() > markValue) {
	// copy/append warnings_[i] to destPtr->warnings_
	DiagsCondition *newPtr =
	  DiagsCondition::allocate(destPtr->collHeapPtr_);

	*newPtr = *(warnings_[i]);
        newPtr->setDiagsId(++destPtr->maxDiagsId_);
	destPtr->warnings_.insert(newPtr);
      }
  rewind(markValue);
  }
}

void ComDiagsArea::deleteWarning(Lng32 entryNumber) {
  warnings_[entryNumber]->deAllocate();
  NABoolean removed = warnings_.removeAt(entryNumber);
  assert(removed);
  --maxDiagsId_;
}


void ComDiagsArea::deleteError(Lng32 entryNumber) {
  errors_[entryNumber]->deAllocate();
  NABoolean removed = errors_.removeAt(entryNumber);
  assert(removed);
  --maxDiagsId_;
}

ComCondition * ComDiagsArea::removeError(Lng32 entryNumber) {
  ComCondition * errCond = getErrorEntry(entryNumber+1);
  NABoolean removed = errors_.removeAt(entryNumber);
  assert(removed);
  return errCond ;
}


void ComCondition::destroyMe()
{
   this -> ~ComCondition();
}

void ComDiagsArea::destroyMe()
{
   this -> ~ComDiagsArea();
}

void ComDiagsArea::DiagsCondition::destroyMe()
{
#ifdef NA_MSVC                              // NT_PORT (bsv 11/7/96)
  this -> DiagsCondition::~DiagsCondition();
#else
  this -> ComDiagsArea::DiagsCondition::~DiagsCondition();
#endif
}

ComDiagsArea::DiagsCondition &
ComDiagsArea::DiagsCondition::operator= (const ComDiagsArea::DiagsCondition&d)
{
    ComCondition::operator=(d);
    diagsId_ = d.diagsId_;
    return *this;
}

void ComDiagsArea::removeFinalCondition100()
{
    // Might not have a SQL_EOF condition, because these
    // are not used on NT.

  if (warnings_.entries() == 0 ) 
    {
      return;
    }

  const CollIndex i = warnings_.entries() - 1;
  DiagsCondition *w100 = warnings_[i];
  if ((w100->getDiagsId() != maxDiagsId_ ) ||
      (w100->getSQLCODE() != 100))
    {
      return;
    }

  w100->deAllocate();
  warnings_.removeAt(i);
  --maxDiagsId_;
  return;
}

void ComDiagsArea::removeLastErrorCondition()
{
    // Might not have a SQL_EOF condition, because these
    // are not used on NT.

  if (errors_.entries() == 0 ) 
    {
      return;
    }

  const CollIndex i = errors_.entries() - 1;
  DiagsCondition *errCond = errors_[i];
  if (errCond->getDiagsId() != maxDiagsId_ ) 
    {
      return;
    }

  deleteError((Lng32) i);
  return;
}


///////////////////////////////////////////////////////////////
// returns TRUE, if any ComCondition in the diagsArea contains
// error SQLCode.
// returns FALSE, otherwise.
///////////////////////////////////////////////////////////////
NABoolean ComDiagsArea::contains(Lng32 SQLCode) const
{

  return containsError(SQLCode) || containsWarning(SQLCode);

} // end of ComDiagsArea::contains

NABoolean ComDiagsArea::containsError(Lng32 SQLCode) const
{
  for ( CollIndex i=0; i < errors_.entries(); i++ )
    {
      if ( errors_[i]->getSQLCODE() == SQLCode )
        {
          return TRUE;
        }
    }
  return FALSE;
}

NABoolean ComDiagsArea::containsWarning(Lng32 SQLCode) const
{
  return containsWarning(0, SQLCode);
}

// Check if warnings_ contains SQLCODE within the range [begin, warnings_.entries()). 
// Note begin is 0-based.
NABoolean ComDiagsArea::containsWarning(CollIndex begin, Lng32 SQLCode) const
{
  for ( CollIndex i=begin; i<warnings_.entries(); i++ )
    {
      if ( warnings_[i]->getSQLCODE() == SQLCode )
        {
          return TRUE;
        }
    }
   return FALSE;
}

  // returns TRUE, if diagsArea contains the fileName for error SQLCode.
  // returns FALSE, otherwise.
NABoolean ComDiagsArea::containsForFile(Lng32 SqlCd, const char * fileName)
{
	 ComDiagsArea* DA = ComDiagsArea::copy();
    if (!(*DA).contains(SqlCd))
		 return FALSE;


	 NABoolean fileNameExists = FALSE;

	 //Loop through Diagnostic area to check if extFileSetName is
	 //already present.
	 for (Lng32 j = 1 ; ((j <= (*DA).getNumber()) && (!(fileNameExists))); j++)
	 {
	     if( ((*DA)[j].getSQLCODE() == SqlCd) && 
		 ((strcmp(fileName, ((*DA)[j].getTableName()))) == 0) )
	     {
		 fileNameExists = TRUE;
	     }
	 }
	 return fileNameExists;
}

//returnIndex returns the index number of a given SQLCODE in this diagsarea
//If the given SQLCODE is not found in the diagsarea then NULL_COLL_INDEX is returned.
//The index is zero based. The index number for warnings is obtained by
//incrementing the array position of the particular SQLCODE by the total
//number of errors in this diagsarea. The CollIndex value returned is in a form suitable
//to be used by a method like ComDiagsArea::negateCondition(CollIndex ), if it is
//not equal to NULL_COLL_INDEX. 
CollIndex ComDiagsArea::returnIndex(Lng32 SQLCode) const
{
CollIndex i;
for ( i=0; i < errors_.entries(); i++ )
    {
      if ( errors_[i]->getSQLCODE() == SQLCode )
        {
          return i;
        }
    } 

  for ( i = 0; i < warnings_.entries(); i++ )
    {
      if ( warnings_[i]->getSQLCODE() == SQLCode )
        {
          return i + errors_.entries();
        }
    }
  return NULL_COLL_INDEX ;
} // end of ComDiagsArea::returnIndex




void ComDiagsArea::removeLastNonFatalCondition()
{
  if (warnings_.entries() == 0 ) 
    {
      return;
    }
  
  const CollIndex i = warnings_.entries() - 1;
  DiagsCondition *wNF = warnings_[i];
  
  if ((wNF->getDiagsId() != maxDiagsId_ ) ||
      ((wNF->getSQLCODE() != EXE_NONFATAL_ERROR_SEEN) &&
       (wNF->getSQLCODE() != EXE_NONFATAL_ERROR_ON_ALL_ROWS))
      )
    {
      return;
    }

  wNF->deAllocate();
  warnings_.removeAt(i);
  --maxDiagsId_;
  setNonFatalErrorSeen(FALSE);
  return;     
}

Lng32 ComDiagsArea::markDupNFConditions()
{ 
  CollIndex lnfw = 0;
  DiagsCondition *warningMark = NULL;

 if ((lnfw = returnIndex(EXE_NONFATAL_ERROR_ON_ALL_ROWS)) != NULL_COLL_INDEX)
    warningMark = warnings_[lnfw-errors_.entries()];
  else 
    if ((lnfw=returnIndex(EXE_NONFATAL_ERROR_SEEN)) != NULL_COLL_INDEX)
      warningMark= warnings_[lnfw-errors_.entries()];

 if(warningMark)
   return warningMark->getDiagsId();
 else
   return -1;
	      
  
}
// -----------------------------------------------------------------------
// ComDiagsTranslator::translateDiagsArea
//    A driver for the translation of individual conditions in a diags area
// -----------------------------------------------------------------------

void ComDiagsTranslator::translateDiagsArea 
                          ( ComDiagsArea &diags, 
                            const NABoolean twoPass)
{
  Int32 index;

  if (twoPass)
  {
    // First, run through the individual conditions and call the virtual
    // condition analyzer method, to allow our caller to figure out
    // what's in the diags area before translating conditions.
    firstError_ = TRUE;
    beforeAnalyze();
    for (index = 1; index <= diags.getNumber(); index++)
    {
      analyzeCondition (diags[index]);
      firstError_ = FALSE;
    }
  }

  ComDiagsArea * localDiags = diags.copy();
  diags.clearConditionsOnly ();
  firstError_ = TRUE;
  beforeTranslate();
  for (index = 1; index <= localDiags->getNumber(); index++)
  {
    // Run through the individual conditions, call the 
    // virtual condition translation method for each condition
    ComCondition &condition = (*localDiags)[index];
    if (!translateCondition (diags, condition))
    {
      // the condition translator method didn't translate the condition,
      // copy it unchanged
      ComCondition * newCondition = diags.makeNewCondition();
      *newCondition = condition;
      diags.acceptNewCondition();
    }
    firstError_ = FALSE;
  }
  afterTranslate();
  // deallocate the copy
  localDiags->deAllocate();
}


// -----------------------------------------------------------------------
// ComDiagsTranslator::analyzeCondition
//    Don't implement - derived classes that want to use this one
//    must provide it themselves
// -----------------------------------------------------------------------

void ComDiagsTranslator::analyzeCondition (const ComCondition &cond)
{ assert(0); }


// -----------------------------------------------------------------------
// Virtual methods, to be called before the first condition is processed.
// Derived classes that want to know about this can redefine.
// -----------------------------------------------------------------------

void ComDiagsTranslator::beforeAnalyze (void) {};
void ComDiagsTranslator::beforeTranslate (void) {};

// -----------------------------------------------------------------------
// Virtual method, to be called after the last condition is processed.
// Derived classes that want to know about this can redefine.
// Note that there is no "afterAnalyze" since that would be identical to
// "beforeTranslate".
// -----------------------------------------------------------------------

void ComDiagsTranslator::afterTranslate (void) {};


