/**********************************************************************
// @@@ 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"

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

#include <byteswap.h>

#include "ComRtUtils.h"

#ifdef _DEBUG
#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.

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
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
}



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

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;

  // 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;
}


// 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);
   assert(classSize == 376);
}

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);
   assert(classSize == 376);
}

// 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);
     }
     str_cpy(memberBuff,src,buffsize);
     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;
}

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

  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 _DEBUG
            // 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
      }
  }

// 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.");
  }
}

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

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

   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
     }
   }
}

// 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);
   assert(classSize == 328);
}

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


   // if (classSize != 320) printf("classSize=%d @ %d\n", classSize, __LINE__);
   assert(classSize == 328);
}


// 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())

         numToDiscard =  numToDiscard - warnings_.entries();
         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_.
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;
}

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 _DEBUG
  // 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 _DEBUG
  // 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
{
   return errors_.entries() + warnings_.entries();
}

Lng32     ComDiagsArea::getNumber (DgSqlCode::ErrorOrWarning type) const
{
   switch (type) {
     case DgSqlCode::ERROR_:	return errors_.entries();
     case DgSqlCode::WARNING_:	return warnings_.entries();
     default:			return -1;
   }
}


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

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


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

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

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

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

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

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

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

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

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

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

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


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

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


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


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

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

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

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


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

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

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

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

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


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

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

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

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

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

// And for the set/get methods:


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

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


// Finally, the IPC methods:

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

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

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

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

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

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

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

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

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

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

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

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

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

  const IpcConstMessageBufferPtr lastByte = buffer + objSize - 1;

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

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

  return TRUE;
}

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

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

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

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

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

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

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

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

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

   newCondition_=NULL;
   enforceLengthLimit();
}

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

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

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

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

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

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

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

  ComCondition * c = NULL;
  CollIndex i = 0;

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

  // sqlCode < 0

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



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

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

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

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

}

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

void ComDiagsArea::clearWarnings()
{
   DiagsCondition  *ptr;
   while (warnings_.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_);

   // 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_ ;
   }

   //    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);

  str_cpy(copy,src,buffsize);
  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;
   while (maxError != -1 && errors_[maxError]->getDiagsId() > markValue) {
       errors_[maxError]->deAllocate();
       NABoolean removed = errors_.removeAt(maxError--); 
       assert(removed);
       if (decId) --maxDiagsId_; // This is the merged line
   }
   CollIndex maxWarning = warnings_.entries()-1;
   while (maxWarning != -1 && warnings_[maxWarning]->getDiagsId() > markValue){
       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()
{
  this -> DiagsCondition::~DiagsCondition();
}

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) {};


