@@ -1671,8 +1671,8 @@ ComDiagsArea::ComDiagsArea (CollHeap* ptr): IpcMessageObj(IPC_SQL_DIAG_AREA,0),
 
 ComDiagsArea::ComDiagsArea () :             IpcMessageObj(IPC_SQL_DIAG_AREA,0),
                                             collHeapPtr_(NULL),
-                                            errors_(),
-                                            warnings_(),
+                                            errors_(NULL),
+                                            warnings_(NULL),
                                             newCondition_(NULL),
 					    lengthLimit_(30),
                                             areMore_(ComCondition::NO_MORE),
/**********************************************************************
// @@@ 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_(),
                                            warnings_(),
                                            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)
{
  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];
            break;
          }
      return c;
    }

  // sqlCode < 0

  for (i = 0; i < errors_.entries(); ++i)
    if (errors_[i]->getSQLCODE() == sqlCode)
      {
        c = errors_[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) {};



Is this another potential leak?