@@ -862,7 +862,17 @@ ex_expr::exp_return_type ex_expr::evalClauses(ex_clause *clause,
 	atp1->setDiagsArea(diagsArea);
 
       if (retcode == ex_expr::EXPR_ERROR)
-	return retcode;
+      {
+        if((getPCodeMode() & ex_expr::ERROR_CONTINUE) > 0)
+        {
+          ExpTupleDesc::setNullValue( op_data[0],
+                                      clause->getOperand(0)->getNullBitIndex(),
+                                      clause->getOperand(0)->getTupleFormat() );
+          retcode = ex_expr::EXPR_OK;
+        }
+        else
+	  return retcode;
+      }
 
       // copy result data into result buffer, if generated in an aligned buffer
       if (result_data)
/**********************************************************************
// @@@ 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:         exp_eval.cpp
 * Description:  Expression evaluator, makes operands accessible, calls
 *               NULL processing methods and/or evaluation methods on clauses
 *               
 * Created:      7/10/95
 * Language:     C++
 *
 *
 *
 *
 *****************************************************************************
 */

#include "Platform.h"



#include "exp_stdh.h"
#include "ExpAtp.h"
#include "exp_clause_derived.h"
#include "ExpPCode.h"
#include "exp_function.h"
#include "ComSysUtils.h"
#include "exp_bignum.h"
#include "BigNumHelper.h"
#include "ExpPCodeOptimizations.h"
#include "unicode_char_set.h"
#include "wstr.h"

#include <unistd.h>
#include <sys/mman.h>

#include "exp_ovfl_ptal.h"

#include "exp_ieee.h"
double MathConvReal64ToReal64(double op1, Int16 * ov);
#include <float.h>      /* nolist */
#include <limits.h>     /* nolist */

// 3 bit left circular shift op1, and xor with op2.
// Both op1 and op2 are UInt32.
#define EXP_SHIFT_XOR(op1, op2) \
  ( ( ((op1) << 3) | ((op1) >> 29) ) ^ (op2) ) 

// Clear the sign bit and toggle one other bit accordingly.
// result is UInt32
#define EXP_CLEAR_SIGNBIT(result) \
  ( ((result) & 0x80000000) ? ((result) ^ 0x80000002) : (result) )


NA_EIDPROC
void setVCLength(char * VCLen, Int32 VCLenSize, UInt32 value);

// --------------------------------------------------------------------
// Generate 31 bit hash value by
// multiplication, shift, and xor for every 4 byte.
// --------------------------------------------------------------------
NA_EIDPROC
SQLEXP_LIB_FUNC
UInt32 FastHash(char *data, Int32 length) 
{
  // FastHash should be removed someday
  assert( 0 /* "FastHash should not be used!" */ );

// scramble factors.  
#define MULT_FACTOR 0x97
#define SCRAMBLE_0 MULT_FACTOR
#define SCRAMBLE_1 0x2d5
#define SCRAMBLE_2 0x1d
#define SCRAMBLE_3 0x2ec3
 
  UInt32 result;   

  if (length == 4)
    {
      // Keep this logic in sync with case PCIT::HASH_MBIN32U_MBIN32_IBIN32S
      // in ex_expr_base::evalPCode.
      return *(UInt32 *)data;
    }
  else if (length == 2)
    {
      // Keep this logic in sync with case PCIT::HASH_MBIN32U_MBIN16_IBIN32S
      // in ex_expr_base::evalPCode.
      return (UInt32) (*(UInt16 *)data);
    }

  register UInt32 *source = (UInt32 *)data;
  register UInt32 z;

  if (length == 8)
    { 
#ifdef NA_LITTLE_ENDIAN
      z = *source * MULT_FACTOR;   
      result = source[1] * SCRAMBLE_1;
#else
      z = source[1] * MULT_FACTOR;
      result = *source * SCRAMBLE_1;
#endif
      result = EXP_SHIFT_XOR(result, z); 	
      return EXP_CLEAR_SIGNBIT(result);
    }

  result = 0;
  while (length >= 4)
    { // longer than 4 bytes and not 8 bytes
      z = (*source++) * SCRAMBLE_0;
      result = EXP_SHIFT_XOR(result, z); 	   
      length -= 4;
      if (length < 4) break;

      z = (*source++) * SCRAMBLE_1;
      result = EXP_SHIFT_XOR(result, z); 	   
      length -= 4;
      if (length < 4) break;

      z = (*source++) * SCRAMBLE_2;
      result = EXP_SHIFT_XOR(result, z); 	   
      length -= 4;
      if (length < 4) break;

      z = (*source++) * SCRAMBLE_3;
      result = EXP_SHIFT_XOR(result, z); 	   
      length -= 4;
    }

  if (length == 0)
    return EXP_CLEAR_SIGNBIT(result);

  // Copy the remaining 1, 2, or 3 bytes to a Int32.
  if (length == 1)
    z = *((unsigned char *)source);
  else {
    z = *((UInt16 *)source);
    if (length == 3) 
      z = (z << 8) + ((unsigned char *)source)[2];
  }
  z *= MULT_FACTOR;
  result = EXP_SHIFT_XOR(result, z); 
  return EXP_CLEAR_SIGNBIT(result);
}

// This static array is used when a default value is not null and the 
// attribute data format is SQLMX_ALIGNED_FORMAT.
// The default value is stored in SQLMX_FORMAT always and thus there
// is an impedence mismatch between the default value format and the
// disk format it is to be used for.
// This array is 16 bytes long and can accomodate 64 added columns
// that do have a default value.
// If the added column has no default or a default of null, then this
// the nulldata pointer is set to NULL and this static array is not used.
//
static const Int32 nullBitmapData[] = { 0, 0, 0, 0 };

NA_EIDPROC
ex_expr::exp_return_type getDefaultValueForAddedColumn(
     UInt32 field_num, // field number whose default value is to be
                              // computed. Zero based.
     ExpTupleDesc * td,       // describes this row
     Attributes * op,
     char ** opdata,
     char ** nulldata,
     char ** varlendata,
     CollHeap * heap,
     ComDiagsArea **diagsArea) 
{
  char * defaultValue = td->getAttr((Int16)field_num)->getDefaultValue();
  Attributes::DefaultClass dc =
                           td->getAttr((Int16)field_num)->getDefaultClass();

  //
  // Default values are stored in the packed SQLMX_FORMAT.
  // This may be a different format than the attribute tuple data format.

  if ((dc == Attributes::NO_DEFAULT) ||
      ((dc == Attributes::DEFAULT_NULL) &&
       (op->getNullFlag() == 0)))
    {
      ExRaiseSqlError(heap, diagsArea, EXE_DEFAULT_VALUE_ERROR);
      return ex_expr::EXPR_ERROR;
    }

  if (op->getNullFlag())
  {
    *nulldata = defaultValue;

    if (dc == Attributes::DEFAULT_NULL)
	*nulldata = NULL;
    else if ( op->isSQLMXAlignedFormat() )
    {
      if ( ExpTupleDesc::isNullValue( defaultValue,
                                      op->getNullBitIndex(),
                                      ExpTupleDesc::SQLMX_FORMAT ) )
        *nulldata = NULL;
      else
        *nulldata = (char *)nullBitmapData;
    }
  
    // Can't use the attribute field since the attribute describes the
    // disk field and not the default value itself.
    // op->getNullIndicatorLength();
    defaultValue += ExpTupleDesc::NULL_INDICATOR_LENGTH;
  }
  
  if (op->getVCIndicatorLength() > 0)
    *varlendata = defaultValue;

  *opdata = defaultValue + op->getVCIndicatorLength();

  return ex_expr::EXPR_OK;
}

/////////////////////////////////////////////////////////
// Computes the address of the field_num field. This
// field follows one (or more) varchar fields in a row
// with old format. This is true only for tables created
// in SQL/MP. In this format, all fields
// are stored next to each other in packed format(varchar
// fields are stored without blank padding).
/////////////////////////////////////////////////////////
NA_EIDPROC
SQLEXP_LIB_FUNC
void computeDataPtr(char * start_data_ptr, // start of data row
		    Int32 field_num,       // field number whose address is to be
		                           // computed. Zero based.
		    ExpTupleDesc * td,     // describes this row
		    char ** opdata,
		    char ** nulldata,
		    char ** varlendata) 
{
  if (! start_data_ptr)
    {
      if (nulldata)
	*nulldata = 0;
      return;
    }

  AttributesPtr * op = td->attrs();
  char * data_ptr = start_data_ptr;
  for (Int32 i = 0; i < field_num; i++, op++)
    {
      data_ptr += ((*op)->getNullFlag() ? 
		   (*op)->getNullIndicatorLength() : 0);
      data_ptr += (*op)->getVCIndicatorLength() + 
	(*op)->getLength(data_ptr);
      
    }
  
  if (((*op)->getNullFlag()) && (nulldata))
    *nulldata = data_ptr;
  
  if (((*op)->getVCIndicatorLength() > 0) && (varlendata))
    *varlendata = data_ptr + (*op)->getNullIndicatorLength();
  
  if (opdata)
    *opdata = data_ptr + (*op)->getNullIndicatorLength() + 
      (*op)->getVCIndicatorLength();
}

// Evaluate one or more clauses from an expression
// -- Helper for PCode abstract machine
//
ex_expr::exp_return_type ex_expr::evalClauses(ex_clause *clause,
					      atp_struct *atp1, 
					      atp_struct *atp2,
					      Int32 datalen,
					      UInt32 *rowLen,
					      Int16 *lastFldIndex,
					      char * fetchedDataPtr) {
  atp_struct *atps[] = {atp1, atp2};

  // a consecutive regions of ex_clause objects (actually subclasses of
  // ex_clause objects), linked by pointers

  // allocated space on the stack for pointers to point to null indicator,
  // var len indicator and actual data. There could be a maximum of
  // MAX_OPERANDS with the first operand of each group being the result.
  // The array contains first MAX_OPERANDS entries for null indicators,
  // the next MAX_OPERANDS for vclen and the last ones for actual data.
  char *op_data[ex_clause::MAX_OPERANDS * 3];

  // allocated space for temporary, aligned operands on the stack
  // (assuming that we have no more than 4 operands and that no operand
  // using the temp space is longer than 64 bytes).
  // Using buffer of type Int64 so it starts on an 8-byte aligned offset.
  Int64 temp_buffer[ex_clause::MAX_OPERANDS][ex_clause::MAX_TEMP_OPERAND_LEN/sizeof(Int64)];

  ex_expr::exp_return_type retcode = ex_expr::EXPR_OK;

  // these next 8 locals are for SQLMX tuple format only
  UInt32      varOffset = ExpOffsetMax,
              voaOffset = 0,
              offset    = 0,
              ff;
  Int16       varIndLen;
  Int16       nullIndLen;
  NABoolean   nullable  = FALSE;
  Attributes *currAttr  = NULL;
  Attributes *prevAttr  = NULL;

  NABoolean     setLastFldIndex = FALSE;
  NABoolean     varOpFound = FALSE;
  ExpTupleDesc *tuppDesc;

  ex_expr::exp_mode mode = ex_expr::exp_UNKNOWN;

  // ---------------------------------------------------------------------
  // Loop over clauses of the expression
  // ---------------------------------------------------------------------
  while (clause)
    {
      // an array of pointers to Attributes data structures, describing
      // the data types of the operands of this expression (op[0] points
      // to the result type)
      register AttributesPtr* op = clause->getOperand();
    
      // pointer to the null indicator data for current operand
      register char ** nulldata = &op_data[0];

      // pointer to the varlen indicator for current operand
      register char ** vardata = &op_data[ex_clause::MAX_OPERANDS];

      // pointer to data for current operand
      register char ** opdata = &op_data[2 * ex_clause::MAX_OPERANDS];

      // a pointer to the actual result buffer of the expression (used in
      // case the result is calculated in the temp buffer)
      char * result_data = NULL;
      
      // initialize the op_data array to all nulls
      //   for *every* clause!
      str_pad((char*)op_data, sizeof(op_data), '\0');

      // reset the variable operand
      currAttr = NULL;

      // for each operand, incrementing i, op, and opdata
      Int16 numOperands = clause->getNumOperands();
      for (Int16 i = 0; i < numOperands;
	   i++, op++, opdata++, nulldata++, vardata++)
	{
	  // -------------------------------------------------------------
	  // get pointer to operand from its ATP, ATPIndex, and offset
	  // value
	  // -------------------------------------------------------------

	  const UInt16 atpix = (*op)->getAtpIndex();
	  const UInt16 atpnum = (*op)->getAtp();

	  if((atpix < 2) && (NOT atps[0]->getTupp(atpix).isAllocated()))
	    {
	      if(!getFixupConstsAndTemps())
		{
		  char *base;
		  if(atpix == 0) base = getConstantsArea();
		  else if(atpnum == 0) base = getTempsArea();
		  else base = getPersistentArea();

		  *opdata = base + (*op)->getOffset();
		  *nulldata = base + (*op)->getNullIndOffset();
		  *vardata = base + (*op)->getVCLenIndOffset();
		}
	      else
		{
		  *opdata = (char*)((*op)->getOffset());
		  *nulldata = (char*)((*op)->getNullIndOffset());
		  *vardata = (char*)((*op)->getVCLenIndOffset());
		}
	    }
	  else
            {
		mode = (i == 0 ? exp_WRITE : exp_READ);

		// all other ATPIndex values indicate to use tupp
		// specified by ATPIndex from the ATP specifed in atp
		register atp_struct *atp;
		
		// which atp is to be used?
		atp = atps[atpnum];

                tuppDesc = atp->getCriDesc()->getTupleDescriptor(atpix);
		
		register char * dataPtr =
		                   (atp->getTupp(atpix)).getDataPointer();

		switch( (*op)->getTupleFormat() )
		  {
		  case ExpTupleDesc::SQLMX_KEY_FORMAT:
		  case ExpTupleDesc::PACKED_FORMAT:
		    {
		      // if this is a special field (either a field following
		      // a varchar field, or a missing field), then compute
		      // its address or value.
		      // If offset is ExpOffsetMax, then this field follows a
		      // varchar field.
		      // If the offset for a non-varchar field is >= the
		      // datalen of this record, then this is a missing
		      // field.
		      // For a varchar field, if the offset is equal to the
		      // datalen, then this varchar field either is a null
		      // value or has a length of zero.
		      // A varchar field is missing if its offset is > datalen.
		      if (((*op)->isSpecialField()) &&
			  (((*op)->getOffset() == ExpOffsetMax) ||
			   ((datalen > 0) &&
			    ((((*op)->getVCIndicatorLength() > 0) &&
			      ((*op)->getOffset() > (UInt32)datalen)) ||
			     (((*op)->getVCIndicatorLength() <= 0) &&
			      ((*op)->getOffset() >= (UInt32)datalen))))))
			{
			  NABoolean defValNeeded = FALSE;
		    
			  if ((*op)->getOffset() == ExpOffsetMax)
			    {
			      // Offset is max value thus read the field number
			      // from the relative offset field.
			      // This signifies that this field follows one or
                              // more varchar fields.
                              // True for SQL/MP tables only.
			      // Needs special logic to compute the actual
			      // address of this field.
			      computeDataPtr(dataPtr, 
					     (Int32)(*op)->getRelOffset(),
                                             tuppDesc,
					     &(*opdata),
					     &(*nulldata),
					     &(*vardata));
	
                              if ((mode == exp_WRITE) && (rowLen))
                              {
                                 currAttr = *op;
                                 varOffset = (*opdata - dataPtr);
                              }

			      // if *opdata is == the end, but vardata is set
			      // then the variable field is length 0 so no
			      // default needed
			      if ((datalen > 0 ) &&
				  ((*opdata > (dataPtr + datalen)) ||
				   ((*opdata == (dataPtr + datalen)) &&
				    (*vardata == NULL))))
				defValNeeded = TRUE;
			    }
			  else
			    defValNeeded = TRUE;
		      
   			  if ((defValNeeded) && (mode == exp_READ))
			    {
			      ComDiagsArea *diagsArea = atp1->getDiagsArea();

			      retcode = 
				getDefaultValueForAddedColumn((*op)->getDefaultFieldNum(),
							      tuppDesc,
							      *op,
							      &(*opdata),
							      &(*nulldata),
							      &(*vardata),
							      getHeap(),
							      &diagsArea);

			      if (retcode == ex_expr::EXPR_ERROR)
				{
				  if (diagsArea != atp1->getDiagsArea())
				    atp1->setDiagsArea(diagsArea);
			    
				  return retcode;
				}
			    }

			  // ----------------------------------------------
			  // For SQL/MP tables, evalClauses returns the 
			  // index of the last field in the fetched record.
			  // This is used by update processing logic to set the
			  // lastFldixOldrec fld in the ModifiedFieldMap struct,
			  // for use by DP2 on backout logic. lastFldIndex is set
			  // to the index of the last column for which a value 
			  // exists in the fetched record. 
			  //----------------------------------------------
			  if ((lastFldIndex != NULL) &&
			      (! setLastFldIndex)    && // last index not set before
			      (mode == exp_WRITE)    && // result operand
			      (tuppDesc->addedFieldPresent()))
			    {
			      // see if this column is present in the fetched
			      // row.
			      char * fetchedOpPtr;
			      computeDataPtr(fetchedDataPtr, 
					     (Int32)(*op)->getDefaultFieldNum(),
					     tuppDesc,
					     &fetchedOpPtr, NULL, NULL);
			      if (fetchedOpPtr >= (fetchedDataPtr + datalen))
				{
				  // (*op)->getDefaultFieldNum is the index of
				  // the first missing column.
				  *lastFldIndex = (Int16)((*op)->getDefaultFieldNum() - 1);
				  setLastFldIndex = TRUE;
				}
			    }
			}
		      else  // not a 'special' attribute
			{
                          if ((mode == exp_WRITE)    &&
                              (rowLen)               &&
                              (*op)->isSQLPackedFormat())
                          {	
                             varOffset = (*op)->getOffset();
                             currAttr = *op;
                          }

			  if (dataPtr)
			    {
			      *opdata = dataPtr + (*op)->getOffset();
			      if ((*op)->getNullFlag())   // nullable
				*nulldata = dataPtr + (*op)->getNullIndOffset();
			      if ((*op)->getVCIndicatorLength() > 0)
				*vardata = dataPtr + (*op)->getVCLenIndOffset();
			    }
			  else
			    {
			      // missing value. Indicates a null value.
			      *nulldata = 0;
			    }
			}
		    }  // SQLMX_KEY_FORMAT, PACKED_FORMAT
		  break;

		  case ExpTupleDesc::SQLARK_EXPLODED_FORMAT:
                  {
		    if (dataPtr)
		      {
			*opdata = dataPtr + (*op)->getOffset();
			if ((*op)->getNullFlag())   // nullable
			  *nulldata = dataPtr + (*op)->getNullIndOffset();
			if ((*op)->getVCIndicatorLength() > 0)
			  *vardata = dataPtr + (*op)->getVCLenIndOffset();
		      }
		    else
		      {
			// missing value. Indicates a null value.
			*nulldata = 0;
		      }
                  }
                  break;

                  case ExpTupleDesc::SQLMX_FORMAT:
                  case ExpTupleDesc::SQLMX_ALIGNED_FORMAT:
		    {
                      ExpTupleDesc::TupleDataFormat tdf = (*op)->getTupleFormat();

		      if (dataPtr)
			{
                          UInt32 nullOff = 0;
                          NABoolean isAlignedFormat =
                                       (*op)->isSQLMXAlignedFormat();
			  offset     = (*op)->getOffset();
			  nullable   = (*op)->getNullFlag();
                          nullIndLen = (*op)->getNullIndicatorLength();
			  varIndLen  = (*op)->getVCIndicatorLength();
			  voaOffset  = (*op)->getVoaOffset();

			  if (mode == exp_WRITE)
			    { 
			      if (offset == ExpOffsetMax)
                              {
                                  // all variable length fields after the
				  // first variable length field have their
				  // offsets initialized to ExpOffsetMax so
                                  // the actual size of the variable field value
                                  // is used to calculate the offset to be
                                  // written into VOA[i] for this variable field

				  offset = varOffset;
                                  ExpTupleDesc::setVoaValue(dataPtr, 
                                                            voaOffset, 
                                                            offset,
                                                            tdf);
				  if (nullable)
				    {
                                      nullOff = (isAlignedFormat
                                                 ? (*op)->getNullIndOffset()
                                                 : offset);

                                      *nulldata = dataPtr + nullOff;

				      offset += nullIndLen;
				    }
				  *vardata = dataPtr + offset;
				  offset  += varIndLen;

				  varOffset = offset;
				  currAttr  = *op;
				}
			      else // offsets computed at compile time
				{
				  if (varIndLen > 0)
				    {
				      *vardata  = dataPtr + (*op)->getVCLenIndOffset();
				      varOffset = offset;
				      currAttr     = *op;
				      varOpFound = TRUE;
				    }
				  else if ((! varOpFound)  &&
					   rowLen          &&
                                           isAlignedFormat &&
                                           ((offset >= varOffset) ||
                                            (varOffset == ExpOffsetMax)))
				  {
                                    // In aligned format, the fixed fields are
                                    // rearranged and ordered by byte alignment
                                    // and thus offsets are not guaranteed to
                                    // be increasing.
                                    // For variable fields this is not true.
                                    varOffset = offset;
                                    currAttr = *op;
                                  }

                                  // set the VOA entry offset to the start
                                  // of this fields data
                                  ExpTupleDesc::setVoaValue(
                                                  dataPtr,
						  voaOffset,
						  offset - varIndLen - nullIndLen,
                                                  tdf
                                                  );

				  if (nullable)
                                    *nulldata = dataPtr+(*op)->getNullIndOffset();
				}

			      *opdata = dataPtr + offset;
			    }
			  else  // read mode
			    {

                              // set the compile time null indicator offset here
                              // and it will be reset if added columns present
                              // or processing a varchar
                              *nulldata = dataPtr + (*op)->getNullIndOffset();
                              
                              // if there are added columns, then there exists
                              // a tuple descriptor
                              if (tuppDesc != NULL &&
                                  tuppDesc->addedFieldPresent() )
                              {

                                ff = ExpTupleDesc::getFirstFixedOffset( dataPtr,
                                                                        tdf );

                                if ( Attributes::isDefaultValueNeeded(
                                               (*op),
                                               tuppDesc,
                                               ff,
                                               varIndLen,
                                               voaOffset,
                                               dataPtr,
                                               datalen ) )
				{
				  ComDiagsArea *diagsArea = atp1->getDiagsArea();

                                  // this sets the *nulldata, *opdata, *vardata as needed				
                                  retcode =
				    getDefaultValueForAddedColumn
				    ((*op)->getDefaultFieldNum(),
                                     tuppDesc,
				     *op,
				     &(*opdata),
				     &(*nulldata),
				     &(*vardata),
				     getHeap(),
				     &diagsArea);

				  if (retcode == ex_expr::EXPR_ERROR)
				    {
				      if (diagsArea != atp1->getDiagsArea())
					atp1->setDiagsArea(diagsArea);
			    
				      return retcode;
				    }

                                  // all pointers are set now
                                  break;
				} 
			      else 
				{ // not an added column needing special attn.
                                  // but there may be other added columns present
                                  
                                  // if variable field, then read the offset from
                                  // the data record
                                  if ( varIndLen > 0 )
                                  {
                                    offset = ExpTupleDesc::getVoaOffset(dataPtr,
                                                                        voaOffset,
                                                                        tdf);
				  
                                  }
                                  else
                                  {
                                    // use the relative offset in case there are
                                    // added columns in the data row and fields
                                    // have shifted
                                    // Relative is always true based on first
                                    // fixed fields offset.
				    offset = ff + (*op)->getRelOffset();
                                  }
                                
                                  // For nullable fields, set the nulldata ptr
                                  // and bump the offset value past the null
                                  // indicator bytes.
				  if (nullable)
				  {
                                    *nulldata = dataPtr 
                                                + (isAlignedFormat 
                                                   ? ExpAlignedFormat::getBitmapOffset(dataPtr)
                                                   : offset);
          			    offset += nullIndLen;
				  }
                                } // need defaults or not
                              } // added col present or not

                              // No added col present.
                              // if variable field, read offset from data record
                              else if ( varIndLen > 0 )
                              {
                                offset = ExpTupleDesc::getVoaOffset(dataPtr,
                                                                    voaOffset,
                                                                    tdf);                               
                                if (nullable)
                                {
                                  // null indicator does not change for aligned format
                                  // but follows data for MX (packed) format
                                  *nulldata = (dataPtr 
                                               + (isAlignedFormat 
                                                 ? (*op)->getNullIndOffset()
                                                 : offset));
                                  offset += nullIndLen;
                                }
                              }

                              // offset now correctly set even if added columns.
                              // null indicator offset correct set too.

                              // For variable length fields, set the vardata
                              // and bump the offset value past the variable
                              // length bytes.
			      if (varIndLen > 0)
                              {
			        *vardata = dataPtr + offset;
				offset  += varIndLen;
			      }
				  
			      *opdata = dataPtr + offset;
                            } // else read mode
			}
		      else    // missing value (indicates a null value)
			*nulldata = 0;
			  
		    }  // SQLMX_FORMAT, SQLMX_ALIGNED_FORMAT
		  break;

		  default:
		    {
		      ComDiagsArea *diagsArea = atp1->getDiagsArea();
		      ExRaiseSqlError(getHeap(), &diagsArea, EXE_INTERNAL_ERROR);
		      if(diagsArea != atp1->getDiagsArea())
		        atp1->setDiagsArea(diagsArea);
		      return ex_expr::EXPR_ERROR;
		    }

		  }  // switch on atp tuple format
	      }  // default atp index case

	  // -------------------------------------------------------------
	  // If the operand is nullable, set its data pointer to 0 if
	  // its NULL indicator is set or set the NULL indicator to 0
	  // and advance the data pointer to the actual data. Don't do
	  // this for the first (result) operand at this time.
	  // -------------------------------------------------------------
	  if (((*op)->getNullFlag()) &&           // nullable and
	      (*nulldata)  &&                     // value not missing
              (i > 0))                            // not result
          {
            if ( ExpTupleDesc::isNullValue( *nulldata,
                                            (*op)->getNullBitIndex(),
                                            (*op)->getTupleFormat() ) )
            {
              (*nulldata) = 0;
            }
          }
	  

	} // for

	  
      // -----------------------------------------------------------------
      // Call the NULL processing method for this clause and, if still
      // necessary, evaluate the expression. Note that if the
      // processNulls() method can determine the result, it will return
      // EXPR_NULL and the evaluation method is not called.
      // -----------------------------------------------------------------
      ComDiagsArea *diagsArea = atp1->getDiagsArea();
      retcode = clause->useProcessNulls()
	      ? clause->processNulls(op_data, getHeap(), &diagsArea)
              : ex_expr::EXPR_OK;

      if (retcode == ex_expr::EXPR_OK)				// do the work
	retcode = clause->eval(&op_data[2 * ex_clause::MAX_OPERANDS],
			       getHeap(),
			       &diagsArea);

      if (retcode == ex_expr::EXPR_OK &&
          clause->getOperType()== ITM_CONVERT &&
          ((ex_conv_clause*)clause)->getLastVOAoffset() >0 &&
          ((ex_conv_clause*)clause)->getComputedLength() >0 )
      {
        varOffset = ((ex_conv_clause*)clause)->getComputedLength();
        currAttr = *(clause->getOperand());
      }
      else
      // Check if we have an operand that we need to keep track of the length
      // as we go.  This is a varchar attribute for SQLMX_FORMAT and
      // PACKED_FORMAT formats, and all attributes for SQLMX_ALIGNED_FORMAT
      // since fixed fields are rearranged.
      if ((currAttr && retcode == ex_expr::EXPR_OK) ||
          (currAttr                        &&
           (retcode == ex_expr::EXPR_NULL) &&
           ((currAttr->getTupleFormat() == ExpTupleDesc::PACKED_FORMAT) ||
            (currAttr->getTupleFormat() == ExpTupleDesc::SQLMX_ALIGNED_FORMAT))))
      {
        varOffset += currAttr->getLength(op_data[ex_clause::MAX_OPERANDS]);

        // Need the last attribute when we get done to adjust the row length
        // for aligned format.
        if (currAttr->isSQLMXAlignedFormat())
          prevAttr = currAttr;
      }
					     
      if (diagsArea != atp1->getDiagsArea())
	atp1->setDiagsArea(diagsArea);

      if (retcode == ex_expr::EXPR_ERROR)
	return retcode;

      // copy result data into result buffer, if generated in an aligned buffer
      if (result_data)
	{
	  str_cpy_all(result_data, (char*)temp_buffer[0], 
		      clause->getOperand(0)->getLength());
	}
 
      // advance to the next clause
      clause = clause->getNextClause();
    } // while

  if (rowLen && (varOffset != ExpOffsetMax))
  {
    currAttr = (currAttr ? currAttr : prevAttr);
    if ( currAttr )
      ex_clause::evalSetRowLength(currAttr,
                                  atps[currAttr->getAtp()],
                                  rowLen,
                                  varOffset);
    else
      *rowLen = varOffset;
  }
  return retcode;
}

NA_EIDPROC
static ex_expr::exp_return_type alignAndEval(ex_clause * clause,
					     char ** op_data,
					     CollHeap * heap,
					     ComDiagsArea ** diagsArea)
{
  ex_expr::exp_return_type retCode = ex_expr::EXPR_OK;

  // -------------------------------------------------------------
  // If data alignment is needed, copy the operand into
  // the aligned temp_buffer array on the stack. If this is done
  // for the result then remember the real result buffer.
  // -------------------------------------------------------------

  // an array of pointers to Attributes data structures, describing
  // the data types of the operands of this expression (op[0] points
  // to the result type)
  register AttributesPtr* op = clause->getOperand();


  // allocated space for temporary, aligned operands on the stack
  // (assuming that we have no more than 4 operands and that no operand
  // using the temp space is longer than 64 bytes).
  // Using buffer of type Int64 so it starts on an 8-byte aligned offset.
  Int64 temp_buffer[ex_clause::MAX_OPERANDS][ex_clause::MAX_TEMP_OPERAND_LEN/sizeof(Int64)];

  // pointer to data for current operand
  register char ** opdata = op_data;



  retCode = clause->eval(op_data, heap, diagsArea);
  

  return retCode;
}


// ex_expr::eval
//
// Interprets the expression. If there is no PCODE, evalClauses is used
// to interpret the expression. Otherwise, the PCODE is interpreted using
// a simple stack-based abstract machine.
//
// IN     : atp1, atp2 - pointers to tuple arrays
//          exHeap - memory allocation
// OUT    : 
// RETURN : The result of the expression 
//            EXPR_OK      - no errors and no return value from expression
//            EXPR_ERROR   - expression error
//            EXPR_TRUE    - the expression returned true
//            EXPR_FALSE   - the expression returned false
//            EXPR_UNKNOWN - the expression returned unknown
// EFFECTS: Executes expression which side effects a tuple or temporary or
//          computes a return value. May also change diagnostics area
//          of atps on error.
//
// NOTE   : When introducing new pcode instructions that involve an
//          an operation between signed shorter length operand and
//          unsigned longer length operand, then one of the operands
//          must be typecasted to Int64 to account for negetive values.
//          See case PCIT::LT_MBIN32S_MBIN16S_MBIN32U below for example.
//
// This variable provides 4096 bytes of null indicators.
//
static const Int64 nullData[] = {
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
};

//
// This table is used when comparing 2 operands.  Given the type of comparison
// to perform (1st level index) and an index indicating whether operand1 is
// less than, equal to, or greater than, operand2 (2nd level index), return
// TRUE or FALSE.
//
// Comp codes used in compTable lookup (2nd level index)
//
// if src1 >  src2  --> compCode = 2
// if src1 == src2  --> compCode = 1
// if src1 <  src2  --> compCode = 0
//

static const Int32 compTable[6][3] = {
  /* ITM_EQUAL */      {0, 1, 0},
  /* ITM_NOT_EQUAL */  {1, 0, 1},
  /* ITM_LESS */       {1, 0, 0},
  /* ITM_LESS_EQ */    {1, 1, 0},
  /* ITM_GREATER */    {0, 0, 1},
  /* ITM_GREATER_EQ */ {0, 1, 1}
};

#define FLT64ASSIGN(tgtptr, srcptr) {*((Int64*)(tgtptr)) = *((Int64*)(srcptr));}

//////////////////////////////////////////////////////////////////////////////
//
// Inlining Routines for PCODE Optimizations
//
// The following evalFast routines were designed to evaluat unique expressions
// identified at compile-time as "inlineable" exprs.  Inlined expressions
// do not call evalPCode().  Instead they call one of several evalFast methods.
// The evalPCode() method has a large setup and take-down cost because of its
// need to support all possible PCODE instructions.  It additionally has an
// instruction-switching overhead cost.  Each evalFast() method is designed to
// evaluate a particular PCODE instruction (or a couple of them).
//
// Below is a set of defines used in each evalFast() method.  PCODE_DEF is
// needed to declare the pcode bytestream pointer for each OS target.  The
// macro SETUP_EVAL_STK is used to set up the stack-based engine needed to
// evaluate the expression.  The stack created assumes that there are no
// more than 2 tuples to be processed.
//
// Also below is the routine setEvalPtr().  This routine is called at fixup
// time to initialize the evalPtr_ function pointer to point to one of the
// many fast eval methods.  It defines which PCODE instructions are inlineable.
//
// And lastly we have the set of evalFast methods.  The methods are defined as
// "evalFastXXX", where "XXX" is the enum value of the major PCODE instruction
// being processed in this inlineable expression.
//

  #define PCODE_DEF(p) PCodeBinary * pCode = p;

#ifdef _DEBUG
  #define DBGASSERT(p)  assert(p);
#else
  #define DBGASSERT(p)
#endif

  
#define SETUP_EVAL_STK(p, atp1, atp2, e)                                    \
  Long stack[6];                                                           \
  atp_struct *atps[] = { atp1, atp2 };                                      \
                                                                            \
  PCODE_DEF(p); /* Define pCode ptr */                                      \
                                                                            \
  Int32 startOffset = ((Int32)pCode[0] << 1) + 2; /* past 1st opcode */	\
                                                                            \
  stack[1] = (Long)(e->getConstantsArea()); /* Set up constants array */   \
                                                                            \
  stack[4] = (Long)atps[pCode[1]]->getTupp((Lng32)pCode[2]).getDataPointer(); \
  if (!stack[4]) {                                                          \
    DBGASSERT(0);  /* don't expect null tuples */                           \
    stack[4] = (Long)nullData;                                               \
  }                                                                         \
  if (startOffset != 4) {                                                   \
    stack[5] = (Long)atps[pCode[3]]->getTupp((Lng32)pCode[4]).getDataPointer();	\
    if (!stack[5]) {                                                        \
      DBGASSERT(0);  /* don't expect null tuples */                         \
      stack[5] = (Long)nullData;                                             \
    }                                                                       \
  }                                                                         \
                                                                            \
  pCode += (startOffset);


// Define a pointer name directly into the pcode
#define PTR_TO_PCODE(the_type,name,pcode_offset)	\
   the_type* name = (the_type*)&pCode[pcode_offset] ;

// Define a new pointer name to type ptype, and initialize its value from
// the stack (index from pCode) plus an offset (from the next pCode entry)
#define PTR_DEF_ASSIGN(ptype, name, pcode_offset)			\
   ptype* name = (ptype*)(stack[pCode[pcode_offset]] + pCode[pcode_offset+1]);

// only the base address, from the stack
#define BASE_PTR_DEF_ASSIGN(the_type, name,pcode_offset)	\
   the_type* name = (the_type*)stack[pCode[pcode_offset]] ;

// Define a new variable name of the type, and assign it a value from pCode
#define DEF_ASSIGN(the_type, name, pcode_offset)	\
  the_type name = (the_type) pCode[pcode_offset] ; 

// Same as DEF_ASSIGN but handle pointer in pcode binary
#define DEF_ASSIGN_PTR(the_type, name, pcode_offset)	\
  the_type name = *(the_type *)&(pCode[pcode_offset]) ; 

#define MOVE_INSTR(target_type, src_type) \
  *((target_type*)(stack[pCode[0]]+pCode[1])) =		\
    *((src_type*)(stack[pCode[2]]+pCode[3]));			\
  pCode += 4;							\
  break;
     
#define MOVE_CAST_INSTR(target_type, cast_type, src_type)	\
  *((target_type*)(stack[pCode[0]]+pCode[1])) =		\
    (cast_type) (*((src_type*)(stack[pCode[2]]+pCode[3])));	\
  pCode += 4;							\
  break;
     
// The length of PCodeBinary sequence of RANGE_LOW or RANGE_HIGH instruction
#define RANGE_INST_LEN 4

//
// Native Expr Routines at Runtime
//
int dbl_le_cmp (double x, double y) { return x <= y; }
int dbl_ge_cmp (double x, double y) { return x >= y; }
int dbl_lt_cmp (double x, double y) { return x < y; }
int dbl_gt_cmp (double x, double y) { return x > y; }
int dbl_eq_cmp (double x, double y) { return x == y; }
int dbl_ne_cmp (double x, double y) { return x != y; }

ex_expr::exp_return_type reportErr(atp_struct* atp1, ex_expr* expr)
{
  ComDiagsArea *diagsArea;

  diagsArea = atp1->getDiagsArea();
  ExRaiseSqlError(expr->getHeap(), &diagsArea, EXE_INTERNAL_ERROR);
  if(diagsArea != atp1->getDiagsArea())
    atp1->setDiagsArea(diagsArea);
  return ex_expr::EXPR_ERROR;
}

Int32 bignumSub(UInt16* tgt, UInt16* src1, UInt16* src2, Int32 length)
{
  NABoolean performAdd = TRUE;
  UInt16 carry = 0;
  Int32 i;

  Int32 length16 = length >> 1;

  // Get source sign bits
  char src1Sign = BIGN_GET_SIGN(src1, length);
  char src2Sign = BIGN_GET_SIGN(src2, length);

  char* origSrc1 = (char*)src1;
  char* origSrc2 = (char*)src2;

  char origSrc1Sign = src1Sign;
  char origSrc2Sign = src2Sign;

  // Temporarily clear sign bits
  BIGN_CLR_SIGN(src1, length);
  BIGN_CLR_SIGN(src2, length);

  if (TRUE) {
    if (src1Sign == src2Sign) {
      performAdd = FALSE;

      // We want to distribute the SUB operation into the signs of the
      // source operand so that everything is normalized as if we were
      // just doing an ADD and the source operands carried the sign.
      src2Sign = (src2Sign == 0) ? MSB_SET_MSK : 0;
    }
  }
  else {
    if (src1Sign != src2Sign)
      performAdd = FALSE;
  }

  if (performAdd)
  {
    // Add shorts - this is because bignum stored this way.
    for (i=0; i < length16; i++) {
      UInt32 result = (UInt32)src1[i] + src2[i] + carry;
      tgt[i] = (UInt16)(result & 0xffff);
      carry = (UInt16)(result >> 16);
    }
  }
  else
  {
    // Determine which source is bigger
    for (i = length16-1; i >= 0; i--) {
      // Skip equality
      if (src1[i] == src2[i])
        continue;

      if (src1[i] < src2[i]) {
        UInt16* temp = src1; src1 = src2; src2 = temp;
        char tempSign = src1Sign; src1Sign = src2Sign; src2Sign = tempSign;
      }

      break;
    }

    // Sub shorts - this is because bignum stored this way.
    for (i=0; i < length16; i++) {
      Int32 result = (Int32)src1[i] - src2[i] + (Int16)carry;
      tgt[i] = (UInt16) (result + (Int32)0x10000) & 0xffff;
      carry = (result < 0) ? -1 : 0;
    }
  }

  if (origSrc1Sign)
    BIGN_SET_SIGN(origSrc1, length);

  if (origSrc2Sign)
    BIGN_SET_SIGN(origSrc2, length);

  // Set target sign - will always be src1Sign, regardless of ADD/SUB
  if (src1Sign) {
    BIGN_SET_SIGN(tgt, length);
  } else {
    BIGN_CLR_SIGN(tgt, length);
  }

  // Report overflow
  return (carry != 0);
}

//
// Method used to initialize the evalPtr_ function pointer.  If the expression
// isn't marked for inlining, then evalPtr_ should be set to NULL.  Also, fast
// moves (strcpy) are evaluated directly by evalFast4().
//
void ex_expr_base::setEvalPtr( NABoolean isSamePrimary ) {
    
  static void* nativeGlobTable[] = {
    (void*)(&nullData),                  // JIT_GLOB_NULL_TABLE = 0 
    (void*)(&randomHashValues),          // JIT_GLOB_RANDOM_HASH_VALS_TABLE = 4
    (void*)(&charStringCompareWithPad),  // JIT_GLOB_COMPARE_WITH_PAD_FUNC = 8
    (void*)(&str_cmp),                   // JIT_GLOB_STRCMP_FUNC = 12
    (void*)(&str_cpy),                   // JIT_GLOB_STRCPY_FUNC = 16
    (void*)(&dbl_le_cmp),                // JIT_GLOB_DBL_LE_CMP_FUNC = 20
    (void*)(&dbl_ge_cmp),                // JIT_GLOB_DBL_GE_CMP_FUNC = 24
    (void*)(&dbl_lt_cmp),                // JIT_GLOB_DBL_LT_CMP_FUNC = 28
    (void*)(&dbl_gt_cmp),                // JIT_GLOB_DBL_GT_CMP_FUNC = 32
    (void*)(&dbl_eq_cmp),                // JIT_GLOB_DBL_EQ_CMP_FUNC = 36
    (void*)(&dbl_ne_cmp),                // JIT_GLOB_DBL_NE_CMP_FUNC = 40
    (void*)(&reportErr),                 // JIT_GLOB_REPORT_ERROR = 44
    (void*)(&bignumSub)                  // JIT_GLOB_BIG_SUB_FUNC = 48
  };

  PCodeBinary *pCode = getPCodeBinary();

  if (getPCodeNative()) {
    // evalPtr_ may have been previously set (send-top tcbs, for example,
    // share the same expr), then we can't initialize it again, since the
    // offset into the constants area where the native code resides is lost.
    // To tell if evalPtr_ hasn't been initialized yet, we check to see if it
    // still has a valid offset value within the constant's area.

    NABoolean doMProtect = FALSE ;

    if ((evalPtrOff_ >= 0) && (evalPtrOff_ <= getConstsLength())) {
       evalPtr_ = (evalPtrType)((Long)getConstantsArea() + (Long)evalPtr_);
       doMProtect = TRUE ;
    }
    else if ( ! isSamePrimary )
       doMProtect = TRUE ;

    if ( doMProtect ) {

      // Now give execute privilege to the page containing evalPtr_.  This will
      // have the side effect of giving other bytes in this page (not related
      // to native expr) execute privilege, so there may be a security risk
      // here.  Also note, this only needs to be done on Linux.
      //
      // NOTE: We could do a better job tightening the upper boundary for
      // which memory pages are executable, but it would require knowing the
      // length of the native expression and we don't currently keep that
      // info.
      //
      void* pageStart = (void*)((Long)evalPtr_ & ~(getpagesize() - 1));
      Int32 lenToAllow = (getConstantsArea() + getConstsLength()) - (char *)pageStart;
      Int32 err = mprotect(pageStart, lenToAllow,
                           PROT_READ | PROT_WRITE | PROT_EXEC);
   
      // If error occurred, do not go through with opt
      if (err != 0) {
        assert(FALSE);
        evalPtr_ = NULL;
        return;
      }
    }

    // Redefine pCode to point to the static function lookup table that can be
    // used at runtime.
    setPCodeBinary((PCodeBinary*)nativeGlobTable);

    return;
  }

  if (!getPCodeMoveFastpath() || (pCode == NULL)) {
    evalPtr_ = NULL;
    return;
  }

  Int32 length = *(Int32*)(pCode++);
  pCode += (2 * length);

  switch(pCode[0]) {
    // Comparisons
    case PCIT::EQ_MBIN32S_MBIN16S_MBIN16S:
      evalPtr_ = &ex_expr::evalFast33;
      break;

    case PCIT::EQ_MBIN32S_MBIN32S_MBIN32S:
      evalPtr_ = &ex_expr::evalFast36;
      break;

    case PCIT::EQ_MBIN32S_MBIN16U_MBIN16U:
      evalPtr_ = &ex_expr::evalFast37;
      break;

    case PCIT::EQ_MBIN32S_MBIN32U_MBIN32U:
      evalPtr_ = &ex_expr::evalFast40;
      break;

    case PCIT::EQ_MBIN32S_MASCII_MASCII:
      evalPtr_ = &ex_expr::evalFast117;
      break;

    case PCIT::LT_MBIN32S_MASCII_MASCII:
      evalPtr_ = &ex_expr::evalFast130;
      break;

    case PCIT::LE_MBIN32S_MASCII_MASCII:
      evalPtr_ = &ex_expr::evalFast131;
      break;

    case PCIT::GT_MBIN32S_MASCII_MASCII:
      evalPtr_ = &ex_expr::evalFast132;
      break;

    case PCIT::GE_MBIN32S_MASCII_MASCII:
      evalPtr_ = &ex_expr::evalFast133;
      break;

    case PCIT::EQ_MBIN32S_MBIN64S_MBIN64S:
      evalPtr_ = &ex_expr::evalFast162;
      break;

    case PCIT::NULL_TEST_MBIN32S_MATTR5_IBIN32S_IBIN32S:
      evalPtr_ = &ex_expr::evalFast262;
      break;

    case PCIT::COMP_MBIN32S_MASCII_MASCII_IBIN32S_IBIN32S_IBIN32S:
      evalPtr_ = &ex_expr::evalFast275;
      break;


    // Hash
    case PCIT::HASH_MBIN32U_MPTR32_IBIN32S_IBIN32S:
      evalPtr_ = &ex_expr::evalFast94;
      break;

    case PCIT::HASH_MBIN32U_MBIN32_IBIN32S_IBIN32S:
      evalPtr_ = &ex_expr::evalFast170;
      break;

    case PCIT::HASH_MBIN32U_MBIN16_IBIN32S_IBIN32S:
      evalPtr_ = &ex_expr::evalFast171;
      break;

    case PCIT::HASH_MBIN32U_MBIN64_IBIN32S_IBIN32S:
      evalPtr_ = &ex_expr::evalFast173;
      break;

    case PCIT::HASH2_DISTRIB:
      evalPtr_ = &ex_expr::evalFast223;
      break;


    // Moves
    case PCIT::MOVE_MBIN32U_MBIN32U:
      evalPtr_ = &ex_expr::evalFast202;
      break;

    case PCIT::MOVE_MBIN64S_MBIN64S:
      evalPtr_ = &ex_expr::evalFast203;
      break;

    default:
      evalPtr_ = NULL;
  }
}

// Moves

ex_expr::exp_return_type
ex_expr_base::evalFast4(PCodeBinary* p, atp_struct *atp1, atp_struct *atp2,ex_expr* e)
{
  SETUP_EVAL_STK(p, atp1, atp2, e); 
  #pragma refaligned 8 pCode

  PTR_DEF_ASSIGN(char,x,0);
  PTR_DEF_ASSIGN(char,y,2);

  str_cpy_all(x, y, pCode[4]);
  return ex_expr::EXPR_OK;
}

ex_expr::exp_return_type
ex_expr_base::evalFast202(PCodeBinary* p,atp_struct *atp1,atp_struct *atp2,ex_expr* e)
{
  SETUP_EVAL_STK(p, atp1, atp2, e); 
  #pragma refaligned 8 pCode

  PTR_DEF_ASSIGN(Int32,x,0);
  PTR_DEF_ASSIGN(Int32,y,2);

  *x = *y;
  return ex_expr::EXPR_OK;
}

ex_expr::exp_return_type
ex_expr_base::evalFast203(PCodeBinary* p,atp_struct *atp1,atp_struct *atp2,ex_expr* e)
{
  SETUP_EVAL_STK(p, atp1, atp2, e); 
  #pragma refaligned 8 pCode

  PTR_DEF_ASSIGN(Int64,x,0);
  PTR_DEF_ASSIGN(Int64,y,2);

  *x = *y;
  return ex_expr::EXPR_OK;
}


// Hash

ex_expr::exp_return_type
ex_expr_base::evalFast94(PCodeBinary* p, atp_struct *atp1,atp_struct *atp2,ex_expr* e)
{
  SETUP_EVAL_STK(p, atp1, atp2, e); 
  #pragma refaligned 8 pCode

  PTR_DEF_ASSIGN(UInt32,x,0);
  PTR_DEF_ASSIGN(char,y,2);

  *x = ExHDPHash::hash(y, pCode[4], pCode[5]);
  return ex_expr::EXPR_OK;
}

ex_expr::exp_return_type
ex_expr_base::evalFast170(PCodeBinary* p,atp_struct *atp1,atp_struct *atp2,ex_expr* e)
{
  SETUP_EVAL_STK(p, atp1, atp2, e); 
  #pragma refaligned 8 pCode

  PTR_DEF_ASSIGN(UInt32,x,0);
  PTR_DEF_ASSIGN(char,y,2);

  *x = ExHDPHash::hash4(y, pCode[4]);
  return ex_expr::EXPR_OK;
}

ex_expr::exp_return_type
ex_expr_base::evalFast171(PCodeBinary* p,atp_struct *atp1,atp_struct *atp2,ex_expr* e)
{
  SETUP_EVAL_STK(p, atp1, atp2, e); 
  #pragma refaligned 8 pCode

  PTR_DEF_ASSIGN(UInt32,x,0);
  PTR_DEF_ASSIGN(char,y,2);

  *x = ExHDPHash::hash2(y, pCode[4]);
  return ex_expr::EXPR_OK;
}

ex_expr::exp_return_type
ex_expr_base::evalFast173(PCodeBinary* p,atp_struct *atp1,atp_struct *atp2,ex_expr* e)
{
  SETUP_EVAL_STK(p, atp1, atp2, e); 
  #pragma refaligned 8 pCode

  PTR_DEF_ASSIGN(UInt32,x,0);
  PTR_DEF_ASSIGN(char,y,2);

  *x = ExHDPHash::hash8(y, pCode[4]);
  return ex_expr::EXPR_OK;
}

ex_expr::exp_return_type
ex_expr_base::evalFast223(PCodeBinary* p,atp_struct *atp1,atp_struct *atp2,ex_expr* e)
{
  SETUP_EVAL_STK(p, atp1, atp2, e); 
  #pragma refaligned 8 pCode

  PTR_DEF_ASSIGN(UInt32,x,0);
  PTR_DEF_ASSIGN(UInt32,y,2);
  PTR_DEF_ASSIGN(UInt32,z,4);

  *x = (UInt32)(((Int64)(*y) * (Int64)(*z)) >> 32);
  return ex_expr::EXPR_OK;
}


// Comparisons

ex_expr::exp_return_type
ex_expr_base::evalFast33(PCodeBinary* p, atp_struct *atp1,atp_struct *atp2,ex_expr* e)
{
  SETUP_EVAL_STK(p, atp1, atp2, e); 
  #pragma refaligned 8 pCode

  PTR_DEF_ASSIGN(Int16,x,2);
  PTR_DEF_ASSIGN(Int16,y,4);

  return (*x == *y) ? ex_expr::EXPR_TRUE : ex_expr::EXPR_FALSE;
}

ex_expr::exp_return_type
ex_expr_base::evalFast36(PCodeBinary* p, atp_struct *atp1,atp_struct *atp2,ex_expr* e)
{
  SETUP_EVAL_STK(p, atp1, atp2, e); 
  #pragma refaligned 8 pCode

  PTR_DEF_ASSIGN(Int32,x,2);
  PTR_DEF_ASSIGN(Int32,y,4);

  return (*x == *y) ? ex_expr::EXPR_TRUE : ex_expr::EXPR_FALSE;
}

ex_expr::exp_return_type
ex_expr_base::evalFast37(PCodeBinary* p, atp_struct *atp1,atp_struct *atp2,ex_expr* e)
{
  SETUP_EVAL_STK(p, atp1, atp2, e); 
  #pragma refaligned 8 pCode

  PTR_DEF_ASSIGN(UInt16, x,2);
  PTR_DEF_ASSIGN(UInt16, y,4);

  return (*x == *y) ? ex_expr::EXPR_TRUE : ex_expr::EXPR_FALSE;
}

ex_expr::exp_return_type
ex_expr_base::evalFast40(PCodeBinary* p, atp_struct *atp1,atp_struct *atp2,ex_expr* e)
{
  SETUP_EVAL_STK(p, atp1, atp2, e); 
  #pragma refaligned 8 pCode

  PTR_DEF_ASSIGN(UInt32,x,2);
  PTR_DEF_ASSIGN(UInt32,y,4);

  return (*x == *y) ? ex_expr::EXPR_TRUE : ex_expr::EXPR_FALSE;
}

ex_expr::exp_return_type
ex_expr_base::evalFast117(PCodeBinary* p,atp_struct *atp1,atp_struct *atp2,ex_expr* e)
{
  SETUP_EVAL_STK(p, atp1, atp2, e); 
  #pragma refaligned 8 pCode

  PTR_DEF_ASSIGN(unsigned char, x,2);
  PTR_DEF_ASSIGN(unsigned char,y,4);

  if (x[0] != y[0])
    return ex_expr::EXPR_FALSE;

  return (memcmp(x, y, pCode[6])==0) ? ex_expr::EXPR_TRUE : ex_expr::EXPR_FALSE;
}

ex_expr::exp_return_type
ex_expr_base::evalFast130(PCodeBinary* p,atp_struct *atp1,atp_struct *atp2,ex_expr* e)
{
  SETUP_EVAL_STK(p, atp1, atp2, e); 
  #pragma refaligned 8 pCode

  PTR_DEF_ASSIGN(unsigned char,x,2);
  PTR_DEF_ASSIGN(unsigned char,y,4);

  if (x[0] > y[0])
    return ex_expr::EXPR_FALSE;

  return (memcmp(x, y, pCode[6])<0) ? ex_expr::EXPR_TRUE : ex_expr::EXPR_FALSE;
}

ex_expr::exp_return_type
ex_expr_base::evalFast131(PCodeBinary* p,atp_struct *atp1,atp_struct *atp2,ex_expr* e)
{
  SETUP_EVAL_STK(p, atp1, atp2, e); 
  #pragma refaligned 8 pCode

  PTR_DEF_ASSIGN(unsigned char,x,2);
  PTR_DEF_ASSIGN(unsigned char,y,4);

  if (x[0] > y[0])
    return ex_expr::EXPR_FALSE;

  return (memcmp(x, y, pCode[6])<=0) ? ex_expr::EXPR_TRUE : ex_expr::EXPR_FALSE;
}

ex_expr::exp_return_type
ex_expr_base::evalFast132(PCodeBinary* p,atp_struct *atp1,atp_struct *atp2,ex_expr* e)
{
  SETUP_EVAL_STK(p, atp1, atp2, e); 
  #pragma refaligned 8 pCode

  PTR_DEF_ASSIGN(unsigned char,x,2);
  PTR_DEF_ASSIGN(unsigned char,y,4);

  if (x[0] < y[0])
    return ex_expr::EXPR_FALSE;

  return (memcmp(x, y, pCode[6])>0) ? ex_expr::EXPR_TRUE : ex_expr::EXPR_FALSE;
}

ex_expr::exp_return_type
ex_expr_base::evalFast133(PCodeBinary* p,atp_struct *atp1,atp_struct *atp2,ex_expr* e)
{
  SETUP_EVAL_STK(p, atp1, atp2, e); 
  #pragma refaligned 8 pCode

  PTR_DEF_ASSIGN(unsigned char,x,2);
  PTR_DEF_ASSIGN(unsigned char,y,4);

  if (x[0] < y[0])
    return ex_expr::EXPR_FALSE;

  return (memcmp(x, y, pCode[6])>=0) ? ex_expr::EXPR_TRUE : ex_expr::EXPR_FALSE;
}

ex_expr::exp_return_type
ex_expr_base::evalFast162(PCodeBinary* p,atp_struct *atp1,atp_struct *atp2,ex_expr* e)
{
  SETUP_EVAL_STK(p, atp1, atp2, e); 
  #pragma refaligned 8 pCode

  PTR_DEF_ASSIGN(Int64,x,2);
  PTR_DEF_ASSIGN(Int64,y,4);

  return (*x == *y) ? ex_expr::EXPR_TRUE : ex_expr::EXPR_FALSE;
}

ex_expr::exp_return_type
ex_expr_base::evalFast262(PCodeBinary* p,atp_struct *atp1,atp_struct *atp2,ex_expr* e)
{
  SETUP_EVAL_STK(p, atp1, atp2, e); 
  #pragma refaligned 8 pCode

  UInt32 pCode3 = (pCode[7] == 1) ? *((Int32*)(stack[pCode[2]] + pCode[4]))
                                  : pCode[3];

  NABoolean isNullCheck = (pCode[8] != 0);

  NABoolean srcNull = ExpTupleDesc::isNullValue(
    (char*)(stack[pCode[2]]+pCode3),
    (Int16)pCode[6],
    (ExpTupleDesc::TupleDataFormat)pCode[5]);

  if (srcNull && isNullCheck)
    return ex_expr::EXPR_TRUE;

  if (!srcNull && !isNullCheck)
    return ex_expr::EXPR_TRUE;

  return ex_expr::EXPR_FALSE;
}

ex_expr::exp_return_type
ex_expr_base::evalFast275(PCodeBinary* p,atp_struct *atp1,atp_struct *atp2,ex_expr* e)
{
  SETUP_EVAL_STK(p, atp1, atp2, e); 
  #pragma refaligned 8 pCode

  Int32 compCode;

  const Int32* table;
  #pragma refaligned 8 table

  // Set table pointer to appropriate position based on operation
  table = &(compTable[pCode[8] - ITM_EQUAL][1]);

  // "x" is the smaller string, "y" is the bigger one
  PTR_DEF_ASSIGN(unsigned char,x,2);
  PTR_DEF_ASSIGN(unsigned char,y,4);

  // Quick first byte compare
  if (x[0] == y[0]) {
    DEF_ASSIGN(Int32,len1,6);
    DEF_ASSIGN(Int32,len2,7);
    //Int32 len1 = pCode[6];
    //Int32 len2 = pCode[7];

    compCode = memcmp(x, y, len1);

    // Fix compCode to -1, 0, or 1
    if (compCode != 0) {
      compCode = (compCode < 0) ? -1 : 1;
    }
    // If strings are equal so far and lengths are different, compare more
    else if (len1 != len2) {
      for (Int32 i=len1; i < len2; i++) {
        if (y[i] == ' ')
          continue;

        compCode = (' ' < y[i]) ? -1 : 1;
        break;
      }
    }
  }
  else
    compCode = (x[0] < y[0]) ? -1 : 1;

  return (table[compCode] ? ex_expr::EXPR_TRUE : ex_expr::EXPR_FALSE);
}

/////////////////////////////////////////////////////////////////////////////


ex_expr::exp_return_type ex_expr::evalPCodeAligned(PCodeBinary* pCode32,
                                                   atp_struct *atp1,
                                                   atp_struct *atp2,
                                                   ULng32 *rowLen)
{
  return ex_expr::EXPR_ERROR;
}

// Guidelines for pcodes involving varchar source and/or varchar targets
// 
// PCodes involving varchars have to support these row formats:
// Packed format, exploded format and aligned format.
// 
// A Varchar operand should be defined as MATTR5 with the pcode values 
// in the following order: (atp, atpindex, offset, voaOffset, length, comboLen)
// where comboLen is a 4 byte integer whose first byte represents length of 
// nullIndicator and second byte represents length of VCIndicator, in bytes.
//
// Note that there is no nullbitmap index in the above notation because pcodes 
// related to null checking will use a shorter version than MATTR5 and 
// will have nullbitmap index as a pcode value.
// 
// If there is a need to check whether the operand is a varchar or not,
// check the value of VCIndLen.
//
// If there is a need to check whether the target is disk format or not,
// check the value of VoaOffset.
//
// Steps in which varchar pcodes should be evaluated for source operands:
// ---------------------------------------------------------------------
// 
// 1. Define a ptr to the start of the source row
//     char  *src = (char *)stack[pCode[2]];
//
// 2. Get the nullIndicator and VCIndicator lengths from the combo pcode
//    Int32 comboLen = pCode[6]; 
//    char* comboPtr = (char*)&comboLen;
//    Int16 srcNullIndLen = (Int16)comboPtr[0];
//    Int16 srcVCIndLen   = (Int16)comboPtr[1];
// 
//2a. Optionally, check if it is a varchar
//    if (srcVCIndLen > 0)
//
// 3. Call inline function getVarOffset() to get the offset to the the beginning 
//    of the varchar, i.e, to the offset of VCIndLen. Increment source to that offset.  
//    src += ExpTupleDesc::getVarOffset(src,
//                                      pCode[3],       // offset
//                                      pCode[4],       // voaOff
//                                      srcVCIndLen,    // vcIndLen
//                                      srcNullIndLen   // nullIndLen
//                                     );
//    If the supplied offset is valid (exploded format or first varchar), this
//    function would simply subtract the vcIndLen and return the new offset. 
//    If it is an indirect varchar, the offset will not be valid, the actual offset
//    will be obtained from the voaOffset and optionally nullIndLen will be added.
//
// 4. Get the actual length of the varchar by calling inline function getVarLength()
//    and increment the source to that offset.
//    srcLen = ExpTupleDesc::getVarLength(src, srcVCIndLen);
//    srcStr += srcVCIndLen; 
//
// 5. If the operand was not a varchar, use the offset and length given at compile time.
//      srcStr += pCode[3];
//      srcLen = pCode[5];
//
// src points to the start of the actual varchar data,  
// srcLen has the actual length of the varchar.
//
// Steps in which varchar pcodes should be evaluated for target operands.
// ---------------------------------------------------------------------
//
// 1. If target operand is a varchar, call getTgtVarOffset() to compute
//    the target offset. For non-disk format, it would just return 
//    offset - vcIndLen. For disk format, it will compute the offset
//    based on loop variable. This function would also update the VOA entry.
//              tgt += ExpTupleDesc::getTgtVarOffset( tgt,
//                                                    tgtOffset,    
//                                                    tgtVoaOffset, 
//                                                    tgtVCIndLen,
//                                                    tgtNullIndLen,
//                                                    varOffset,
//                                                    len0
//                                                  );
//
// 2. Update the varchar length at the varchar offset and increment the tgt pointer. 
//              if (tgtVCIndLen > 0) 
//              {
//                ExpTupleDesc::setVarLength(tgt, len0, tgtVCIndLen); 
//                tgt += tgtVCIndLen;
//              }
//
// 3. Do the desired operation.
//     if (len0 > 0)
//	 str_cpy_all(tgt, &src[start], len0);

ex_expr::exp_return_type ex_expr::evalPCode(PCodeBinary* pCode32,
					    atp_struct *atp1,
					    atp_struct *atp2,
					    ULng32 *rowLen)
{
  ComDiagsArea *diagsArea;

  PCodeBinary * pCode = pCode32;

  // Declarations for clause variables used in some cases of the
  // switch statement below. Declared here to make the compiler happy.
  //
  ex_clause *clause;
  ex_branch_clause *branchClause;

  // The return code is OK unless something happens to change it.
  //
  ex_expr::exp_return_type retCode = ex_expr::EXPR_OK;

  // Should runtime optimizations be performed
  //
  NABoolean enableRuntimeOpts = FALSE;

  // The stack used by the evaluator and a stack pointer
  //
  char *opData[3 * ex_clause::MAX_OPERANDS];
  char **opDataData = &opData[2 * ex_clause::MAX_OPERANDS];

  // dg64 - stack contains addresses
  Long stack[258];

  // The first N entries in the stack are reserved for pointers to 
  // the base addresses for the tuple data that is accessed by the
  // PCODE instructions. During PCODE generation the accessed ATPs
  // and indexes are recorded and preprended along with a count
  // to the PCODE instruction sequence.
  //
  atp_struct *atps[] = { atp1, atp2 };

  // dg64 - Use Long for stack
  stack[1] = (Long)(castToExExpr()->getMyConstantsArea());
  stack[2] = (Long)(castToExExpr()->getTempsArea());
  stack[3] = (Long)(castToExExpr()->getMyPersistentArea());

  Long lengthPlus4 = *(pCode) + 4;

  // Move past length.  Note, this was done before in conjunction with the
  // previous assignment, but because of a bug in the compiler which prevents
  // the refaligned pragma to be recognized in such cases, I separated the two
  // statements -
  pCode++;

  for(Long i=4; i<lengthPlus4; i++) {
    stack[i] = (Long)atps[pCode[0]]->getTupp((Lng32)pCode[1]).getDataPointer();

    // A null (C++ NULL) tuple data pointer indicates that the tuple
    // value is null (SQL NULL). This special case is handled here
    // rather than requiring every PCODE load/move instruction to
    // understand this case.
    //
    // Basically, the null tuple address is changed to point to 4096 bytes
    // of null data (from a variable above). Thus, the PCODE instructions
    // will unsuspectingly load/move this null data instead of the 
    // non-existent null data from the tuple.
    //
    // Caveats -- null pointer errors may be masked and moves are limited
    // to 4096 bytes (size of null data array).
    //
    if(!stack[i]) { 
      // Should remove this whole check when we are confident that we
      // will no longer see any null tuples
      DBGASSERT(0);  /* don't expect null tuples */
      stack[i] = (Long)nullData;
    }
    pCode += 2;
  }

  Int16  ov;	// overflow indicator

  double flt64_1;
  double flt64_2;

  // current max variable field offset
  // incremented everytime a variable field in disk format is evaluated
  Int32 varOffset = 0;
  // Keep track of write of varchars to aligned rows.  VOA values should always be increasing.
  Int32 lastVoaOffset = 0;

    PCodeBinary * pCodeOpcPtr;

  while(1) {
    PCodeBinary pCodeOpc;

    pCodeOpcPtr = pCode;
    pCodeOpc = *pCodeOpcPtr;

    pCode++;

    /**
    *** The large switch statement below results in a mis-predicted indirect
    *** branch every time we iterate through the loop.  This cost is severe.
    *** Since we know that one of the instructions has to be an END, we can
    *** directly check for that at the beginning of each iteration.  The
    *** conditional branch will always be dynamically predicted as not taken.
    *** When we do end up taking the branch, the target address will have
    *** already been calculated, and all that would happen would be 3 inserted
    *** pipeline bubbles.  Compare that to the 13+ cycles we lose each time
    *** from the mis-predicted branch. 
    **/

    if (pCodeOpc == PCIT::RETURN) {
      if (enableRuntimeOpts) {
        PCodeCfg* cfg = new(heap_) PCodeCfg(this, NULL, NULL, heap_, NULL);
        cfg->runtimeOptimize();
        NADELETE(cfg, PCodeCfg, heap_);
      }
      return retCode;
    }

    switch(pCodeOpc) {

    case PCIT::OPDATA_MBIN16U_IBIN32S:
    case PCIT::OPDATA_MPTR32_IBIN32S:
    case PCIT::OPDATA_MPTR32_IBIN32S_IBIN32S:
    case PCIT::OPDATA_MATTR5_IBIN32S:
    {
      // Loop through all opdata instructions and then fall-through to
      // eval instruction.  Note, the assumption is that opdata/eval instruction
      // sequences are contiguous - no intermediate instruction can exist
      // within this sequence.

      do {
	PTR_DEF_ASSIGN(char,src,0);

        if (pCodeOpc == PCIT::OPDATA_MPTR32_IBIN32S_IBIN32S)
        {
          // If the operand is NULL, leave 0 on the stack, otherwise a non-zero.
          NABoolean valueNull = ExpAlignedFormat::isNullValue((char *)src,
                                                              (Int16)pCode[2]);
          opData[pCode[3]] = (char *)(valueNull ? 0 : 1);
          pCodeOpc = pCode[4];
          pCode += 5;
        }
        else if (pCodeOpc == PCIT::OPDATA_MATTR5_IBIN32S)
        {
          // Set up the data pointer and vclen pointer (this one instruction
          // does both) for an indirect varchar field in aligned row format.  
          //
	  BASE_PTR_DEF_ASSIGN(char, dataPtr, 0);

	  DEF_ASSIGN(Int32,comboLen,4);
          char* comboPtr = (char*)&comboLen;
          Int16 nullIndLen = (Int16)comboPtr[0];
          Int16 vcIndLen   = (Int16)comboPtr[1];

	  DEF_ASSIGN(Int32,vcLoc,5);
          Int32 dataLoc = vcLoc + ex_clause::MAX_OPERANDS;

          // If this is the first operand it is a write.
          // So set the VOA entry for this varchar.
          if(vcLoc == ex_clause::MAX_OPERANDS) {

	    DEF_ASSIGN(Int32,tgtVoaOffset,2);
        
            // VOA offsets should always be used in order.
            if(tgtVoaOffset > 0) {
              assert(tgtVoaOffset > lastVoaOffset);
              lastVoaOffset = tgtVoaOffset;
            }

            ExpTupleDesc::setVoaValue(dataPtr, tgtVoaOffset, varOffset, vcIndLen); 
            dataPtr = dataPtr + varOffset;
            
          } else {
            // Otherwise, get the offset from the VOA entry.
	    DEF_ASSIGN(UInt32, offset, 1 );
	    DEF_ASSIGN(UInt32, voaOffset, 2 );
	
            dataPtr += ExpTupleDesc::getVarOffset(dataPtr,
                                                  offset,
                                                  voaOffset,
                                                  vcIndLen,      // vcIndLen
                                                  nullIndLen     // nullIndLen
                                                  );
          }

          // Update the VCLen pointer and the data pointer of
          // the opData array.
          opData[vcLoc] = dataPtr;
          opData[dataLoc] = dataPtr + vcIndLen;

          pCodeOpc = pCode[6];
          pCode += 7;
          
        }
        else
        {
          if (pCodeOpc == PCIT::OPDATA_MBIN16U_IBIN32S)
            src = (char*)(*((UInt16*)src) == 0);

          opData[pCode[2]] = src;
          pCodeOpc = pCode[3];
          pCode += 4;
        }
      } while (pCodeOpc != PCIT::CLAUSE_EVAL);

      //
      // Do NOT break here...
      // OPDATA and CLAUSE_EVAL go together
    }

    case PCIT::CLAUSE_EVAL:
      // on 64-bit platform, pCode[0] and pCode[1] store the clause ptr
      // and pCode[2] is check null indicator, while on 32-bit platform
      // pCode[0] alone stores the clause ptr. Use PCODEBINARIES_PER_PTR to
      // handle these differences.
      clause = (ex_clause*)*(Long*)&(pCode[0]);
      diagsArea = atp1->getDiagsArea();
      if(!(pCode[PCODEBINARIES_PER_PTR] && clause->processNulls(opData)))
	retCode = alignAndEval(clause, opDataData, getHeap(), &diagsArea);

      if (diagsArea != atp1->getDiagsArea())
	atp1->setDiagsArea(diagsArea);

      if(retCode == ex_expr::EXPR_ERROR) 
	return retCode;

      pCode += 1 + PCODEBINARIES_PER_PTR;
      break;

    case PCIT::HASHCOMB_BULK_MBIN32U:
    {
      UInt32 i, combRes = 0;
      UInt32 hashVals[PCodeCfg::MAX_HASHCOMB_BULK_OPERANDS];

      UInt32 numOfOps = ((UInt32)pCode[0] - 4) >> 2;
      UInt32 count = numOfOps;

      PTR_DEF_ASSIGN(UInt32,tgt,1);

      pCode += 3; // Move to first operand

      // Hash all source operands
      do {
	DEF_ASSIGN(Int32,len1,2);
	DEF_ASSIGN(Int32,len2,6);
	DEF_ASSIGN(Int32,pos1,3);
	DEF_ASSIGN(Int32,pos2,7);

	PTR_DEF_ASSIGN(unsigned char,src1,0);
	PTR_DEF_ASSIGN(unsigned char,src2,4);

        UInt64 result = ExHDPHash::hashP(src1, src2, len1, len2);

        UInt32 h1 = (len1 == 0) ? *((UInt32*)src1) : (UInt32)(result >> 32);
        UInt32 h2 = (len2 == 0) ? *((UInt32*)src2)
                                : (UInt32)(result & 0xFFFFFFFF);

        hashVals[pos1] = h1;
        hashVals[pos2] = h2;

        count -= 2;
        pCode += 8;
      } while (count > 1);

      if (count) {
	PTR_DEF_ASSIGN(char,src1,0);

        hashVals[pCode[3]] = (pCode[2] == 0) ? *((UInt32*)src1)
	  :  ExHDPHash::hash(src1, ExHDPHash::NO_FLAGS, 
			     (Int32)pCode[2]);
        pCode += 4;
      }

      // Join all operands (j of them) one at a time;
      combRes = hashVals[0];
      for (i=1; i < numOfOps; i++)
        combRes = ((combRes << 1) | (combRes >> 31)) ^ hashVals[i];

      *tgt = combRes;

      break;
    }

    case PCIT::NOT_NULL_BRANCH_BULK:
    {
      NABoolean isNull = FALSE;
      DEF_ASSIGN(Int32,length,0);
      length--;

      Int32 btgt = length - 1;

      if (pCode[1] == 0) {
        Int32 i = 3;
        Long tgt = stack[pCode[2]];
        do {
          // Retrieve null bit and check for nullness
          isNull = (*((Int16*)(tgt + pCode[i])) != 0);
          if (isNull)
            break;

          // Move to next offset
          i++;

        } while(i < btgt);
      }
      else {
        Long tgt, i = 2;
        do {
          tgt = stack[pCode[i]];
          // Retrieve null bit and check for nullness
          isNull = (*((Int16*)(tgt + pCode[i+1])) != 0);
          if (isNull)
            break;

          // Move to next offset
          i += 2;

        } while(i < btgt);
      }

      pCode += (isNull) ? length : pCode[btgt];
      break;
    }

    case PCIT::NULL_BITMAP_BULK:
    {
      //Int32 i;
      NABoolean isNull = FALSE;
      DEF_ASSIGN(Int32,length,0);
      length--;

      Int32 btgt = length - 1;

      if (pCode[1] == 0) {
	PTR_DEF_ASSIGN(char,nullDataPtr,2);

	PTR_TO_PCODE(char, bitmapMaskPtr, 5);

        for (Int32 i=0; i < (Int32)pCode[4]; i++) {
          isNull = (nullDataPtr[i] & bitmapMaskPtr[i]);
          if (isNull)
            break;
        }
      }
      else {
        for (Int32 i=2; i < btgt; i+=3) {
	  DEF_ASSIGN(Int32,nbi,i+2);
	  PTR_DEF_ASSIGN(char,nullDataPtr,i);

          isNull = (nbi == -1) ? (*nullDataPtr != 0) :
                       ExpAlignedFormat::isNullValue(nullDataPtr, (UInt16)nbi);

          if (isNull)
            break;
        }
      }

      pCode += (isNull) ? length : pCode[btgt];
      break;
    }

    case PCIT::MOVE_BULK:
    {
      Int32 i;
      DEF_ASSIGN(Int32,length,0);
      length--;

      Long tgtBase = stack[pCode[1]];
      Long srcBase = stack[pCode[2]];

      for (i=3; i != length; i+=3) {


        Long tgt = tgtBase + pCode[i+1];
        Long src = srcBase + pCode[i+2];


        switch (pCode[i]) {
          case PCIT::MOVE_MBIN8_MBIN8_IBIN32S:
            str_cpy_all((char*)tgt, (char*)src, (Lng32)pCode[i+3]);
            i++;
            break;

          case PCIT::MOVE_MBIN64S_MBIN64S:
            *((Int64*)tgt) = *((Int64*)src);
            break;

          case PCIT::MOVE_MBIN32U_MBIN32U:
            *((UInt32*)tgt) = *((UInt32*)src);
            break;

          case PCIT::MOVE_MBIN16U_MBIN16U:
            *((UInt16*)tgt) = *((UInt16*)src);
            break;

          case PCIT::MOVE_MBIN16U_IBIN16U:
            *((UInt16*)tgt) = (UInt16)pCode[i+2];
            break;

          case PCIT::MOVE_MBIN32S_IBIN32S:
            *((Int32*)tgt) = (Int32)pCode[i+2];
            break;

          case PCIT::MOVE_MBIN8_MBIN8:
            *((char*)tgt) = *((char*)src);
            break;
        }
      }

      pCode += length;
      break;
    }

    case PCIT::CLAUSE_BRANCH:
      // On 64-bit platform pCode[0] and pCode[1] contain branch pcode stream,
      // pCode[2] and pCode[3] store ptr to target clause, while on 32-bit
      // platform, only pCode[0] and pCode[1] are used for both.
      // Use PCODEBINARIES_PER_PTR to handle both platforms
      branchClause = (ex_branch_clause*)*(Long*)&(pCode[PCODEBINARIES_PER_PTR]);
      if(branchClause->get_branch_clause() == branchClause->getNextClause())
	pCode += (Int64)pCode[0];
      else
	pCode += PCODEBINARIES_PER_PTR + PCODEBINARIES_PER_PTR;
      break;

    case PCIT::RETURN_IBIN32S:
    {
      NABoolean res = (pCode[0] == 1);

      if (enableRuntimeOpts) {
        PCodeCfg* cfg = new(heap_) PCodeCfg(this, NULL, NULL, heap_, NULL);
        cfg->runtimeOptimize();
        NADELETE(cfg, PCodeCfg, heap_);
      }

      return ((res) ? ex_expr::EXPR_TRUE : ex_expr::EXPR_FALSE);
      break;
    }

    case PCIT::MOVE_MBIN32S:
    {
      PTR_DEF_ASSIGN(Int32,resultPtr,0);
      if ( *resultPtr == 1 ) retCode = ex_expr::EXPR_TRUE;
      else retCode = ex_expr::EXPR_FALSE;
      pCode += 2;
      break;
    }

    case PCIT::MOVE_MBIN32S_IBIN32S:
    {
      PTR_DEF_ASSIGN(UInt32,tmpUIntPtr,0);
      DEF_ASSIGN(UInt32,tmpUInt,2);
      * tmpUIntPtr = tmpUInt ;
      pCode += 3;
      break;
    }
    case PCIT::MOVE_MBIN16U_IBIN16U:
    {
      PTR_DEF_ASSIGN(UInt16, tmpUShortPtr,0);
      DEF_ASSIGN(UInt16, tmpUShort,2);
      * tmpUShortPtr = tmpUShort ;
      pCode += 3;
      break;
    }
    case PCIT::MOVE_MBIN8_MBIN8_IBIN32S:
    {
      PTR_DEF_ASSIGN(char,toPtr,0);
      PTR_DEF_ASSIGN(char,fromPtr,2);
      DEF_ASSIGN(UInt32,moveLen,4);
      str_cpy_all( toPtr, fromPtr, moveLen );
      pCode += 5;
      break;
    }
    // fixed length source to fixed length target. Lengths
    // are not equal. Currently only supports targetlen > srclen.
    case PCIT::MOVE_MASCII_MASCII_IBIN32S_IBIN32S:
      {
	DEF_ASSIGN(Int32,maxTgtLen, 4);
	DEF_ASSIGN(Int32,actualSrcLen, 5);

	PTR_DEF_ASSIGN(char,tgt, 0);
	PTR_DEF_ASSIGN(char,src, 2);

        char* pad = tgt + actualSrcLen;
        Int32 padLen = (maxTgtLen - actualSrcLen);

        str_cpy_all(tgt, src, actualSrcLen);

        // add blankpad
        str_pad(pad, padLen, ' ');

        pCode += 6;
        break;
      }

    // fixed length source to fixed length target. Lengths
    // are not equal. Currently only supports targetlen > srclen.
    case PCIT::MOVE_MUNI_MUNI_IBIN32S_IBIN32S:
      {
	DEF_ASSIGN(Int32,maxTgtLen, 4);
	DEF_ASSIGN(Int32,actualSrcLen, 5);

	PTR_DEF_ASSIGN(char,tgt, 0);
	PTR_DEF_ASSIGN(char,src, 2);

        NAWchar* pad = (NAWchar*)(tgt + actualSrcLen);
        Int32 padLen = (maxTgtLen - actualSrcLen) >> 1; // Shift for dbl-byte

        str_cpy_all(tgt, src, actualSrcLen);

        // add blankpad
        wc_str_pad(pad, padLen);

        pCode += 6;
        break;
      }

    // move varchar source to varchar target
    // source or target may be indirect. 
    case PCIT::MOVE_MATTR5_MATTR5:   
      {
	DEF_ASSIGN(Int32,maxTgtLen, 3);
	Int32 srcLen, copyLen;
	BASE_PTR_DEF_ASSIGN(char,src, 5);
	BASE_PTR_DEF_ASSIGN(char,tgt, 0);

	DEF_ASSIGN(Int32,comboLen1, 4);
        char* comboPtr1 = (char*)&comboLen1;      
        Int16 tgtNullIndLen = (Int16)comboPtr1[0];
        Int16 tgtVCIndLen   = (Int16)comboPtr1[1];

	DEF_ASSIGN(Int32,comboLen2, 9);
        char* comboPtr2 = (char*)&comboLen2;      
        Int16 srcNullIndLen = (Int16)comboPtr2[0];
        Int16 srcVCIndLen   = (Int16)comboPtr2[1];

	DEF_ASSIGN(UInt32,srcOffset, 6);
	DEF_ASSIGN(UInt32,srcVoaOffset, 7);

        src += ExpTupleDesc::getVarOffset(src,
                                          srcOffset, 
                                          srcVoaOffset,
                                          srcVCIndLen,   // vcIndLen
                                          srcNullIndLen  // nullIndLen
                                         );

        srcLen = ExpTupleDesc::getVarLength(src, srcVCIndLen);
        copyLen = ((maxTgtLen >= srcLen) ? srcLen : maxTgtLen);

        src += srcVCIndLen;

	DEF_ASSIGN(Int32,tgtOffset, 1);
	DEF_ASSIGN(Int32,tgtVoaOffset, 2);
        
        // VOA offsets should always be used in order.
        if(tgtVoaOffset > 0) {
          assert(tgtVoaOffset > lastVoaOffset);
          lastVoaOffset = tgtVoaOffset;
        }
        tgt += ExpTupleDesc::getTgtVarOffset( tgt,
                                              tgtOffset,     // tgt offset
                                              tgtVoaOffset,  // tgt voa offset
                                              tgtVCIndLen,
                                              tgtNullIndLen,
                                              varOffset,
                                              copyLen
                                            );
          
        ExpTupleDesc::setVarLength(tgt, copyLen, tgtVCIndLen);  // set variable length value
        tgt += tgtVCIndLen;  // bump past the vc indicator length field
        str_cpy_all(tgt, src, copyLen);

	pCode += 10;
      }
      break;

    // move varchar source to fixed target
    // source may be indirect
    case PCIT::MOVE_MASCII_MATTR5_IBIN32S:
      {
	DEF_ASSIGN(Int32,maxTgtLen, 7);
	Int32 srcLen, copyLen, padLen = 0;
	PTR_DEF_ASSIGN(char, dst, 0);
	BASE_PTR_DEF_ASSIGN(char, src, 2);

	DEF_ASSIGN(Int32,comboLen1, 6);
        char* comboPtr1 = (char*)&comboLen1;
        Int16 srcNullIndLen = (Int16)comboPtr1[0];
        Int16 srcVCIndLen   = (Int16)comboPtr1[1];

	DEF_ASSIGN(UInt32, srcOffset, 3);
	DEF_ASSIGN(UInt32, srcVoaOffset, 4);
        src += ExpTupleDesc::getVarOffset(src,
                                          srcOffset, 
                                          srcVoaOffset,
                                          srcVCIndLen,    // vcIndLen
                                          srcNullIndLen   // nullIndLen
                                         );

        srcLen = ExpTupleDesc::getVarLength(src, srcVCIndLen);
        padLen = maxTgtLen - srcLen;

        if (padLen > 0) {
          copyLen = srcLen;
          str_pad(dst + copyLen, padLen, ' ');
        } else {
          copyLen = maxTgtLen;
        }

        // Now copy in the value ...
        str_cpy_all(dst, src + srcVCIndLen, copyLen);

	pCode += 8;
      }
      break;

    // move fixed source to varchar target
    // target may be indirect. 
    case PCIT::MOVE_MATTR5_MASCII_IBIN32S:
      {
	PTR_DEF_ASSIGN(char, src, 5);

	DEF_ASSIGN(Int32, srcLen, 7);
	DEF_ASSIGN(Int32, maxTgtLen, 3);
        Int32 copyLen = ((maxTgtLen >= srcLen) ? srcLen : maxTgtLen);

	DEF_ASSIGN(Int32, comboLen1, 4);
        char* comboPtr1 = (char*)&comboLen1;      
        Int16 tgtNullIndLen = (Int16)comboPtr1[0];
        Int16 tgtVCIndLen   = (Int16)comboPtr1[1];

	BASE_PTR_DEF_ASSIGN(char, tgt, 0);
	DEF_ASSIGN(Int32, tgtOffset, 1);
	DEF_ASSIGN(Int32,tgtVoaOffset, 2);

        // VOA offsets should always be used in order.
        if(tgtVoaOffset > 0) {
          assert(tgtVoaOffset > lastVoaOffset);
          lastVoaOffset = tgtVoaOffset;
        }

        tgt += ExpTupleDesc::getTgtVarOffset( tgt,
                                              tgtOffset,     
                                              tgtVoaOffset,  
                                              tgtVCIndLen,
                                              tgtNullIndLen,
                                              varOffset,
                                              copyLen
                                            );
                    
        ExpTupleDesc::setVarLength(tgt, copyLen, tgtVCIndLen);  
        tgt += tgtVCIndLen;  
        str_cpy_all(tgt, src, copyLen);
                                   
	pCode += 8;
      }
      break;

    // convert varchar ptr source to Int32 or Int64
    case PCIT::CONVVCPTR_MBIN32S_MATTR5_IBIN32S:
    case PCIT::CONVVCPTR_MBIN64S_MATTR5_IBIN32S:
      {
	DEF_ASSIGN(Int32,maxTgtLen, 7);
	Int32 srcLen = 0;
	PTR_DEF_ASSIGN(char, dst, 0);
	BASE_PTR_DEF_ASSIGN(char, src, 2);

	DEF_ASSIGN(Int32,comboLen1, 6);
        char* comboPtr1 = (char*)&comboLen1;
        Int16 srcNullIndLen = (Int16)comboPtr1[0];
        Int16 srcVCIndLen   = (Int16)comboPtr1[1];

	DEF_ASSIGN(UInt32, srcOffset, 3);
	DEF_ASSIGN(UInt32, srcVoaOffset, 4);
        src += ExpTupleDesc::getVarOffset(src,
                                          srcOffset, 
                                          srcVoaOffset,
                                          srcVCIndLen,    // vcIndLen
                                          srcNullIndLen   // nullIndLen
                                         );

        srcLen = ExpTupleDesc::getVarLength(src, srcVCIndLen);

	// ptr to source value is stored at src as an Int64.
	Int64 ptrVal = *(Int64*)(src + srcVCIndLen);
	char * ptrSrc = (char*)ptrVal;

	// convert source to target (Int32)
	// First try simple conversion. If that returns an error, try complex conversion.
	NABoolean neg = FALSE;
	if (ptrSrc[0] == '-')
	  {
	    neg = TRUE;
	    ptrSrc++;
	    srcLen--;
	  }

	Int64 srcNumericVal = str_atoi(ptrSrc, srcLen);
	if (srcNumericVal == -1)
	  {
	    diagsArea = atp1->getDiagsArea();

	    ex_expr::exp_return_type er =
	      convDoIt(ptrSrc, srcLen, REC_BYTE_F_ASCII, 0, 0,
		       (char*)&srcNumericVal, sizeof(Int64), 
		       (pCodeOpc == PCIT::CONVVCPTR_MBIN64S_MATTR5_IBIN32S 
			? REC_BIN64_SIGNED : REC_BIN32_SIGNED), 
			0, 0, 
		       NULL, 0,
		       heap_, &diagsArea,
		       CONV_ASCII_BIN64S,
		       NULL, 0);

            if (diagsArea != atp1->getDiagsArea())
                   atp1->setDiagsArea(diagsArea);
	    if (er == ex_expr::EXPR_ERROR) 
	      return ex_expr::EXPR_ERROR;
	  }

	if (pCodeOpc == PCIT::CONVVCPTR_MBIN64S_MATTR5_IBIN32S)
	  {
	    if (neg)
	      *(Int64*)dst = -srcNumericVal; 
	    else
	      *(Int64*)dst = srcNumericVal; 
	  }
	else
	  {
	    if (neg)
	      *(Lng32*)dst = -(Int32)srcNumericVal; 
	    else
	      *(Lng32*)dst = (Int32)srcNumericVal; 
	  }
	  
	pCode += 8;
      }
      break;

   // convert varchar ptr source to Flt32
    case PCIT::CONVVCPTR_MFLT32_MATTR5_IBIN32S:
      {
	DEF_ASSIGN(Int32,maxTgtLen, 7);
	Int32 srcLen = 0;
	PTR_DEF_ASSIGN(char, dst, 0);
	BASE_PTR_DEF_ASSIGN(char, src, 2);

	DEF_ASSIGN(Int32,comboLen1, 6);
        char* comboPtr1 = (char*)&comboLen1;
        Int16 srcNullIndLen = (Int16)comboPtr1[0];
        Int16 srcVCIndLen   = (Int16)comboPtr1[1];

	DEF_ASSIGN(UInt32, srcOffset, 3);
	DEF_ASSIGN(UInt32, srcVoaOffset, 4);
        src += ExpTupleDesc::getVarOffset(src,
                                          srcOffset, 
                                          srcVoaOffset,
                                          srcVCIndLen,    // vcIndLen
                                          srcNullIndLen   // nullIndLen
                                         );

        srcLen = ExpTupleDesc::getVarLength(src, srcVCIndLen);

	// ptr to source value is stored at src as an Int64.
	Int64 ptrVal = *(Int64*)(src + srcVCIndLen);
	char * ptrSrc = (char*)ptrVal;

	// convert source to target (Flt32). 
	// First try simple conversion. If that returns an error, try complex conversion.
	NABoolean neg = FALSE;
	if (ptrSrc[0] == '-')
	  {
	    neg = TRUE;
	    ptrSrc++;
	    srcLen--;
	  }

	double srcNumericVal = str_ftoi(ptrSrc, srcLen);
	if (srcNumericVal == -1)
	  {
	    diagsArea = atp1->getDiagsArea();
	    ex_expr::exp_return_type er =
	      convDoIt(ptrSrc, srcLen, REC_BYTE_F_ASCII, 0, 0,
		       (char*)&srcNumericVal, sizeof(double), REC_FLOAT32, 0, 0, 
		       NULL, 0,
		       heap_, &diagsArea,
		       CONV_ASCII_FLOAT64,
		       NULL, 0);
            if (diagsArea != atp1->getDiagsArea())
                   atp1->setDiagsArea(diagsArea);
	    if (er == ex_expr::EXPR_ERROR) 
	      return ex_expr::EXPR_ERROR;
	  }

	if (neg)
	  *(float*)dst = - (float)srcNumericVal; 
	else
	  *(float*)dst = (float)srcNumericVal; 

	pCode += 8;
      }
      break;

    // convert varchar ptr source to varchar tgt
    case PCIT::CONVVCPTR_MATTR5_MATTR5:
      {
	DEF_ASSIGN(Int32,maxTgtLen, 3);
	Int32 srcLen, copyLen;
	BASE_PTR_DEF_ASSIGN(char,src, 5);
	BASE_PTR_DEF_ASSIGN(char,tgt, 0);

	DEF_ASSIGN(Int32,comboLen1, 4);
        char* comboPtr1 = (char*)&comboLen1;      
        Int16 tgtNullIndLen = (Int16)comboPtr1[0];
        Int16 tgtVCIndLen   = (Int16)comboPtr1[1];

	DEF_ASSIGN(Int32,comboLen2, 9);
        char* comboPtr2 = (char*)&comboLen2;      
        Int16 srcNullIndLen = (Int16)comboPtr2[0];
        Int16 srcVCIndLen   = (Int16)comboPtr2[1];

	DEF_ASSIGN(UInt32,srcOffset, 6);
	DEF_ASSIGN(UInt32,srcVoaOffset, 7);

        src += ExpTupleDesc::getVarOffset(src,
                                          srcOffset, 
                                          srcVoaOffset,
                                          srcVCIndLen,   // vcIndLen
                                          srcNullIndLen  // nullIndLen
                                         );

        srcLen = ExpTupleDesc::getVarLength(src, srcVCIndLen);
        copyLen = ((maxTgtLen >= srcLen) ? srcLen : maxTgtLen);

	// ptr to source value is stored at src as an Int64.
	Int64 ptrVal = *(Int64*)(src + srcVCIndLen);
	char * ptrSrc = (char*)ptrVal;

	DEF_ASSIGN(Int32,tgtOffset, 1);
	DEF_ASSIGN(Int32,tgtVoaOffset, 2);
        
        // VOA offsets should always be used in order.
        if(tgtVoaOffset > 0) {
          assert(tgtVoaOffset > lastVoaOffset);
          lastVoaOffset = tgtVoaOffset;
        }
        tgt += ExpTupleDesc::getTgtVarOffset( tgt,
                                              tgtOffset,     // tgt offset
                                              tgtVoaOffset,  // tgt voa offset
                                              tgtVCIndLen,
                                              tgtNullIndLen,
                                              varOffset,
                                              copyLen
                                            );
          
	if (copyLen < srcLen)
	  {
	    diagsArea = atp1->getDiagsArea();
	    ex_expr::exp_return_type er =
	      convDoIt(ptrSrc, srcLen, REC_BYTE_F_ASCII, 0, 0,
		       (tgt+tgtVCIndLen), maxTgtLen, REC_BYTE_V_ASCII, 0, 0, 
		       tgt, tgtVCIndLen,
		       heap_, &diagsArea,
		       CONV_ASCII_F_V,
		       NULL, 0);
            if (diagsArea != atp1->getDiagsArea())
               atp1->setDiagsArea(diagsArea);
	    if (er == ex_expr::EXPR_ERROR) 
	      return ex_expr::EXPR_ERROR;
	  }
	else
	  {
	    ExpTupleDesc::setVarLength(tgt, copyLen, tgtVCIndLen);  // set variable length value
	    tgt += tgtVCIndLen;  // bump past the vc indicator length field
	    str_cpy_all(tgt, ptrSrc, copyLen);
	  }

	pCode += 10;
      }
      break;

    case PCIT::STRLEN_MBIN32U_MATTR5:
    case PCIT::STRLEN_MBIN32U_MUNIV:
    {
      PTR_DEF_ASSIGN(UInt32, tgt, 0);

      BASE_PTR_DEF_ASSIGN(char, src, 2);
      UInt32 srcLen;

      DEF_ASSIGN(Int32, comboLen, 6);
      char* comboPtr = (char*)&comboLen;
      Int16 srcNullIndLen = (Int16)comboPtr[0];
      Int16 srcVCIndLen   = (Int16)comboPtr[1];

      DEF_ASSIGN(UInt32,srcOffset, 3);
      DEF_ASSIGN(UInt32,srcVoaOffset, 4);

      src += ExpTupleDesc::getVarOffset(src,
                                        srcOffset, 
                                        srcVoaOffset,
                                        srcVCIndLen,    // vcIndLen
                                        srcNullIndLen   // nullIndLen
                                       );

      srcLen = ExpTupleDesc::getVarLength(src, srcVCIndLen);

      // Divide length by 2 if we're dealing with a UCS2 string
      *tgt = (pCodeOpc == PCIT::STRLEN_MBIN32U_MATTR5)
             ? srcLen : (srcLen >> 1);

      pCode +=  7;
      break;
    }

    case PCIT::LIKE_MBIN32S_MATTR5_MATTR5_IBIN32S_IBIN32S:
    {
      PTR_DEF_ASSIGN(Int32, result, 0);
      Int32 retVal = 1;

      DEF_ASSIGN(Int32,comboLen1, 6);
      DEF_ASSIGN(Int32,comboLen2, 11);

      //
      // NOTE: Use "unsigned char" in the next 2 lines so that we do not
      //       get sign extension.  That way the 8-bit values pointed at
      //       can be 0 - 255 rather than only 0 - 127.
      //
      unsigned char* comboPtr1 = (unsigned char*)&comboLen1;
      unsigned char* comboPtr2 = (unsigned char*)&comboLen2;
      
      Int16 srcVCIndLen   = (Int16)comboPtr1[1];
      Int16 patVCIndLen   = (Int16)comboPtr2[1];
      Int16 srcNullIndLen = (Int16)comboPtr1[0];
      Int16 patNullIndLen = (Int16)comboPtr2[0];

      BASE_PTR_DEF_ASSIGN(char,srcStr, 2);
      BASE_PTR_DEF_ASSIGN(char,patStr, 7);

      DEF_ASSIGN(UInt32,srcOffset, 3);
      DEF_ASSIGN(UInt32,srcVoaOffset, 4);
      DEF_ASSIGN(UInt32,srcLen, 5);
      DEF_ASSIGN(UInt32,patOffset, 8);
      DEF_ASSIGN(UInt32,patVoaOffset, 9);
      DEF_ASSIGN(UInt32,patLen, 10);

      //UInt32 srcLen, patLen;

      if (srcVCIndLen > 0)
      {
        srcStr += ExpTupleDesc::getVarOffset(srcStr,
                                             srcOffset, 
                                             srcVoaOffset,
                                             srcVCIndLen,
                                             srcNullIndLen
                                            );                                           
        srcLen = ExpTupleDesc::getVarLength(srcStr, srcVCIndLen); 
        srcStr += srcVCIndLen; 
      }
      else
      {
	srcStr += srcOffset;
      }

      if (patVCIndLen > 0)
      {
        patStr += ExpTupleDesc::getVarOffset(patStr, 
                                             patOffset, 
                                             patVoaOffset,
                                             patVCIndLen,
                                             patNullIndLen
                                            );
        patLen = ExpTupleDesc::getVarLength(patStr, patVCIndLen);
        patStr += patVCIndLen;
      }
      else
      {
	patStr += patOffset;
      }
      
      // Set up pointers to offsets and lengths of all pattern strings
      //
      // NOTE: Use "unsigned char" so that offsets and lengths can be
      // up to 255.
      //
      PTR_TO_PCODE(unsigned char, pOffPtr, 12);
      PTR_TO_PCODE(unsigned char, pLenPtr, 13);

      char* tempSrc = srcStr;
      Int32 tempSrcLen = srcLen;

      Int32 numOfPatterns = comboPtr1[3];
      Int32 flags = comboPtr1[2];
      Int32 precision = comboPtr2[2];

      // ignore trailing filler blanks for UTF-8 arguments with a char limit
      if (precision)
        tempSrcLen = 
        srcLen     = lightValidateUTF8Str(tempSrc, tempSrcLen, precision, 0);

      // Iterate through each pattern string.  The length of the pattern string
      // can't exceed the remaining length of the source string to search.  As
      // pattern strings are found, shift up source string (i.e. temp string)
      // so that searching can continue with next pattern.  Also, we generate
      // pcode *only* if there is at least one pattern.

      for (Int32 i=0; i < numOfPatterns; i++) {
        Int32 pos;
        NABoolean fastCheck = FALSE;

        char* pat    = patStr + pOffPtr[i];
        Int32 patLen = pLenPtr[i];

        if (patLen > tempSrcLen) {
          retVal = 0;
          break;
        }

        // Do a fast check if flags indicate so for head of string
        if ((i == 0) && (flags & ex_like_clause_base::LIKE_HEAD))
          fastCheck = TRUE;

        // If flags indicate a search from tail of string, re-adjust pointers
        // so that a fast boundary search can be done with strcmp.
        if ((i == numOfPatterns-1) && (flags & ex_like_clause_base::LIKE_TAIL))
        {
          fastCheck = TRUE;
          tempSrc = srcStr + (srcLen - patLen);
          tempSrcLen = patLen;
        }

        // Perform search
        pos = ex_function_position::findPosition(pat, patLen, tempSrc,
                                                 tempSrcLen, fastCheck);

        // If match was not found, return false.
        if (pos == 0) {
          retVal = 0;
          break;
        }

        // Adjust pointers to source string to begin searching next pattern.
        tempSrc += (pos + patLen - 1);
        tempSrcLen -= (pos + patLen -1);
      }

      *result = retVal;

      pCode += 14;
      break;
    }

    case PCIT::POS_MBIN32S_MATTR5_MATTR5:
    {
      PTR_DEF_ASSIGN(Int32, result, 0);
      Int32 pos;

      DEF_ASSIGN(Int32, comboLen1, 6);
      DEF_ASSIGN(Int32, comboLen2, 11);
      char* comboPtr1 = (char*)&comboLen1;
      char* comboPtr2 = (char*)&comboLen2;

      Int16 patVCIndLen   = (Int16)comboPtr1[1];
      Int16 srcVCIndLen   = (Int16)comboPtr2[1];
      Int16 patNullIndLen = (Int16)comboPtr1[0];
      Int16 srcNullIndLen = (Int16)comboPtr2[0];

      BASE_PTR_DEF_ASSIGN(char, patStr, 2);
      BASE_PTR_DEF_ASSIGN(char, srcStr, 7);

      DEF_ASSIGN(UInt32,patOffset, 3);
      DEF_ASSIGN(UInt32,patVoaOffset, 4);
      DEF_ASSIGN(UInt32, patLen, 5);

      DEF_ASSIGN(UInt32,srcOffset, 8);
      DEF_ASSIGN(UInt32,srcVoaOffset, 9);
      DEF_ASSIGN(UInt32, srcLen, 10);

      if (patVCIndLen > 0)
      {
        patStr += ExpTupleDesc::getVarOffset(patStr,
                                             patOffset, 
                                             patVoaOffset,
                                             patVCIndLen,
                                             patNullIndLen
                                            );
        patLen = ExpTupleDesc::getVarLength(patStr, patVCIndLen);
        patStr += patVCIndLen;
      }
      else
      {
        patStr += patOffset;
      }

      if (srcVCIndLen > 0)
      {
        srcStr += ExpTupleDesc::getVarOffset(srcStr,
                                             srcOffset, 
                                             srcVoaOffset,
                                             srcVCIndLen,
                                             srcNullIndLen
                                            );                                           
        srcLen = ExpTupleDesc::getVarLength(srcStr, srcVCIndLen); 
        srcStr += srcVCIndLen; 
      }
      else
      {
        srcStr += srcOffset;
      }

      // Must check patLen first to ensure functionality correctness
      if (patLen == 0)
        pos = 1;
      else if (srcLen == 0)
        pos = 0;
      else
        pos =
          ex_function_position::findPosition(patStr,patLen,srcStr,srcLen,FALSE);

      *result = pos;

      pCode += 12;
      break;
    }

    case PCIT::CONCAT_MATTR5_MATTR5_MATTR5:
    {
      DEF_ASSIGN(Int32, comboLen1, 4);
      DEF_ASSIGN(Int32, comboLen2, 9);
      DEF_ASSIGN(Int32, comboLen3, 14);

      char* comboPtr1 = (char*)&comboLen1;
      char* comboPtr2 = (char*)&comboLen2;
      char* comboPtr3 = (char*)&comboLen3;

      Int16 tgtNullIndLen  = (Int16)comboPtr1[0];
      Int16 tgtVCIndLen    = (Int16)comboPtr1[1];
      Int16 src1NullIndLen = (Int16)comboPtr2[0];
      Int16 src1VCIndLen   = (Int16)comboPtr2[1];
      Int16 src2NullIndLen = (Int16)comboPtr3[0];
      Int16 src2VCIndLen   = (Int16)comboPtr3[1];

      BASE_PTR_DEF_ASSIGN(char, tgt, 0);
      BASE_PTR_DEF_ASSIGN(char, src1, 5);
      BASE_PTR_DEF_ASSIGN(char, src2, 10);
      DEF_ASSIGN(UInt32,src1Offset, 6);
      DEF_ASSIGN(UInt32,src1VoaOffset, 7);
      DEF_ASSIGN(UInt32,src1Len, 8);
      DEF_ASSIGN(UInt32,src2Offset, 11);
      DEF_ASSIGN(UInt32,src2VoaOffset, 12);
      DEF_ASSIGN(UInt32,src2Len, 13);

      if (src1VCIndLen > 0)
      {
        src1 += ExpTupleDesc::getVarOffset(src1,
					   src1Offset, 
					   src1VoaOffset,
                                             src1VCIndLen,
                                             src1NullIndLen
                                            );

        src1Len = ExpTupleDesc::getVarLength(src1, src1VCIndLen);
        src1 += src1VCIndLen;
      }
      else
      {
        src1 += src1Offset;
      }

      if (src2VCIndLen > 0)
      {
        src2 += ExpTupleDesc::getVarOffset(src2,
					   src2Offset, 
					   src2VoaOffset,
                                             src2VCIndLen,
                                             src2NullIndLen
                                            );

        src2Len = ExpTupleDesc::getVarLength(src2, src2VCIndLen);
        src2 += src2VCIndLen;
      }
      else
      {
        src2 += src2Offset; 
      }

      Int32 tgtLen  = src1Len + src2Len;
      DEF_ASSIGN(Int32, maxTgtLen, 3);
      if (tgtLen > maxTgtLen ) 
        goto Error1_;

      DEF_ASSIGN(Int32,tgtOffset, 1);
      DEF_ASSIGN(Int32,tgtVoaOffset, 2);

      if (tgtVCIndLen > 0)
      {
        // VOA offsets should always be used in order.
        if(tgtVoaOffset > 0) {
          assert(tgtVoaOffset > lastVoaOffset);
          lastVoaOffset = tgtVoaOffset;
        }

        tgt += ExpTupleDesc::getTgtVarOffset( tgt,
                                              tgtOffset, 
                                              tgtVoaOffset,
                                              tgtVCIndLen,
                                              tgtNullIndLen,
                                              varOffset,
                                              tgtLen
                                            );

        ExpTupleDesc::setVarLength(tgt, tgtLen, tgtVCIndLen); 
        tgt += tgtVCIndLen;  
      }
      else
      {
        tgt += tgtOffset;
      }

      str_cpy_all(tgt, src1, src1Len);
      str_cpy_all(&(tgt[src1Len]), src2, src2Len);

      pCode += 15;
      break;
    }

    case PCIT::SUBSTR_MATTR5_MATTR5_MBIN32S_MBIN32S:
    {
      // SUBSTRING
      // Source/target string can be in Exploded or Compressed Internal format.

      DEF_ASSIGN(UInt32, comboLen1, 4);
      DEF_ASSIGN(UInt32, comboLen2, 9);

      char* comboPtr1 = (char*)&comboLen1;
      char* comboPtr2 = (char*)&comboLen2;
      Int16 tgtNullIndLen = (Int16)comboPtr1[0];
      Int16 tgtVCIndLen   = (Int16)comboPtr1[1];
      Int16 srcNullIndLen = (Int16)comboPtr2[0];
      Int16 srcVCIndLen   = (Int16)comboPtr2[1];
      Int16 numOperands   = (Int16)comboPtr2[2];

      DEF_ASSIGN(UInt32, srcOffset, 6);
      DEF_ASSIGN(UInt32, srcVoaOffset, 7);
      DEF_ASSIGN(UInt32, srcMaxLen, 8);

      BASE_PTR_DEF_ASSIGN(char, src, 5);
      BASE_PTR_DEF_ASSIGN(char, tgt, 0);
      
      if (srcVCIndLen > 0) // is varchar
      {
        src += ExpTupleDesc::getVarOffset(src,
                                          srcOffset, 
                                          srcVoaOffset,
                                          srcVCIndLen,   
                                          srcNullIndLen);

        srcMaxLen = ExpTupleDesc::getVarLength(src, srcVCIndLen);
        src += srcVCIndLen;
      } 
      else
      {
        src += srcOffset; 
      }

      PTR_DEF_ASSIGN(Int32, startPtr, 10);
      PTR_DEF_ASSIGN(Int32, lengthPtr,12);
      Int64 start  = *startPtr; 
      Int64 length = *lengthPtr; 

      Int64 temp = ((numOperands > 0)
                    ? (start + length)
                    : ((start > (srcMaxLen + 1)) ? start : (srcMaxLen + 1)));

     // This error case must be when we have a potential overflow
     if (temp < start) {
       diagsArea = atp1->getDiagsArea();
       ExRaiseSqlError(heap_, &diagsArea, EXE_SUBSTRING_ERROR);

       if(diagsArea != atp1->getDiagsArea())
         atp1->setDiagsArea(diagsArea);
       return ex_expr::EXPR_ERROR;
     }

     Int32 len0 = 0;
     if ((start <= srcMaxLen) && (temp > 0)) {
       if (start < 1)
         start = 1;
       if (temp > (srcMaxLen + 1))
         temp = srcMaxLen + 1;
       len0 = (Int32)(temp - start);

       // The copy length can't be greater than the max target length
       DEF_ASSIGN(Int32, maxTgtLen, 3);
       if ( len0 > maxTgtLen ) len0 = maxTgtLen ;
     }

     src += (start - 1);

     DEF_ASSIGN(Int32, tgtOffset, 1);
     DEF_ASSIGN(Int32, tgtVoaOffset, 2);

     // VOA offsets should always be used in order.
     if(tgtVoaOffset > 0) {
       assert(tgtVoaOffset > lastVoaOffset);
       lastVoaOffset = tgtVoaOffset;
     }

     tgt += ExpTupleDesc::getTgtVarOffset( tgt,
                                           tgtOffset,     
                                           tgtVoaOffset,  
                                           tgtVCIndLen,
                                           tgtNullIndLen,
                                           varOffset,
                                           len0
                                         );
     if (tgtVCIndLen > 0) // if varchar
     {
       ExpTupleDesc::setVarLength(tgt, len0, tgtVCIndLen); 
       tgt += tgtVCIndLen;  
     }

     if (len0)
       str_cpy_all(tgt, src, len0);
     
     pCode += 14;
     break;
    }

    case PCIT::MOVE_MBIN16U_MBIN8:
      MOVE_INSTR( UInt16, UInt8 );

    case PCIT::MOVE_MBIN32U_MBIN16U:
      MOVE_INSTR( UInt32, UInt16 );

    case PCIT::MOVE_MBIN32S_MBIN16U: 
      MOVE_INSTR( Int32 , UInt16 );

    case PCIT::MOVE_MBIN64S_MBIN16U:
      MOVE_INSTR( Int64, UInt16 );

    case PCIT::MOVE_MBIN32U_MBIN16S:
      MOVE_INSTR( UInt32 , Int16 );

    case PCIT::MOVE_MBIN32S_MBIN16S:
      MOVE_INSTR( Int32 , Int16 );

    case PCIT::MOVE_MBIN64S_MBIN16S:
      MOVE_INSTR( Int64 , Int16 );

    case PCIT::MOVE_MBIN64S_MBIN32U:
      MOVE_INSTR( Int64 , UInt32 );

    case PCIT::MOVE_MBIN64S_MBIN32S:
      MOVE_INSTR( Int64 , Int32 );

    case PCIT::MOVE_MBIN8_MBIN8:
      MOVE_INSTR( unsigned char , unsigned char );

    case PCIT::MOVE_MBIN16U_MBIN16U:
      MOVE_INSTR( UInt16 , UInt16 );

    case PCIT::MOVE_MBIN32U_MBIN32U:
      MOVE_INSTR( UInt32 , UInt32 );
      
    case PCIT::MOVE_MBIN64S_MBIN64S:
      MOVE_INSTR( Int64 , Int64 );

    case PCIT::MOVE_MBIN64S_MDECS_IBIN32S:
      {
	PTR_DEF_ASSIGN(char, src, 2);
	PTR_DEF_ASSIGN(Int64, tgt, 0);
	
	if (src[0] & 0200)
	  {
	    *tgt = ((src[0] & 0177) - '0');
	  }
	else
	  {
	    *tgt = (src[0] - '0');
	  }
	for (Int32 k = 1; k < pCode[4]; k++)
	  {
	    *tgt = *tgt * 10 + (src[k] - '0');
	  }

	if (src[0] & 0200)
	  {
	    *tgt = -*tgt;
	  }

	pCode += 5;
      }
      break;

    case PCIT::MOVE_MBIN64S_MDECU_IBIN32S:
      {
	PTR_DEF_ASSIGN(char, src, 2);
	PTR_DEF_ASSIGN(Int64, tgt, 0);
	
	*tgt = 0;
	for (Int32 k = 0; k < pCode[4]; k++)
	  {
	    *tgt = *tgt * 10 + (src[k] - '0');
	  }

	pCode += 5;
      }
      break;

    case PCIT::MOVE_MFLT64_MBIN16S:
      MOVE_INSTR( double , short );

    case PCIT::MOVE_MFLT64_MBIN32S:
      MOVE_INSTR( double , Int32 );

    case PCIT::MOVE_MFLT64_MBIN64S:
      MOVE_CAST_INSTR( double , double, Int64 );

    case PCIT::MOVE_MFLT64_MFLT32:
      MOVE_INSTR( double , float );

    // Generated by ExHeaderClause ... new in R2.4
    case PCIT::HDR_MPTR32_IBIN32S_IBIN32S_IBIN32S_IBIN32S_IBIN32S:
    {
      BASE_PTR_DEF_ASSIGN(char, data, 0 );
      PTR_DEF_ASSIGN(char, hdrStart , 0 );

      // Clear the header area
      str_pad(hdrStart, pCode[2], '\0');
      
      // Set the first fixed offset
      if ( pCode[4] == sizeof(Int16) )
        *((UInt16 *)hdrStart) = (UInt16)pCode[3];
      else
        *((Int32 *)hdrStart) = (Int32)pCode[3];

      // Set the bitmap offset if relevant (n/a for SQLMX_FORMAT)
      if ( pCode[5] > 0 )
        *((Int16 *)(data + pCode[6])) = (Int16)pCode[5];

      pCode += 7;

      break;
    }

    case PCIT::NULL_MBIN16U:
    {
      PTR_DEF_ASSIGN(Int16, tmpPtr, 0 );
      * tmpPtr = 0x00;
      pCode += 2;
      break;
    }
    case PCIT::NULL_BITMAP:
    {
      PTR_DEF_ASSIGN(char, bitmap, 0 );
      DEF_ASSIGN(Int16, bitIdx , 3 );
      // for aligned format's null bitmap
      switch (pCode[2])
      {
        case PCIT::NULL_BITMAP_SET:
        {
          // Either clear a bit or set one ...
          if ( pCode[4] )
	    ExpAlignedFormat::setNullBit( bitmap, bitIdx );
          else
            ExpAlignedFormat::clearNullBit( bitmap, bitIdx );

          pCode += 5;
          break;
        }
        case PCIT::NULL_BITMAP_TEST:
        {
	  assert(0);   // this code is not used
	  // in case this code is to become used: missing below are
	  //   -- return the value from isNullValue()
	  //   -- advance the pCode
	  
          // Test a bit to see if it is null or not.
          ExpAlignedFormat::isNullValue( bitmap, bitIdx );
	  
          break;
        }
      }
    }
    break;

    case PCIT::NULL_BYTES:
    {
      // for packed format
      DEF_ASSIGN(UInt32, nullIndOffset, 1 );
      DEF_ASSIGN(Int16, tmp, 2 );

      if (nullIndOffset == ExpOffsetMax)
	nullIndOffset = varOffset;

      *(Int16 *)(stack[pCode[0]] + nullIndOffset) = tmp;

     pCode += 3;
     break;
    }

    case PCIT::NULL_MBIN16U_IBIN16U:
    {
      PTR_DEF_ASSIGN(Int16, tmpPtr16 , 0);
      DEF_ASSIGN(Int16, tmp16, 2 );
      * tmpPtr16 = tmp16 ;
      pCode += 3;
      break;
    }

    case PCIT::NULL_TEST_MBIN32S_MBIN16U_IBIN32S:
      // for packed format
    {
      PTR_DEF_ASSIGN(Int16, tmpPtr16, 2);
      DEF_ASSIGN(Int16, tmp16, 4);
      PTR_DEF_ASSIGN(Int32, resultPtr, 0);
      * resultPtr = ( *tmpPtr16 == tmp16 ) ? 1 : 0 ;
      pCode += 5;
      break;
    }

    case PCIT::NOT_NULL_BRANCH_MBIN16S_IBIN32S:
      {
	PTR_DEF_ASSIGN(Int16, resultPtr, 0);

	// Not sure why we cast to Int64 ?
	if( *resultPtr == 0 ) 
          pCode += (Int64)pCode[2];
	else 
          pCode += 3;
      }
    break;
      
    case PCIT::NOT_NULL_BRANCH_MBIN16S_MBIN16S_IBIN32S:
      {
	PTR_DEF_ASSIGN(Int16, returnResultPtr, 0);
	PTR_DEF_ASSIGN(Int16, resultPtr, 2);
	* returnResultPtr = * resultPtr ;
	if( *resultPtr == 0 ) pCode += (Int64)pCode[4];
	else pCode += 5;
      }
    break;

      
    case PCIT::NOT_NULL_BRANCH_MBIN32S_MBIN16S_IBIN32S:
      {
	PTR_DEF_ASSIGN(Int32, returnResultPtr32, 0);
	PTR_DEF_ASSIGN(Int16, resultPtr16, 2);
	* returnResultPtr32 = * resultPtr16 ;
	if( * resultPtr16 == 0 ) pCode += (Int64)pCode[4];
	else pCode += 5;
      }
    break;

    // nullBranchHelper - two operands
    case PCIT::NOT_NULL_BRANCH_MBIN32S_MBIN32S_MBIN32S_IATTR4_IBIN32S:
      // Handles all data formats
      // If either source operands are null, then target is null.
      // If neither source operands are null, then clear target null indicator.
      {                 
        // If NullIndOffset is negative, it indicates that it is an indirect
        // varchar in packed format and its positive value gives the voaOffset
        // where the actual offset can be found (read 4 bytes from VOA entry).
        // For exploded and aligned format the NullIndOffsets will never be
        // negative since the null indicator offset is known at compile time.
        UInt32 op2NullIndOff = 
	  pCode[3] < 0 ? *((Int32 *)(stack[pCode[2]]+(-pCode[3]))) : pCode[3];
        UInt32 op3NullIndOff = 
	  pCode[5] < 0 ? *((Int32 *)(stack[pCode[4]]+(-pCode[5]))) : pCode[5];

        // for target operand, if NullIndOffset is negative, use loop variable
        // varOffset to get to the next available varchar. This only applies
        // to packed format. All other formats will have valid NullIndOffset. 
        // Note that varOffset is not incremented here. It will be incremented and
        // voaOffset will be set when the actual varchar data is written.
        UInt32 op1NullIndOff = pCode[1] < 0 ? varOffset : pCode[1];
        
        // Map a group of pcodes to PCodeAttrNull struct. 
        PCodeAttrNull *attrs = (PCodeAttrNull *)&pCode[6];

        NABoolean op2Null =
          ExpTupleDesc::isNullValue((char *)stack[pCode[2]] + op2NullIndOff,
                                    (Int16)attrs->op2NullBitIndex_,
                                    (ExpTupleDesc::TupleDataFormat)attrs->fmt_.op2Fmt_);
	NABoolean op3Null =
          ExpTupleDesc::isNullValue((char *)stack[pCode[4]] + op3NullIndOff,
                                    (Int16)attrs->op3NullBitIndex_,
                                    (ExpTupleDesc::TupleDataFormat)attrs->fmt_.op3Fmt_);

	if( op2Null || op3Null )  // either one is null
        {
          ExpTupleDesc::setNullValue((char*)(stack[pCode[0]] + op1NullIndOff),
                                     (Int16)attrs->op1NullBitIndex_,
                                     (ExpTupleDesc::TupleDataFormat)attrs->fmt_.op1Fmt_);
          pCode += attrs->fmt_.size_;
        }
	else
        {
          ExpTupleDesc::clearNullValue((char*)(stack[pCode[0]] + op1NullIndOff),
                                       (Int16)attrs->op1NullBitIndex_,
                                       (ExpTupleDesc::TupleDataFormat)attrs->fmt_.op1Fmt_);
          pCode += (Int64)pCode[10];
        }
      }
    break;

    case PCIT::NOT_NULL_BRANCH_MBIN32S_MBIN32S_IATTR3_IBIN32S:
      // nullBranchHelper - one operand
      // Handles all data formats
      // If source operand is null, then target is null.
      // If source operand is not null, then clear target null indicator.
      { 
        // If NullIndOffset is negative, it indicates that it is an indirect
        // varchar in packed format and its positive value gives the voaOffset
        // where the actual offset can be found (read 4 bytes from VOA entry).
        // For exploded and aligned format the NullIndOffsets will never be
        // negative since the null indicator offset is known at compile time.
        UInt32 op2NullIndOff =
	  pCode[3] < 0 ? *((Int32 *)(stack[pCode[2]]+(-pCode[3]))) : pCode[3];

        // for target operand, if NullIndOffset is negative, use loop variable
        // varOffset to get to the next available varchar. This only applies
        // to packed format. All other formats will have valid NullIndOffset. 
        // Note that varOffset is not incremented here. It will be incremented and
        // voaOffset will be set when the actual varchar data is written.
        UInt32 op1NullIndOff = pCode[1] < 0 ? varOffset : pCode[1];  
                
        PCodeAttrNull *attrs = (PCodeAttrNull *)&pCode[4];
        
        NABoolean op2Null =
          ExpTupleDesc::isNullValue((char *)stack[pCode[2]] + op2NullIndOff,
                                    (Int16)attrs->op2NullBitIndex_,
                                    (ExpTupleDesc::TupleDataFormat)attrs->fmt_.op2Fmt_);

	if( op2Null ) // check to see if operand is null
        {
          ExpTupleDesc::setNullValue((char*)(stack[pCode[0]] + op1NullIndOff),
                                     (Int16)attrs->op1NullBitIndex_,
                                     (ExpTupleDesc::TupleDataFormat)attrs->fmt_.op1Fmt_);
          pCode += attrs->fmt_.size_;
        }
	else
        {
          ExpTupleDesc::clearNullValue((char*)(stack[pCode[0]] + op1NullIndOff),
                                       (Int16)attrs->op1NullBitIndex_,
                                       (ExpTupleDesc::TupleDataFormat)attrs->fmt_.op1Fmt_);
          pCode += (Int64)pCode[7];
        }
      }
    break;

    case PCIT::NOT_NULL_BRANCH_COMP_MBIN32S_MBIN32S_MBIN32S_IATTR4_IBIN32S:
      // nullBranchHelperForComp - two operands
      {
        // If NullIndOffset is negative, it indicates that it is an indirect
        // varchar in packed format and its positive value gives the voaOffset
        // where the actual offset can be found (read 4 bytes from VOA entry).
        // For exploded and aligned format the NullIndOffsets will never be
        // negative since the null indicator offset is known at compile time.
        UInt32 op2NullIndOff =
	  pCode[3] < 0 ? *((Int32 *)(stack[pCode[2]]+(-pCode[3]))) : pCode[3];
        UInt32 op3NullIndOff =
	  pCode[5] < 0 ? *((Int32 *)(stack[pCode[4]]+(-pCode[5]))) : pCode[5];
  
        PCodeAttrNull *attrs = (PCodeAttrNull *)&pCode[6];

        NABoolean  op2Null =
          ExpTupleDesc::isNullValue((char*)(stack[pCode[2]] + op2NullIndOff),
                                    (Int16)attrs->op2NullBitIndex_,
                                    (ExpTupleDesc::TupleDataFormat)attrs->fmt_.op2Fmt_);
        NABoolean  op3Null =
          ExpTupleDesc::isNullValue((char*)(stack[pCode[4]] + op3NullIndOff),
                                    (Int16)attrs->op3NullBitIndex_,
                                    (ExpTupleDesc::TupleDataFormat)attrs->fmt_.op3Fmt_);

        Int32 rslt = (op2Null || op3Null) ? -1 : 0;

	PTR_DEF_ASSIGN(Int32, result, 0 );
	* result = rslt ;
        if (rslt == 0)
          pCode += (Int64)pCode[10];
        else
          pCode += attrs->fmt_.size_;
      }
    break;

    case PCIT::NOT_NULL_BRANCH_COMP_MBIN32S_MBIN32S_IATTR3_IBIN32S:
      // nullBranchHelperForComp - one operand
      {
        // If NullIndOffset is negative, it indicates that it is an indirect
        // varchar in packed format and its positive value gives the voaOffset
        // where the actual offset can be found (read 4 bytes from VOA entry).
        // For exploded and aligned format the NullIndOffsets will never be
        // negative since the null indicator offset is known at compile time.
        UInt32 op2NullIndOff =
	  pCode[3] < 0 ? *((Int32 *)(stack[pCode[2]]+(-pCode[3]))) : pCode[3];
  
        PCodeAttrNull *attrs = (PCodeAttrNull *)&pCode[4];

        NABoolean  op2Null =
          ExpTupleDesc::isNullValue((char*)(stack[pCode[2]] + op2NullIndOff),
                                    (Int16)attrs->op2NullBitIndex_,
                                    (ExpTupleDesc::TupleDataFormat)attrs->fmt_.op2Fmt_);

        Int32 rslt = (op2Null) ? -1 : 0;

	PTR_DEF_ASSIGN(Int32, result, 0 );
	* result = rslt ;
        if (rslt == 0)
          pCode += (Int64)pCode[7];
        else
          pCode += attrs->fmt_.size_;
      }
    break;


    case PCIT::NOT_NULL_BRANCH_MBIN32S_MBIN16S_IBIN32S_IBIN32S:
      {
	PTR_DEF_ASSIGN(Int32, resultPtr32, 0 );
	PTR_DEF_ASSIGN(Int16, resultPtr16, 2 );
	DEF_ASSIGN(Int32, val32 , 4 );

	if( * resultPtr16 == 0 ) 
	  pCode += (Int64)pCode[5];
	else 
	  {
	    * resultPtr32 = val32 ;
	    pCode += 6;
	  }
      }
    break;
      
    case PCIT::NOT_NULL_BRANCH_MBIN32S_MBIN16S_MBIN16S_IBIN32S:
      {
	PTR_DEF_ASSIGN(Int32, ptr32 , 0 );
	PTR_DEF_ASSIGN(Int16, ptr16_1, 2 );
	PTR_DEF_ASSIGN(Int16, ptr16_2, 4 );
	Int16 result = *ptr16_1 | *ptr16_2 ;

	* ptr32 = result ;
	if(result == 0) pCode += (Int64)pCode[6];
	else pCode += 7;
      }
    break;

    case PCIT::NNB_MATTR3_IBIN32S:
      // Handles all formats ...
      {
	PTR_DEF_ASSIGN(char, ptr , 0 );
	DEF_ASSIGN(Int16, val, 2);
        NABoolean nullp = ExpTupleDesc::isNullValue( ptr, val );

	if ( nullp ) 
        {
          pCode += 4;
        }
	else 
        {
	  pCode += (Int64)pCode[3];
        }
      }
    break;
      
    case PCIT::NNB_MBIN32S_MATTR3_IBIN32S_IBIN32S:
      // Handles all formats ...
      // generated by nullBranchHelperForHash
      {
	PTR_DEF_ASSIGN(Int32, retPtr, 0 );
	PTR_DEF_ASSIGN(char, ptr , 2 );
	DEF_ASSIGN(Int16, val, 4);
	DEF_ASSIGN(Int32, retVal, 5 );
        NABoolean nullp = ExpTupleDesc::isNullValue( ptr, val );

	if ( nullp ) 
        {
	  * retPtr = retVal ;
          pCode += 7;
        }
	else 
        {
	  pCode += (Int64)pCode[6];
        }
      }
    break;
      

    case PCIT::NNB_SPECIAL_NULLS_MBIN32S_MATTR3_MATTR3_IBIN32S_IBIN32S:
      // Supports all data formats.
      {
	PTR_DEF_ASSIGN(Int32, retPtr, 0 );
	PTR_DEF_ASSIGN(char, ptr1 , 2 );
	PTR_DEF_ASSIGN(char, ptr2 , 5 );
	DEF_ASSIGN(Int16, val1, 4);
	DEF_ASSIGN(Int16, val2, 7);

        NABoolean op1Null = ExpTupleDesc::isNullValue( ptr1, val1 );
        NABoolean op2Null = ExpTupleDesc::isNullValue( ptr2, val2 );

        if ( (NOT op1Null) && (NOT op2Null) )
        {
	  * retPtr = 0;
          pCode += (Int64)pCode[9];
        }
        else
        {
          // only equi case is supported. Could be extended later.
          // pCode[8] contains the operator type (ITM_EQUAL for now).
          * retPtr = op1Null && op2Null ? 1 : 0;
          pCode += 10;
        }
      }
    break;


    case PCIT::NOT_NULL_BRANCH_MBIN16S_MBIN16S_MBIN16S_IBIN32S:
      {
	PTR_DEF_ASSIGN(Int16, ptr16_0, 0);
	PTR_DEF_ASSIGN(Int16, ptr16_2, 2);
	PTR_DEF_ASSIGN(Int16, ptr16_4, 4);

	* ptr16_0 =  * ptr16_2 | * ptr16_4 ;
	if( * ptr16_0 == 0) pCode += (Int64)pCode[6];
	else pCode += 7;
      }
    break;


    case PCIT::NULL_VIOLATION_MPTR32_MPTR32_IPTR_IPTR:
    // for aligned format's null bitmap
    // Handles 1 or 2 arguments to check if null and raise an error if so.
    //   Select b, c from TFoo where cast( c as int not null) = 30
    // where c is a nullable column this gets pushed to the EID.
    {
      PTR_DEF_ASSIGN(char, ptr_0, 0);
      PTR_DEF_ASSIGN(char, ptr_2, 2);
      Attributes *arg1 = (Attributes*)(GetPCodeBinaryAsPtr(pCode, 4));
      Attributes *arg2 = (Attributes*)(GetPCodeBinaryAsPtr(pCode, 4 + PCODEBINARIES_PER_PTR));

      NABoolean arg1Null =
	ExpTupleDesc::isNullValue( ptr_0, 
				   arg1->getNullBitIndex(),
				   arg1->getTupleFormat() );
      NABoolean arg2Null =
          ( arg2 == 0
               ? FALSE
	    : ExpTupleDesc::isNullValue( ptr_2, 
                                            arg2->getNullBitIndex(),
                                            arg2->getTupleFormat() ) );

      if( arg1Null || arg2Null )
      {
        // Raise an "assigning a null value to a NOT NULL".
        diagsArea = atp1->getDiagsArea();
        ExRaiseSqlError(getHeap(), &diagsArea, EXE_ASSIGNING_NULL_TO_NOT_NULL);
        if(diagsArea != atp1->getDiagsArea())
          atp1->setDiagsArea(diagsArea);
        return ex_expr::EXPR_ERROR;
      }

      pCode += 4 + PCODEBINARIES_PER_PTR + PCODEBINARIES_PER_PTR;
      break;
    }


    case PCIT::UPDATE_ROWLEN3_MATTR5_IBIN32S:
    {
      {
	BASE_PTR_DEF_ASSIGN(char, data, 0);
	DEF_ASSIGN(UInt32, offset, 1);
	DEF_ASSIGN(Int32, comboLen1, 4);

        char* comboPtr1 = (char*)&comboLen1;
        Int16 attrNullIndLen = (Int16)comboPtr1[0];
        Int16 attrVCIndLen   = (Int16)comboPtr1[1];

	DEF_ASSIGN(Int32, voaOffset, 2 );

        offset = ExpTupleDesc::getVarOffset( data,
                                             offset, 
                                             voaOffset,
                                             attrVCIndLen,  
                                             attrNullIndLen );

        offset += ExpTupleDesc::getVarLength( data + offset,
                                              attrVCIndLen );

        offset += attrVCIndLen;     // jump past the variable length bytes


        varOffset = offset;


        if (rowLen != NULL) {

	  DEF_ASSIGN(Int32, newLen, 5 );
          // the last varchar must adjust the overall length out if
          // in aligned format
          if ( newLen > 0 )
            {
              offset = ExpAlignedFormat::adjustDataLength(data,
                                                          offset,
                                                          newLen); 
            }

          *rowLen = offset;
        }
      }
      pCode += 6;
      break;
    }

    case PCIT::COPYVARROW_MBIN8_MBIN8_IBIN32S_IBIN32S_IBIN32S_IBIN32S:
    {
      {
	PTR_DEF_ASSIGN(char, tgtData , 0 );
	PTR_DEF_ASSIGN(char, srcData , 2 );

	DEF_ASSIGN(UInt32, voaOffset, 4);
	DEF_ASSIGN(Int32, comboLen1, 5);
        char* comboPtr1 = (char*)&comboLen1;
        Int16 attrNullIndLen = (Int16)comboPtr1[0];
        Int16 attrVCIndLen   = (Int16)comboPtr1[1];

	DEF_ASSIGN(Int16, alignment, 6);
	DEF_ASSIGN(Int16, rowLength, 7);

        UInt32 copyLength = 0;

        if (*(Int32*)srcData ==-1 )  //if aliggned format header is 0xFFFFFFFF
        {// case of null instantiated row
          DBGASSERT(*(Int16*)&srcData[voaOffset] ==-1);
          copyLength = (UInt32)rowLength;
        }
        else
        {
          copyLength = ExpTupleDesc::getVarOffset(srcData,
                                                UINT_MAX,  // offset
                                                voaOffset,         // voaEntryOffset
                                                attrVCIndLen,
                                                attrNullIndLen );

          copyLength += ExpTupleDesc::getVarLength( srcData + copyLength,
                                                  attrVCIndLen );
          copyLength += attrVCIndLen;     // jump past the variable length bytes
        }

        DBGASSERT(copyLength > 0 && copyLength <=(UInt32)rowLength);
        str_cpy_all(tgtData,srcData,copyLength);
        UInt32 newLen = copyLength;

        // the last varchar must adjust the overall length out if
        // in aligned format. Aligngemne should be ExpAlignedFormat::ALIGNMENT
        if ( alignment > 0 )
        {
          newLen = ExpAlignedFormat::adjustDataLength(tgtData, copyLength, alignment, FALSE) ;
        }

        if (rowLen != NULL)
        {
          *rowLen = newLen;
        }
      }

      pCode += 8;
      break;
    }
    case PCIT::ADD_MBIN16S_MBIN16S_MBIN16S:
    {
      PTR_DEF_ASSIGN(Int16, result, 0);
      PTR_DEF_ASSIGN(Int16, operand1, 2);
      PTR_DEF_ASSIGN(Int16, operand2, 4);
      * result = *operand1 + *operand2 ;
      pCode += 6;
      break;
    }
    case PCIT::ADD_MBIN32S_MBIN32S_MBIN32S:
    {
      PTR_DEF_ASSIGN(Int32, result, 0);
      PTR_DEF_ASSIGN(Int32, operand1, 2);
      PTR_DEF_ASSIGN(Int32, operand2, 4);
      * result = *operand1 + *operand2 ;
      pCode += 6;
      break;
    }
    case PCIT::ADD_MBIN64S_MBIN64S_MBIN64S:
    {
      PTR_DEF_ASSIGN(Int64, result, 0);
      PTR_DEF_ASSIGN(Int64, xptr, 2);
      PTR_DEF_ASSIGN(Int64, yptr, 4);
#if (defined NA_YOS || defined (NA_LINUX)) && !defined _DEBUG
      Int64 x = *xptr, y = *yptr;
      Int64 z = x + y;

      *result = z;

      // Same check C/C++ compiler uses to check for overflow
      if ((((UInt64)(~(x ^ y) & (x ^ z))) >> 63) == 0) {
      } else {
        goto Error1_;
      }
#else
      * result = EXP_FIXED_OV_ADD( *xptr, *yptr, &ov );

      if (ov)
        {// overflowed
          goto Error1_;  
        }
#endif
      pCode += 6;
      break;
    }

    case PCIT::ADD_MBIN32S_MBIN16S_MBIN16S:
    {
      PTR_DEF_ASSIGN(Int32, result, 0);
      PTR_DEF_ASSIGN(Int16, operand1, 2);
      PTR_DEF_ASSIGN(Int16, operand2, 4);
      * result = *operand1 + *operand2 ;
      pCode += 6;
      break;
    }
    case PCIT::ADD_MBIN32S_MBIN16S_MBIN32S:
    {
      PTR_DEF_ASSIGN(Int32, result, 0);
      PTR_DEF_ASSIGN(Int16, operand1, 2);
      PTR_DEF_ASSIGN(Int32, operand2, 4);
      * result = *operand1 + *operand2 ;
      pCode += 6;
      break;
    }

    case PCIT::ADD_MBIN64S_MBIN32S_MBIN64S:
    {
      PTR_DEF_ASSIGN(Int64, result, 0);
      PTR_DEF_ASSIGN(Int32, xptr32, 2);
      PTR_DEF_ASSIGN(Int64, yptr, 4);
#if (defined (NA_YOS) || defined (NA_LINUX)) && !defined _DEBUG

      Int64 x = (Int64) *xptr32 , y = *yptr;
      Int64 z = x + y;

      *result = z;

      // Same check C/C++ compiler uses to check for overflow
      if ((((UInt64)(~(x ^ y) & (x ^ z))) >> 63) == 0) {
      }
      else {
        goto Error1_;
      }
#else
      * result = EXP_FIXED_OV_ADD( *xptr32, *yptr, &ov );
       if (ov)
        {
          goto Error1_;
        }
#endif
      pCode += 6;
      break;
    }

	
    case PCIT::SUB_MBIN16S_MBIN16S_MBIN16S:
    {
      PTR_DEF_ASSIGN(Int16, result, 0);
      PTR_DEF_ASSIGN(Int16, operand1, 2);
      PTR_DEF_ASSIGN(Int16, operand2, 4);
      * result = *operand1 - *operand2 ;
      pCode += 6;
      break;
    }
    case PCIT::SUB_MBIN32S_MBIN32S_MBIN32S:
    {
      PTR_DEF_ASSIGN(Int32, result, 0);
      PTR_DEF_ASSIGN(Int32, operand1, 2);
      PTR_DEF_ASSIGN(Int32, operand2, 4);
      * result = *operand1 - *operand2 ;
      pCode += 6;
      break;
    }
    case PCIT::SUB_MBIN64S_MBIN64S_MBIN64S:
    {
      PTR_DEF_ASSIGN(Int64, result, 0);
      PTR_DEF_ASSIGN(Int64, xptr, 2);
      PTR_DEF_ASSIGN(Int64, yptr, 4);
#if (defined NA_YOS || defined (NA_LINUX)) && !defined _DEBUG
      Int64 x = *xptr, y = *yptr;
      Int64 z = x - y;

      *result = z;

      // Same check C/C++ compiler uses to check for overflow
      if ((((UInt64)((x ^ y) & (x ^ z))) >> 63) == 0) {
      }
      else {
        goto Error1_;
      }
#else
      * result = EXP_FIXED_OV_SUB( *xptr, *yptr, &ov);

      if (ov)
        {
          goto Error1_;
        }
#endif
      pCode += 6;
      break;
    }

    case PCIT::SUB_MBIN32S_MBIN16S_MBIN16S:
    {
      PTR_DEF_ASSIGN(Int32, result, 0);
      PTR_DEF_ASSIGN(Int16, operand1, 2);
      PTR_DEF_ASSIGN(Int16, operand2, 4);
      * result = *operand1 - *operand2 ;
      pCode += 6;
      break;
    }
    case PCIT::SUB_MBIN32S_MBIN16S_MBIN32S:
    {
      PTR_DEF_ASSIGN(Int32, result, 0);
      PTR_DEF_ASSIGN(Int16, operand1, 2);
      PTR_DEF_ASSIGN(Int32, operand2, 4);
      * result = *operand1 - *operand2 ;
      pCode += 6;
      break;
    }
    case PCIT::SUB_MBIN32S_MBIN32S_MBIN16S:
    {
      PTR_DEF_ASSIGN(Int32, result, 0);
      PTR_DEF_ASSIGN(Int32, operand1, 2);
      PTR_DEF_ASSIGN(Int16, operand2, 4);
      * result = *operand1 - *operand2 ;
      pCode += 6;
      break;
    }
    case PCIT::MUL_MBIN16S_MBIN16S_MBIN16S:
    {
      PTR_DEF_ASSIGN(Int16, result, 0);
      PTR_DEF_ASSIGN(Int16, operand1, 2);
      PTR_DEF_ASSIGN(Int16, operand2, 4);
      * result = *operand1 * *operand2 ;
      pCode += 6;
      break;
    }
    case PCIT::MUL_MBIN32S_MBIN32S_MBIN32S:
    {
      PTR_DEF_ASSIGN(Int32, result, 0);
      PTR_DEF_ASSIGN(Int32, operand1, 2);
      PTR_DEF_ASSIGN(Int32, operand2, 4);
      * result = *operand1 * *operand2 ;
      pCode += 6;
      break;
    } 
    case PCIT::MUL_MBIN64S_MBIN16S_MBIN32S:
    {
      PTR_DEF_ASSIGN(Int64, result, 0);
      PTR_DEF_ASSIGN(Int16, operand1, 2);
      PTR_DEF_ASSIGN(Int32, operand2, 4);
      * result = (Int64) *operand1 * (Int64) *operand2 ;

      pCode += 6;
      break;
    }
    case PCIT::MUL_MBIN64S_MBIN32S_MBIN32S:
    {
      PTR_DEF_ASSIGN(Int64, result, 0);
      PTR_DEF_ASSIGN(Int32, operand1, 2);
      PTR_DEF_ASSIGN(Int32, operand2, 4);
      * result = (Int64) *operand1 * (Int64) *operand2 ;
      pCode += 6;
      break;
    }
    case PCIT::MUL_MBIN64S_MBIN64S_MBIN64S:
    {
      PTR_DEF_ASSIGN(Int64, result, 0);
      PTR_DEF_ASSIGN(Int64, xptr, 2);
      PTR_DEF_ASSIGN(Int64, yptr, 4);
      * result = EXP_FIXED_OV_MUL( *xptr, *yptr, &ov);

      if (ov)
        {
          goto Error1_;
        }
      pCode += 6;
      break;
    }

    case PCIT::MUL_MBIN32S_MBIN16S_MBIN16S:
    {
      PTR_DEF_ASSIGN(Int32, result, 0);
      PTR_DEF_ASSIGN(Int16, operand1, 2);
      PTR_DEF_ASSIGN(Int16, operand2, 4);
      * result = *operand1 * *operand2 ;
      pCode += 6;
      break;
    }
    case PCIT::MUL_MBIN32S_MBIN16S_MBIN32S:
    {
      PTR_DEF_ASSIGN(Int32, result, 0);
      PTR_DEF_ASSIGN(Int16, operand1, 2);
      PTR_DEF_ASSIGN(Int32, operand2, 4);
      * result = *operand1 * *operand2 ;
      pCode += 6;
      break;
    }

    case PCIT::DIV_MBIN64S_MBIN64S_MBIN64S:
    {
      PTR_DEF_ASSIGN(Int64, result, 0);
      PTR_DEF_ASSIGN(Int64, xptr, 2);
      PTR_DEF_ASSIGN(Int64, yptr, 4);
#if (defined (NA_YOS) || defined (NA_LINUX)) && !defined _DEBUG

      Int64 x = *xptr, y = *yptr;

      // Same check C/C++ compiler uses to check for overflow
      if (y != 0) {
        if ((x != 0x8000000000000000LL) || (y != -1)) {
          *result = x / y;
        }
        else {
          goto Error1_;
        }
      }
      else {
        goto Error1_;
      }
#else
      if ( *yptr == 0 )
        {// div by zero
          goto Error1_; 
        }

      * result = EXP_FIXED_OV_DIV( *xptr, *yptr, &ov);

      if (ov)
        {
          goto Error1_;
        }
#endif
      pCode += 6;
      break;
    }

    case PCIT::DIV_MBIN64S_MBIN64S_MBIN64S_ROUND:
    {
      PTR_DEF_ASSIGN(Int64, result, 0);
      PTR_DEF_ASSIGN(Int64, xptr, 2);
      PTR_DEF_ASSIGN(Int64, yptr, 4);

      if ( *yptr == 0 )
	{// div by zero
	  goto Error1_; 
	}
	
	// upscale numerator by 1 
	NABoolean upscaled;
	Int64 temp;
	DEF_ASSIGN(Int32, bitmap, 6);
	Lng32 roundingMode = (Lng32)(bitmap & 0x77);
	NABoolean divToDownscale = ((bitmap & 0x100) != 0);
	if (divToDownscale)
	  {
	    temp = *yptr / 10;
	    temp = *xptr / temp;
	    upscaled = TRUE;
	  }
	else
	  {
	    temp = EXP_FIXED_OV_MUL( *xptr,
				    10, &ov);
	    if (ov)
	      {
		// couldn't upscale. Use the original value and don't do
		// any rounding.
		upscaled = FALSE;
		temp = * xptr;
	      }
	    else
	      {
		upscaled = TRUE;
	      }
	    
	    temp = EXP_FIXED_OV_DIV(temp,
				    *yptr,
				    &ov);
	    if (ov)
	      {
	        //division by zero
		goto Error1_;
	      }
	  }

	if (upscaled)
	  {
	    short nsign = 0; // indicates negative sign when set to 1.
	    
	    // get the last digit
	    Lng32 v = (Lng32) (temp % (Int64)10);
            
            if( v < 0 ) v = -v;
            if(temp < 0) nsign = 1;
            
	    // downscale the result
	    temp = temp / (Int64)10;

	    if (roundingMode == 1)
	      {
		// ROUND HALF UP MODE
		if (v >= 5)
		  {
		    // round up the result by 1
		    temp = nsign ? temp-1 : temp+1;
		  }
	      }
	    else if (roundingMode == 2)
	      {
		// ROUND HALF EVEN MODE
		if (v > 5)
		  {
		    // round up the result by 1
		    temp = nsign ? temp-1 : temp+1;
		  }
		else if (v == 5)
		  {
		    // Roundup 'w' only if all the trailing digits following
		    // 'v' is zero and 'w' is even. If 'w' is odd, irrespective
		    // of trailing digits following 'v', 'w' is rounded up.
		    // w is second last digit.
		    Lng32 w = (Lng32) (temp % (Int64)10);
		    if ((w & 0x1) != 0)
		    {
		      // odd number, round up.
		      temp = nsign ? temp-1 : temp+1;
		    }
		    else
		    {
		      // Since 'w' is an even digit, we need to determine if
		      // all the trailing digits following 'v' is zero.
		      // If any digit following 'v' is nonzero, then it is
		      // similar to v > 5.
		      NABoolean vGT5 = FALSE;
		      if(!divToDownscale)
		      {
		        //Figure out if digits following 'v' is non zero.
		        Int64 multiplier = 100;//For digit following 'v'.
		        Int64 temp1;
                       NABoolean biggerPrecision = FALSE;
		        while(!vGT5)
		        {
			  temp1 = EXP_FIXED_OV_MUL(*xptr, multiplier, &ov);
	                  if (ov)
	                  {
	                    //end of digits.
			    // When we reach here, temp1 is overflowed over 
			    // Int64.  In this rare but possible situation, 
			    // we should try checking
			    // for additional digits using BigNum datatype.
			    biggerPrecision = TRUE;
	                    break;
	                  }
	                  temp1 = EXP_FIXED_OV_DIV(temp1, *yptr, &ov);
	                  if (ov)
	                  {
	                    //Something went wrong, lets consider
	                    //it as end of digits.
		            break;
	                  }
	                  if(temp1 % (Int64)10)
	                  {
	                    vGT5 = TRUE;
	                    break;
	                  }
		          multiplier = EXP_FIXED_OV_MUL(multiplier, 10, &ov);
	                  if (ov)
	                  {
	                    //end of digits.
	                    break;
	                  }
		        }
                       if(biggerPrecision)
                       { 
                          short rc = 0;
			  Int64 dividend = *xptr;
			  Int64 divisor  = *yptr;
                          char *op_data[3];
                          char result1[100];
                          char result2[100];
                          Int64 result3 = 0;
                          Int64 ten = 10;
                          SimpleType opST(REC_BIN64_SIGNED, sizeof(Int64), 0, 0,
		                         ExpTupleDesc::SQLMX_FORMAT,
		                         8, 0, 0, 0, Attributes::NO_DEFAULT, 0);
                          
                          BigNum opBN(16, 38, 0, 0);                          
                          
                          while(!vGT5)
		           {
                            op_data[0] = result1;
                            op_data[1] = (char *) &dividend;
                            op_data[2] = (char *) &multiplier; 
                            rc = EXP_FIXED_BIGN_OV_MUL(&opST,
                                                    &opST,
			                              op_data);
                           if (rc)
	                    {
	                      //end of digits.
	                      break;
	                    }
                           
                           op_data[0] = result2;
                           op_data[1] = result1;
                           op_data[2] = (char *) &divisor;
                           rc = EXP_FIXED_BIGN_OV_DIV(&opBN,
				                    &opST,
				                    op_data);
	                    if (rc)
	                    {
	                      //Something went wrong, lets consider
	                      //it as end of digits.
		              break;
	                    }
                           
                           op_data[0] = result2;
                           op_data[1] = (char *) &ten;
                           result3 = EXP_FIXED_BIGN_OV_MOD(&opBN,
                                                      &opST,
                                                      op_data,
                                                      &ov);
                           if (ov)
	                    {
	                      //end of digits.
	                      break;
	                    }
                            
	                    if(result3)
	                    {
	                      vGT5 = TRUE;
	                      break;
	                    }
		             
                           multiplier = EXP_FIXED_OV_MUL(multiplier, 10, &ov);
	                    if (ov)
	                    {
	                      //end of digits.
	                      break;
	                    }
		           }
                       }
		      }
		      else
		      {
		        Int64 divisor = 100;//divisor=10 corresponds to v digit.
		        Int64 temp1;
		        while(!vGT5)
		        {
			  temp1 = *yptr / divisor;
		          if(!temp1) //reached end of digits.
		          {
		            break;
		          }
			  temp1 = *xptr / temp1;
		          if(temp1 % (Int64)10)
	                  {
	                    vGT5 = TRUE;
	                    break;
	                  }
	                  divisor = EXP_FIXED_OV_MUL(divisor, 10, &ov);
	                  if (ov)
	                  {
	                    //end of digits.
	                    break;
	                  }
		        }
		      }
  		    
		      if(vGT5)
		      {
		        //irrespective of w being even number,
		        //round up the value;
		        temp = nsign ? temp-1 : temp+1;  
		      }
		    }
		  }
	      }
	  }

	* result = temp;
	pCode += 7;
      }
    break;

    // Sum of two nullable BIN32S. Do the null processing in this case
    // and then fall through to the next case to handle the actual
    // addition.
    //
    case PCIT::SUM_MATTR3_MATTR3_IBIN32S_MBIN32S_MBIN32S:
    {
      PTR_DEF_ASSIGN(char, nv1, 0);
      DEF_ASSIGN(Int16, off1, 2);
      PTR_DEF_ASSIGN(char, nv2, 3);
      DEF_ASSIGN(Int16, off2, 5);
      PTR_DEF_ASSIGN(Int32, target, 7);

      if ( ExpTupleDesc::isNullValue( nv2, off2 ) )
      {
        pCode += 11;
        break;
      }

      if ( ExpTupleDesc::isNullValue( nv1, off1 ) )
       {
         // Clear the target null bytes/bit ...
	 ExpTupleDesc::clearNullValue( nv1, off1 );

         // Now set the target value to 0 so it can be used in the sum ...
	 * target = 0;
        }
      
      pCode += 7;
      //
      // Do NOT break here...
      // The nulls have been processed above, so fall through to do the adding.
      // These two cases belong together...
      //
      // Sum of two BIN32S. Assume that either the operands are not nullable
      // or the null processing has been accomplished above. Sum the second
      // operand to the first. 
      //
    }
    case PCIT::SUM_MBIN32S_MBIN32S:
    {
      PTR_DEF_ASSIGN(Int32, tgtPtr, 0 );
      PTR_DEF_ASSIGN(Int32, operPtr, 2 );
      * tgtPtr += *operPtr ;
      pCode += 4;
      break;
    }
    // Sum of two nullable BIN64S. Do the null processing in this case
    // and then fall through to the next case to handle the actual
    // addition.
    //
    case PCIT::SUM_MATTR3_MATTR3_IBIN32S_MBIN64S_MBIN64S:
    {
      PTR_DEF_ASSIGN(char, nv2, 3);
      DEF_ASSIGN(Int16, off2, 5);

      if ( ExpTupleDesc::isNullValue( nv2, off2 ) )
      {
        pCode += 11;
        break;
      }

      PTR_DEF_ASSIGN(char, nv1, 0);
      DEF_ASSIGN(Int16, off1, 2);
      PTR_DEF_ASSIGN(Int64, target, 7);

      if ( ExpTupleDesc::isNullValue( nv1, off1 ) )
       {
         // Clear the target null bytes/bit ...
         ExpTupleDesc::clearNullValue( nv1, off1 );

         // Now set the target value to 0 so it can be used in the sum ...
	 * target = 0;
        }
      
      pCode += 7;
      //
      // Do NOT break here...
      // The nulls have been processed above, so fall through to do the adding.
      // These two cases belong together...
      //
      // Sum of two BIN64S. Assume that either the operands are not nullable
      // or the null processing has been accomplished above. Sum the second
      // operand to the first. Check the result for overflow.
      //
    }
    case PCIT::SUM_MBIN64S_MBIN64S:
    {
      PTR_DEF_ASSIGN(Int64, result, 0);
      PTR_DEF_ASSIGN(Int64, yptr, 2);
      //#if defined NA_YOS && !defined _DEBUG
      Int64 y = *yptr;
      Int64 x = *result;

      Int64 z = x + y;

      // Same check C/C++ compiler uses to check for overflow
      if ((((UInt64)(~(x ^ y) & (x ^ z))) >> 63) == 0) {
        *result = z;
      } else {
        goto Error1_;
      }
      pCode += 4;
      break;
    }

    // Sum of a nullable BIN64S and BIN32S. Do the null processing in this
    // case and then fall through to the next case to handle the actual
    // addition.
    //
    case PCIT::SUM_MATTR3_MATTR3_IBIN32S_MBIN64S_MBIN32S:
    {
      PTR_DEF_ASSIGN(char, nv2, 3);
      DEF_ASSIGN(Int16, off2, 5);

      if ( ExpTupleDesc::isNullValue( nv2, off2 ) )
      {
        pCode += 11;
        break;
      }

      PTR_DEF_ASSIGN(char, nv1, 0);
      DEF_ASSIGN(Int16, off1, 2);
      PTR_DEF_ASSIGN(Int64, target, 7);

      if ( ExpTupleDesc::isNullValue( nv1, off1 ) )
       {
         // Clear the target null bytes/bit ...
	 ExpTupleDesc::clearNullValue( nv1, off1 );

         // Now set the target value to 0 so it can be used in the sum ...
	 * target = 0;
        }
      
      pCode += 7;
      //
      // Do NOT break here...
      // The nulls have been processed above, so fall through to do the adding.
      // These two cases belong together...
      //
      // Sum of a BIN64S and BIN32S. Assume that either the operands are not
      // nullable or the null processing has been accomplished above. Sum the
      // second operand to the first. Check the result for overflow.
      //
    }
    case PCIT::SUM_MBIN64S_MBIN32S:
    {
      PTR_DEF_ASSIGN(Int64, result, 0 );
      PTR_DEF_ASSIGN(Int32, yptr, 2 );
#if (defined (NA_YOS) || defined (NA_LINUX)) && !defined _DEBUG
      Int32 y = *yptr;
      Int64 x = *result;

      Int64 z = x + (Int64)y;

      // Same check C/C++ compiler uses to check for overflow
      if ((((UInt64)(~(x ^ y) & (x ^ z))) >> 63) == 0) {
        *result = z;
      } else {
        goto Error1_;
      }
#else
      Int64 op1 = * result;
      Int64 theResult = EXP_FIXED_OV_ADD( op1, (Int64) *yptr, &ov);
      if (ov)
	{
	  goto Error1_;
	}

      * result = theResult;
#endif
      pCode += 4;
      break;
    }


    // Sum of two nullable FLT64. Do the null processing in this case
    // and then fall through to the next case to handle the actual
    // addition.
    //
    case PCIT::SUM_MATTR3_MATTR3_IBIN32S_MFLT64_MFLT64:
    {
      PTR_DEF_ASSIGN(char, nv2, 3);
      DEF_ASSIGN(Int16, off2, 5);

      if ( ExpTupleDesc::isNullValue( nv2, off2 ) )
      {
        pCode += 11;
        break;
      }

      PTR_DEF_ASSIGN(char, nv1, 0);
      DEF_ASSIGN(Int16, off1, 2);

      if( ExpTupleDesc::isNullValue( nv1, off1 ) )
       {
         // Clear the target null bytes/bit ...
	 ExpTupleDesc::clearNullValue( nv1, off1 );

	 PTR_DEF_ASSIGN(Int64, target, 7);

         // Now set the target value to 0 so it can be used in the sum ...
	 flt64_1 = 0;
	 * target = (Int64) flt64_1 ;  // why not just use a simple zero ?
        }

      pCode += 7;
      //
      // Do NOT break here...
      // The nulls have been processed above, so fall through to do the adding.
      // These two cases belong together...
      //
      // Sum of two FLT64 ... assume that either the operands are not nullable
      // or the null processing has been accomplished above. Sum the second
      // operand to the first. Check the result for overflow.
      //
    }
    case PCIT::SUM_MFLT64_MFLT64:
    {
      double flt64_0;
      FLT64ASSIGN(&flt64_1, (stack[pCode[0]] + pCode[1]));
      FLT64ASSIGN(&flt64_2, (stack[pCode[2]] + pCode[3]));

      flt64_0 = flt64_1 + flt64_2;
      if ((flt64_0 < -DBL_MAX) || (flt64_0 > DBL_MAX) ||
          ((flt64_0 != 0) && (flt64_0 < DBL_MIN) &&
           (flt64_0 > -DBL_MIN)))
        {
          goto Error1_;
        }

      FLT64ASSIGN((stack[pCode[0]] + pCode[1]), &flt64_0);

      pCode += 4;
      break;
    }

    case PCIT::MINMAX_MBIN8_MBIN8_MBIN32S_IBIN32S:
      if (*((Int32*)(stack[pCode[4]]+pCode[5])) == 1) // if TRUE  
	{
	  PTR_DEF_ASSIGN(char, target, 0 );
	  PTR_DEF_ASSIGN(char, source, 2 );
	  DEF_ASSIGN(Int32, length, 6 );
	  // make the current value the new min/max value
	  str_cpy_all( target, source, length );
	}   
      pCode += 7;
      break;

      // A new PCode for hashing an 8 byte key (pCode[4] is ignored)
    case PCIT::HASH_MBIN32U_MBIN64_IBIN32S_IBIN32S:
    {
      PTR_DEF_ASSIGN(UInt32, hashValuePtr, 0 );
      PTR_DEF_ASSIGN(char, eightByteValPtr, 2 );
      * hashValuePtr = ExHDPHash::hash8( eightByteValPtr, pCode[4]);

      pCode += 6;
      break;
    }
    case PCIT::HASH_MBIN32U_MBIN32_IBIN32S_IBIN32S:
    {
      PTR_DEF_ASSIGN(UInt32, hashValuePtr, 0 );
      PTR_DEF_ASSIGN(char, fourByteValPtr, 2 );
      * hashValuePtr = ExHDPHash::hash4( fourByteValPtr, pCode[4]);

      pCode += 6;
      break;
    }
    case PCIT::HASH_MBIN32U_MBIN16_IBIN32S_IBIN32S:
    {
      PTR_DEF_ASSIGN(UInt32, hashValuePtr, 0 );
      PTR_DEF_ASSIGN(char, twoByteValPtr, 2 );
      * hashValuePtr = ExHDPHash::hash2( twoByteValPtr, pCode[4]);

      pCode += 6;
      break;
    }
    case PCIT::HASH_MBIN32U_MPTR32_IBIN32S_IBIN32S:
    {
      PTR_DEF_ASSIGN(UInt32, hashValuePtr, 0 );
      PTR_DEF_ASSIGN(char, dataPtr, 2 );
      DEF_ASSIGN(UInt32, flags, 4 );
      DEF_ASSIGN(Int32, length, 5 );
      * hashValuePtr = ExHDPHash::hash( dataPtr, flags, length );

      pCode += 6;
      break;
    }

    // varchar hash function
    case PCIT::HASH_MBIN32U_MUNIV:
    case PCIT::HASH_MBIN32U_MATTR5:
    {
      DEF_ASSIGN(UInt32, offset, 3 );
      DEF_ASSIGN(UInt32, voaOffset, 4 );
      BASE_PTR_DEF_ASSIGN(char, data, 2 );
      PTR_DEF_ASSIGN(UInt32, tgt, 0 );
      DEF_ASSIGN(UInt32, len, 5 );
      DEF_ASSIGN(Int32, comboLen, 6 );
      char* comboPtr = (char*)&comboLen;
      Int16 attrNullIndLen = (Int16)comboPtr[0];
      Int16 attrVCIndLen   = (Int16)comboPtr[1];

      if (attrVCIndLen > 0) // this check may not be needed
      {
        offset = ExpTupleDesc::getVarOffset( data,
                                             offset,
                                             voaOffset,
                                             attrVCIndLen,  
                                             attrNullIndLen );

        len = ExpTupleDesc::getVarLength( data + offset,
                                          attrVCIndLen );
        offset += attrVCIndLen;
      }

      data += offset;

      UInt32 flags = ExHDPHash::NO_FLAGS;

      if (pCodeOpc == PCIT::HASH_MBIN32U_MUNIV)
      {
        flags = ExHDPHash::SWAP_TWO;

        // skip trailing blanks
        NAWchar* wstr = (NAWchar*)data;
        len = len >> 1; // Divide len by 2 since unicode strs are dbl-bytes
        while ((len > 0) && (wstr[len-1] == unicode_char_set::space_char()))
          len--;
        len = len << 1; // Shift back to length in bytes
      }
      else {
        // skip trailing blanks
        while ((len > 0) && (data[len-1] == ' '))
          len--;
      }

      *tgt = ExHDPHash::hash(data, flags, len);

      pCode += 7;
      break;
    }

    case PCIT::FILL_MEM_BYTES:
      {
	PTR_DEF_ASSIGN(char, str, 0);
	DEF_ASSIGN(Int32, length, 2);
	DEF_ASSIGN(char, padchar, 3);
        // for all fixed length fields
	str_pad( str, length, padchar );
        pCode += 4;
        break;
      }

    case PCIT::FILL_MEM_BYTES_VARIABLE:
    {
      DEF_ASSIGN(Int32, comboLen1, 4 );
      char* comboPtr1 = (char*)&comboLen1;      
      Int16 tgtNullIndLen = (Int16)comboPtr1[0];
      Int16 tgtVCIndLen   = (Int16)comboPtr1[1];

      BASE_PTR_DEF_ASSIGN(char, tgt, 0 );
      DEF_ASSIGN(Int32, tgtOffset, 1);
      DEF_ASSIGN(Int32, tgtVoaOffset, 2);
      DEF_ASSIGN(Int32, copyLen, 5);
      DEF_ASSIGN(char, padchar, 6);

      // VOA offsets should always be used in order.
      if(tgtVoaOffset > 0) {
        assert(tgtVoaOffset > lastVoaOffset);
        lastVoaOffset = tgtVoaOffset;
      }

      tgt += ExpTupleDesc::getTgtVarOffset( tgt,
                                            tgtOffset,     // tgt offset
                                            tgtVoaOffset,  // tgt voa offset
                                            tgtVCIndLen,
                                            tgtNullIndLen,
                                            varOffset,
                                            copyLen
                                          );                        
      if (tgtVCIndLen > 0)
      {
        ExpTupleDesc::setVarLength(tgt, copyLen, tgtVCIndLen);  // set variable length value
        tgt += tgtVCIndLen;  
      }

      if (copyLen > 0)
        str_pad(tgt, copyLen, padchar );

      pCode += 7;
      break;
    }

    // EQUAL TO ("=") operations
    case PCIT::EQ_MBIN32S_MASCII_MASCII:   
      // both are fixed chars
    {
      PTR_DEF_ASSIGN(Lng32, tgt, 0);
      PTR_DEF_ASSIGN(unsigned char, src1, 2);
      PTR_DEF_ASSIGN(unsigned char, src2, 4);

      DEF_ASSIGN(Int32, length, 6);

      *tgt = (src1[0] != src2[0]) ? 0 : (memcmp(src1, src2, length) == 0);

      pCode += 7;
      break;
    }

    case PCIT::COMP_MBIN32S_MUNI_MUNI_IBIN32S_IBIN32S_IBIN32S:
    {
      Int32 i;

      PTR_DEF_ASSIGN(Lng32, res, 0 );
      PTR_DEF_ASSIGN(NAWchar, src1, 2 );
      PTR_DEF_ASSIGN(NAWchar, src2, 4 );

      DEF_ASSIGN(Int32, src1Len, 6 );
      DEF_ASSIGN(Int32, src2Len, 7 );

      NABoolean diffLens = (src1Len != src2Len);

      const Int32* table = compTable[pCode[8] - ITM_EQUAL];


      // src1 is guaranteed to be smaller or equal in length to src2, so use
      // its length with memcmp.
      Int32 compCode = wc_str_cmp(src1, src2, src1Len) + 1;

      if (diffLens && (compCode == 1)) {
        NAWchar space = unicode_char_set::space_char();
        for (i=src1Len; i < src2Len; i++) {
          if (src2[i] == space)
            continue;

          compCode = (space < src2[i]) ? 0 : 2;
          break;
        }
      }

      *res = table[compCode];

      pCode += 9;
      break;
    }

    case PCIT::COMP_MBIN32S_MASCII_MASCII_IBIN32S_IBIN32S_IBIN32S:
    {
      Int32 i, compCode;

      PTR_DEF_ASSIGN(Lng32, res, 0 );
      PTR_DEF_ASSIGN(unsigned char, src1, 2 );
      PTR_DEF_ASSIGN(unsigned char, src2, 4 );

      DEF_ASSIGN(Int32, src1Len, 6 );
      DEF_ASSIGN(Int32, src2Len, 7 );

      NABoolean diffLens = (src1Len != src2Len);

      // Set table pointer to appropriate position based on operation
      const Int32* table = &(compTable[pCode[8] - ITM_EQUAL][1]);


      // Quick first byte compare 
      if (src1[0] == src2[0]) {
        // src1 is guaranteed to be smaller or equal in length to src2, so use
        // its length with memcmp.
        compCode = memcmp(src1, src2, src1Len);

        // Fix compCode to -1, 0, or 1
        if (compCode != 0) {
          compCode = (compCode < 0) ? -1 : 1;
        }
        // If strings are equal so far and lengths are different, compare more
        else if (diffLens && (compCode == 0)) {
          for (i=src1Len; i < src2Len; i++) {
            if (src2[i] == ' ')
              continue;

            compCode = (' ' < src2[i]) ? -1 : 1;
            break;
          }
        }
      }
      else
        compCode = (src1[0] < src2[0]) ? -1 : 1;

      *res = table[compCode];

      pCode += 9;
      break;
    }

    case PCIT::COMP_MBIN32S_MUNIV_MUNIV_IBIN32S:
    case PCIT::COMP_MBIN32S_MATTR5_MATTR5_IBIN32S:
    {
      PTR_DEF_ASSIGN(Int32, res, 0 );

      // Set table pointer to appropriate position based on operation
      const Int32* table = &(compTable[pCode[12] - ITM_EQUAL][1]);


      UInt32 len1, len2;
      Int32 compCode;

      BASE_PTR_DEF_ASSIGN(char, src1Data, 2);
      BASE_PTR_DEF_ASSIGN(char, src2Data, 7);

      PTR_TO_PCODE(char, comboPtr1, 6);
      PTR_TO_PCODE(char, comboPtr2, 11);

      UInt32 src1VCIndLen = (Int32)comboPtr1[1];
      UInt32 src2VCIndLen = (Int32)comboPtr2[1];
      DEF_ASSIGN(UInt32, offset1, 3);
      DEF_ASSIGN(UInt32, offset2, 8);

      if( src1VCIndLen > 0 )  // varchar
      {
	DEF_ASSIGN(UInt32, voaOffset1, 4);
        src1Data += ExpTupleDesc::getVarOffset(src1Data,             // atp_
                                               offset1, 
                                               voaOffset1, 
                                               src1VCIndLen,         // vcIndLen
                                               (Int32)comboPtr1[0]); // nullIndLen

        len1 = ExpTupleDesc::getVarLength(src1Data, src1VCIndLen); 
        src1Data += src1VCIndLen;
      } 
      else {
	DEF_ASSIGN(UInt32, length1, 5);
        src1Data += offset1; 
        len1 = length1;
      }

      if ( src2VCIndLen > 0 )  // varchar
      {
	DEF_ASSIGN(UInt32, voaOffset2, 9);
        src2Data += ExpTupleDesc::getVarOffset(src2Data,             // atp_
                                               offset2, 
                                               voaOffset2, 
                                               src2VCIndLen,         // vcIndLen
                                               (Int32)comboPtr2[0]); // nullIndLen

        len2 = ExpTupleDesc::getVarLength(src2Data, src2VCIndLen); 
        src2Data += src2VCIndLen;
      }
      else {
	DEF_ASSIGN(UInt32, length2, 10);
        src2Data += offset2; 
        len2 = length2;
      }

      if (pCodeOpc == PCIT::COMP_MBIN32S_MUNIV_MUNIV_IBIN32S)
      {
        compCode = wcharStringCompareWithPad(
                         (NAWchar*)(src1Data), len1 >> 1,
                         (NAWchar*)(src2Data), len2 >> 1,
                         unicode_char_set::space_char());
      }
      else
      {
        compCode = charStringCompareWithPad(src1Data, len1, src2Data, len2, ' ');
      }

      *res = table[compCode];

      pCode += 13;

      break;
    }

  
    case PCIT::EQ_MBIN32S_MBIN16U_MBIN16S:
    {
      PTR_DEF_ASSIGN(Int32, result, 0 );
      PTR_DEF_ASSIGN(unsigned short, x, 2 );
      PTR_DEF_ASSIGN(short, y, 4 );

      *result = (*x == *y);

      pCode += 6;
      break;
    }
      
    case PCIT::EQ_MBIN32S_MBIN16S_MBIN16S:
    {
      PTR_DEF_ASSIGN(Int32, result, 0 );
      PTR_DEF_ASSIGN(short, x, 2 );
      PTR_DEF_ASSIGN(short, y, 4 );

      *result = (*x == *y);

      pCode += 6;
      break;
    }
      
    case PCIT::EQ_MBIN32S_MBIN16S_MBIN32S:
    {
      PTR_DEF_ASSIGN(Int32, result, 0 );
      PTR_DEF_ASSIGN(short, x, 2 );
      PTR_DEF_ASSIGN(Int32, y, 4 );

      *result = (*x == *y);

      pCode += 6;
      break;
    }
      
      
    case PCIT::EQ_MBIN32S_MBIN32S_MBIN32S:
    {
      PTR_DEF_ASSIGN(Int32, result, 0 );
      PTR_DEF_ASSIGN(Int32, x, 2 );
      PTR_DEF_ASSIGN(Int32, y, 4 );

      *result = (*x == *y);

      pCode += 6;
      break;
    }
      
    case PCIT::EQ_MBIN32S_MBIN16U_MBIN16U:
    {
      PTR_DEF_ASSIGN(Int32, result, 0 );
      PTR_DEF_ASSIGN(unsigned short, x, 2 );
      PTR_DEF_ASSIGN(unsigned short, y, 4 );

      *result = (*x == *y);

      pCode += 6;
      break;
    }
      
    case PCIT::EQ_MBIN32S_MBIN16U_MBIN32U:
    {
      PTR_DEF_ASSIGN(Int32, result, 0 );
      PTR_DEF_ASSIGN(unsigned short, x, 2 );
      PTR_DEF_ASSIGN(UInt32, y, 4 );

      *result = (*x == *y);

      pCode += 6;
      break;
    }
      
      
    case PCIT::EQ_MBIN32S_MBIN32U_MBIN32U: 
    {
      PTR_DEF_ASSIGN(Int32, result, 0 );
      PTR_DEF_ASSIGN(UInt32, x, 2 );
      PTR_DEF_ASSIGN(UInt32, y, 4 );

      *result = (*x == *y);

      pCode += 6;
      break;
    }
      
    case PCIT::EQ_MBIN32S_MBIN16S_MBIN32U:
    {
      PTR_DEF_ASSIGN(Int32, result, 0 );
      PTR_DEF_ASSIGN(short, x, 2 );
      PTR_DEF_ASSIGN(UInt32, y, 4 );

      //typecast x to Int64 to account for negetive values
      *result = ((Int64)*x == *y);

      pCode += 6;
      break;
    }
      
    case PCIT::EQ_MBIN32S_MBIN64S_MBIN64S:
    {
      PTR_DEF_ASSIGN(Int32, result, 0 );
      PTR_DEF_ASSIGN(Int64, x, 2 );
      PTR_DEF_ASSIGN(Int64, y, 4 );

      *result = (*x == *y);

      pCode += 6;
      break;
    }

    // LESS THAN ("<") operations
    case PCIT::LT_MBIN32S_MASCII_MASCII:     // both are fixed chars
    {
      PTR_DEF_ASSIGN(Lng32, tgt, 0 );
      PTR_DEF_ASSIGN(unsigned char, src1, 2 );
      PTR_DEF_ASSIGN(unsigned char, src2, 4 );

      *tgt = (src1[0] > src2[0]) ? 0 : (memcmp(src1, src2, pCode[6]) < 0);

      pCode += 7;
      break;
    }

    case PCIT::LT_MBIN32S_MBIN16U_MBIN16S:
    {
      PTR_DEF_ASSIGN(Int32, result, 0 );
      PTR_DEF_ASSIGN(unsigned short, x, 2 );
      PTR_DEF_ASSIGN(short, y, 4 );

      *result = (*x < *y);

      pCode += 6;
      break;
    }
      
    case PCIT::LT_MBIN32S_MBIN16S_MBIN16S:
    {
      PTR_DEF_ASSIGN(Int32, result, 0 );
      PTR_DEF_ASSIGN(short, x, 2 );
      PTR_DEF_ASSIGN(short, y, 4 );

      *result = (*x < *y);

      pCode += 6;
      break;
    }
      
    case PCIT::LT_MBIN32S_MBIN16S_MBIN32S:
    {
      PTR_DEF_ASSIGN(Int32, result, 0 );
      PTR_DEF_ASSIGN(short, x, 2 );
      PTR_DEF_ASSIGN(Int32, y, 4 );

      *result = (*x < *y);

      pCode += 6;
      break;
    }
      
      
    case PCIT::LT_MBIN32S_MBIN32S_MBIN32S:
    {
      PTR_DEF_ASSIGN(Int32, result, 0 );
      PTR_DEF_ASSIGN(Int32, x, 2 );
      PTR_DEF_ASSIGN(Int32, y, 4 );

      *result = (*x < *y);

      pCode += 6;
      break;
    }
      
    case PCIT::LT_MBIN32S_MBIN16U_MBIN16U:
    {
      PTR_DEF_ASSIGN(Int32, result, 0 );
      PTR_DEF_ASSIGN(unsigned short, x, 2 );
      PTR_DEF_ASSIGN(unsigned short, y, 4 );

      *result = (*x < *y);

      pCode += 6;
      break;
    }
      
    case PCIT::LT_MBIN32S_MBIN16U_MBIN32U:
    {
      PTR_DEF_ASSIGN(Int32, result, 0 );
      PTR_DEF_ASSIGN(unsigned short, x, 2 );
      PTR_DEF_ASSIGN(UInt32, y, 4 );

      *result = (*x < *y);

      pCode += 6;
      break;
    }
      
      
    case PCIT::LT_MBIN32S_MBIN32U_MBIN32U: 
    {
      PTR_DEF_ASSIGN(Int32, result, 0 );
      PTR_DEF_ASSIGN(UInt32, x, 2 );
      PTR_DEF_ASSIGN(UInt32, y, 4 );

      *result = (*x < *y);

      pCode += 6;
      break;
    }
      
    case PCIT::LT_MBIN32S_MBIN16S_MBIN32U:
    {
      PTR_DEF_ASSIGN(Int32, result, 0 );
      PTR_DEF_ASSIGN(short, x, 2 );
      PTR_DEF_ASSIGN(UInt32, y, 4 );

      //typecast x to Int64 to account for negetive values
      *result = ((Int64)*x < *y);

      pCode += 6;
      break;
    }
      
      
    case PCIT::LT_MBIN32S_MBIN64S_MBIN64S:
    {
      PTR_DEF_ASSIGN(Int32, result, 0 );
      PTR_DEF_ASSIGN(Int64, x, 2 );
      PTR_DEF_ASSIGN(Int64, y, 4 );

      *result = (*x < *y);

      pCode += 6;
      break;
    }

    // GREATER THAN (">") operations
    case PCIT::GT_MBIN32S_MASCII_MASCII:     // both are fixed chars
    {
      PTR_DEF_ASSIGN(Lng32, tgt, 0 );
      PTR_DEF_ASSIGN(unsigned char, src1, 2 );
      PTR_DEF_ASSIGN(unsigned char, src2, 4 );

      *tgt = (src1[0] < src2[0]) ? 0 : (memcmp(src1, src2, pCode[6]) > 0);

      pCode += 7;
      break;
    }

    case PCIT::GT_MBIN32S_MBIN16U_MBIN16S:
    {
      PTR_DEF_ASSIGN(Int32, result, 0 );
      PTR_DEF_ASSIGN(unsigned short, x, 2 );
      PTR_DEF_ASSIGN(short, y, 4 );

      *result = (*x > *y);

      pCode += 6;
      break;
    }
      
    case PCIT::GT_MBIN32S_MBIN16S_MBIN16S:
    {
      PTR_DEF_ASSIGN(Int32, result, 0 );
      PTR_DEF_ASSIGN(short, x, 2 );
      PTR_DEF_ASSIGN(short, y, 4 );

      *result = (*x > *y);

      pCode += 6;
      break;
    }
      
    case PCIT::GT_MBIN32S_MBIN16S_MBIN32S:
    {
      PTR_DEF_ASSIGN(Int32, result, 0 );
      PTR_DEF_ASSIGN(short, x, 2 );
      PTR_DEF_ASSIGN(Int32, y, 4 );

      *result = (*x > *y);

      pCode += 6;
      break;
    }
      
      
    case PCIT::GT_MBIN32S_MBIN32S_MBIN32S:
    {
      PTR_DEF_ASSIGN(Int32, result, 0 );
      PTR_DEF_ASSIGN(Int32, x, 2 );
      PTR_DEF_ASSIGN(Int32, y, 4 );

      *result = (*x > *y);

      pCode += 6;
      break;
    }
      
    case PCIT::GT_MBIN32S_MBIN16U_MBIN16U:
    {
      PTR_DEF_ASSIGN(Int32, result, 0 );
      PTR_DEF_ASSIGN(unsigned short, x, 2 );
      PTR_DEF_ASSIGN(unsigned short, y, 4 );

      *result = (*x > *y);

      pCode += 6;
      break;
    }
      
    case PCIT::GT_MBIN32S_MBIN16U_MBIN32U:
    {
      PTR_DEF_ASSIGN(Int32, result, 0 );
      PTR_DEF_ASSIGN(unsigned short, x, 2 );
      PTR_DEF_ASSIGN(UInt32, y, 4 );

      *result = (*x > *y);

      pCode += 6;
      break;
    }
      
      
    case PCIT::GT_MBIN32S_MBIN32U_MBIN32U: 
    {
      PTR_DEF_ASSIGN(Int32, result, 0 );
      PTR_DEF_ASSIGN(UInt32, x, 2 );
      PTR_DEF_ASSIGN(UInt32, y, 4 );

      *result = (*x > *y);

      pCode += 6;
      break;
    }
      
    case PCIT::GT_MBIN32S_MBIN16S_MBIN32U:
    {
      PTR_DEF_ASSIGN(Int32, result, 0 );
      PTR_DEF_ASSIGN(short, x, 2 );
      PTR_DEF_ASSIGN(UInt32, y, 4 );

      //typecast x to Int64 to account for negetive values
      *result = ((Int64)*x > *y);

      pCode += 6;
      break;
    }
      
      
    case PCIT::GT_MBIN32S_MBIN64S_MBIN64S:
    {
      PTR_DEF_ASSIGN(Int32, result, 0 );
      PTR_DEF_ASSIGN(Int64, x, 2 );
      PTR_DEF_ASSIGN(Int64, y, 4 );

      *result = (*x > *y);

      pCode += 6;
      break;
    }

    // LESS THAN EQUAL TO("<=") operations   
    case PCIT::LE_MBIN32S_MASCII_MASCII:     // both are fixed chars
    {
      PTR_DEF_ASSIGN(Lng32, tgt, 0 );
      PTR_DEF_ASSIGN(unsigned char, src1, 2 );
      PTR_DEF_ASSIGN(unsigned char, src2, 4 );

      *tgt = (src1[0] > src2[0]) ? 0 : (memcmp(src1, src2, pCode[6]) <= 0);

      pCode += 7;
      break;
    }

    case PCIT::LE_MBIN32S_MBIN16U_MBIN16S:
    {
      PTR_DEF_ASSIGN(Int32, result, 0 );
      PTR_DEF_ASSIGN(unsigned short, x, 2 );
      PTR_DEF_ASSIGN(short, y, 4 );

      *result = (*x <= *y);

      pCode += 6;
      break;
    }
      
    case PCIT::LE_MBIN32S_MBIN16S_MBIN16S:
    {
      PTR_DEF_ASSIGN(Int32, result, 0 );
      PTR_DEF_ASSIGN(short, x, 2 );
      PTR_DEF_ASSIGN(short, y, 4 );

      *result = (*x <= *y);

      pCode += 6;
      break;
    }
      
    case PCIT::LE_MBIN32S_MBIN16S_MBIN32S:
    {
      PTR_DEF_ASSIGN(Int32, result, 0 );
      PTR_DEF_ASSIGN(short, x, 2 );
      PTR_DEF_ASSIGN(Int32, y, 4 );

      *result = (*x <= *y);

      pCode += 6;
      break;
    }
      
      
    case PCIT::LE_MBIN32S_MBIN32S_MBIN32S:
    {
      PTR_DEF_ASSIGN(Int32, result, 0 );
      PTR_DEF_ASSIGN(Int32, x, 2 );
      PTR_DEF_ASSIGN(Int32, y, 4 );

      *result = (*x <= *y);

      pCode += 6;
      break;
    }
      
    case PCIT::LE_MBIN32S_MBIN16U_MBIN16U:
    {
      PTR_DEF_ASSIGN(Int32, result, 0 );
      PTR_DEF_ASSIGN(unsigned short, x, 2 );
      PTR_DEF_ASSIGN(unsigned short, y, 4 );

      *result = (*x <= *y);

      pCode += 6;
      break;
    }
      
    case PCIT::LE_MBIN32S_MBIN16U_MBIN32U:
    {
      PTR_DEF_ASSIGN(Int32, result, 0 );
      PTR_DEF_ASSIGN(unsigned short, x, 2 );
      PTR_DEF_ASSIGN(UInt32, y, 4 );

      *result = (*x <= *y);

      pCode += 6;
      break;
    }
      
    case PCIT::LE_MBIN32S_MBIN32U_MBIN32U: 
    {
      PTR_DEF_ASSIGN(Int32, result, 0 );
      PTR_DEF_ASSIGN(UInt32, x, 2 );
      PTR_DEF_ASSIGN(UInt32, y, 4 );

      *result = (*x <= *y);

      pCode += 6;
      break;
    }
      
    case PCIT::LE_MBIN32S_MBIN16S_MBIN32U:
    {
      PTR_DEF_ASSIGN(Int32, result, 0 );
      PTR_DEF_ASSIGN(short, x, 2 );
      PTR_DEF_ASSIGN(UInt32, y, 4 );

      //typecast x to Int64 to account for negetive values
      *result = ((Int64)*x <= *y);

      pCode += 6;
      break;
    }
      
      
    case PCIT::LE_MBIN32S_MBIN64S_MBIN64S:
    {
      PTR_DEF_ASSIGN(Int32, result, 0 );
      PTR_DEF_ASSIGN(Int64, x, 2 );
      PTR_DEF_ASSIGN(Int64, y, 4 );

      *result = (*x <= *y);

      pCode += 6;
      break;
    }

    // GREATER THAN EQUAL TO (">=") operations   
    case PCIT::GE_MBIN32S_MASCII_MASCII:      // both are fixed chars
    {
      PTR_DEF_ASSIGN(Lng32, tgt, 0 );
      PTR_DEF_ASSIGN(unsigned char, src1, 2 );
      PTR_DEF_ASSIGN(unsigned char, src2, 4 );

      *tgt = (src1[0] < src2[0]) ? 0 : (memcmp(src1, src2, pCode[6]) >= 0);

      pCode += 7;
      break;
    }

    case PCIT::GE_MBIN32S_MBIN16U_MBIN16S:
    {
      PTR_DEF_ASSIGN(Int32, result, 0 );
      PTR_DEF_ASSIGN(unsigned short, x, 2 );
      PTR_DEF_ASSIGN(short, y, 4 );

      *result = (*x >= *y);

      pCode += 6;
      break;
    }
      
    case PCIT::GE_MBIN32S_MBIN16S_MBIN16S:
    {
      PTR_DEF_ASSIGN(Int32, result, 0 );
      PTR_DEF_ASSIGN(short, x, 2 );
      PTR_DEF_ASSIGN(short, y, 4 );

      *result = (*x >= *y);

      pCode += 6;
      break;
    }
      
    case PCIT::GE_MBIN32S_MBIN16S_MBIN32S:
    {
      PTR_DEF_ASSIGN(Int32, result, 0 );
      PTR_DEF_ASSIGN(short, x, 2 );
      PTR_DEF_ASSIGN(Int32, y, 4 );

      *result = (*x >= *y);

      pCode += 6;
      break;
    }
      
      
    case PCIT::GE_MBIN32S_MBIN32S_MBIN32S:
    {
      PTR_DEF_ASSIGN(Int32, result, 0 );
      PTR_DEF_ASSIGN(Int32, x, 2 );
      PTR_DEF_ASSIGN(Int32, y, 4 );

      *result = (*x >= *y);

      pCode += 6;
      break;
    }
      
    case PCIT::GE_MBIN32S_MBIN16U_MBIN16U:
    {
      PTR_DEF_ASSIGN(Int32, result, 0 );
      PTR_DEF_ASSIGN(unsigned short, x, 2 );
      PTR_DEF_ASSIGN(unsigned short, y, 4 );

      *result = (*x >= *y);

      pCode += 6;
      break;
    }
      
    case PCIT::GE_MBIN32S_MBIN16U_MBIN32U:
    {
      PTR_DEF_ASSIGN(Int32, result, 0 );
      PTR_DEF_ASSIGN(unsigned short, x, 2 );
      PTR_DEF_ASSIGN(UInt32, y, 4 );

      *result = (*x >= *y);

      pCode += 6;
      break;
    }
      
      
    case PCIT::GE_MBIN32S_MBIN32U_MBIN32U: 
    {
      PTR_DEF_ASSIGN(Int32, result, 0 );
      PTR_DEF_ASSIGN(UInt32, x, 2 );
      PTR_DEF_ASSIGN(UInt32, y, 4 );

      *result = (*x >= *y);

      pCode += 6;
      break;
    }
      
    case PCIT::GE_MBIN32S_MBIN16S_MBIN32U:
    {
      PTR_DEF_ASSIGN(Int32, result, 0 );
      PTR_DEF_ASSIGN(short, x, 2 );
      PTR_DEF_ASSIGN(UInt32, y, 4 );

      //typecast x to Int64 to account for negetive values
      *result = ((Int64)*x >= *y);

      pCode += 6;
      break;
    }
      
      
    case PCIT::GE_MBIN32S_MBIN64S_MBIN64S:
    {
      PTR_DEF_ASSIGN(Int32, result, 0 );
      PTR_DEF_ASSIGN(Int64, x, 2 );
      PTR_DEF_ASSIGN(Int64, y, 4 );

      *result = (*x >= *y);

      pCode += 6;
      break;
    }


    // NOT EQUAL TO ("<>") operations   
    case PCIT::NE_MBIN32S_MASCII_MASCII:   // both are fixed chars
    {
      PTR_DEF_ASSIGN(Lng32, tgt, 0 );
      PTR_DEF_ASSIGN(unsigned char, src1, 2 );
      PTR_DEF_ASSIGN(unsigned char, src2, 4 );

      *tgt = (src1[0] != src2[0]) ? 1 : (memcmp(src1, src2, pCode[6]) != 0);

      pCode += 7;
      break;
    }

    case PCIT::NE_MBIN32S_MBIN64S_MBIN64S:
    {
      PTR_DEF_ASSIGN(Int32, result, 0 );
      PTR_DEF_ASSIGN(Int64, x, 2 );
      PTR_DEF_ASSIGN(Int64, y, 4 );

      *result = (*x != *y);

      pCode += 6;
      break;
    }

    case PCIT::NE_MBIN32S_MBIN16S_MBIN16S:
    {
      PTR_DEF_ASSIGN(Int32, result, 0 );
      PTR_DEF_ASSIGN(short, x, 2 );
      PTR_DEF_ASSIGN(short, y, 4 );

      *result = (*x != *y);

      pCode += 6;
      break;
    }

    // EQUAL TO ZERO operations   
    case PCIT::ZERO_MBIN32S_MBIN32U:
    {
      PTR_DEF_ASSIGN(Int32, result, 0 );
      PTR_DEF_ASSIGN(UInt32, x, 2 );

      *result = (*x == 0);
      break;
    }

    // NOT EQUAL TO ZERO operations   
    case PCIT::NOTZERO_MBIN32S_MBIN32U:
    {
      PTR_DEF_ASSIGN(Int32, result, 0 );
      PTR_DEF_ASSIGN(UInt32, x, 2 );

      *result = (*x != 0);
      break;
    }


    case PCIT::AND_MBIN32S_MBIN32S_MBIN32S:
      {
	PTR_DEF_ASSIGN(Int32, resultPtr, 0 );
	PTR_DEF_ASSIGN(Int32, opAPtr, 2 );
	PTR_DEF_ASSIGN(Int32, opBPtr, 4 );

	* resultPtr =  *opAPtr & *opBPtr  ?  *opAPtr | *opBPtr : 0 ; 

	pCode += 6;
      }
      break;

    case PCIT::OR_MBIN32S_MBIN32S_MBIN32S:
      {
	PTR_DEF_ASSIGN(Int32, resultPtr, 0 );
	PTR_DEF_ASSIGN(Int32, opAPtr, 2 );
	PTR_DEF_ASSIGN(Int32, opBPtr, 4 );

	* resultPtr =  *opAPtr == 1 || *opBPtr == 1 ? 1 : *opAPtr | *opBPtr ; 

	pCode += 6;
      }
      break;

    case PCIT::MOD_MBIN32S_MBIN32S_MBIN32S:
    {
      PTR_DEF_ASSIGN(Int32, resultPtr, 0 );
      PTR_DEF_ASSIGN(Int32, opAPtr, 2 );
      PTR_DEF_ASSIGN(Int32, opBPtr, 4 );

      * resultPtr = *opAPtr % *opBPtr ;

      pCode += 6;
      break;
    }
    case PCIT::MOD_MBIN32U_MBIN32U_MBIN32S:
    {
      PTR_DEF_ASSIGN(UInt32, resultPtr, 0 );
      PTR_DEF_ASSIGN(UInt32, opAPtr, 2 );
      PTR_DEF_ASSIGN(Int32, opBPtr, 4 );

      * resultPtr = *opAPtr % *opBPtr ;

      pCode += 6;
      break;
    }
    case PCIT::HASHCOMB_MBIN32U_MBIN32U_MBIN32U:
    {
      PTR_DEF_ASSIGN(UInt32, tgtPtr, 0 );
      PTR_DEF_ASSIGN(UInt32, src1Ptr, 2 );
      PTR_DEF_ASSIGN(UInt32, src2Ptr, 4 );

      *tgtPtr = ( *src1Ptr << 1 | *src1Ptr >> 31 ) ^ *src2Ptr;

      pCode += 6;
      break;
    }

    case PCIT::ENCODE_MASCII_MBIN16S_IBIN32S:
      {
	PTR_DEF_ASSIGN(Int16, outputPtr, 0 );
	PTR_DEF_ASSIGN(Int16, resultPtr, 2 );
	DEF_ASSIGN(Int32, bitwiseNOT , 4 );
	Int16 result = *resultPtr;

	result ^= 0x8000;
#ifdef NA_LITTLE_ENDIAN
	result = reversebytes((UInt16)result);
#endif // NA_LITTLE_ENDIAN      

	if ( bitwiseNOT ) result = ~result;

	* outputPtr = result ;

	pCode += 5;
      }
      break;

    case PCIT::ENCODE_MASCII_MBIN16U_IBIN32S:
      {
	PTR_DEF_ASSIGN(Int16, outputPtr, 0 );
	PTR_DEF_ASSIGN(Int16, resultPtr, 2 );
	DEF_ASSIGN(Int32, bitwiseNOT , 4 );
	Int16 result = *resultPtr;

#ifdef NA_LITTLE_ENDIAN
	result = reversebytes((UInt16)result);
#endif // NA_LITTLE_ENDIAN      

	if ( bitwiseNOT ) result = ~result;

	* outputPtr = result ;

	pCode += 5;
      }
      break;

    case PCIT::ENCODE_MASCII_MBIN32S_IBIN32S:
      {
	PTR_DEF_ASSIGN(Int32, outputPtr, 0 );
	PTR_DEF_ASSIGN(Int32, resultPtr, 2 );
	DEF_ASSIGN(Int32, bitwiseNOT , 4 );
	Int32 result = *resultPtr;

	result ^= 0x80000000;

#ifdef NA_LITTLE_ENDIAN
	result = reversebytes((UInt32)result);
#endif // NA_LITTLE_ENDIAN      
	if ( bitwiseNOT ) result = ~result;

	* outputPtr = result ;

	pCode += 5;
      }
    break;

    case PCIT::ENCODE_MASCII_MBIN32U_IBIN32S:
      {
	PTR_DEF_ASSIGN(Int32, outputPtr, 0 );
	PTR_DEF_ASSIGN(Int32, resultPtr, 2 );
	DEF_ASSIGN(Int32, bitwiseNOT , 4 );
	Int32 result = *resultPtr;

#ifdef NA_LITTLE_ENDIAN
	result = reversebytes((UInt32)result);
#endif // NA_LITTLE_ENDIAN      
	if ( bitwiseNOT ) result = ~result;

	* outputPtr = result ;

	pCode += 5;
      }
    break;

    case PCIT::ENCODE_MASCII_MBIN64S_IBIN32S:
      {
	PTR_DEF_ASSIGN(Int64, outputPtr, 0 );
	PTR_DEF_ASSIGN(Int64, resultPtr, 2 );
	DEF_ASSIGN(Int32, bitwiseNOT , 4 );
	Int64 result = *resultPtr;

//SQ_LINUX #ifndef NA_HSC
	result ^= 0x8000000000000000LL;
#ifdef NA_LITTLE_ENDIAN
	result = reversebytes(result);
#endif // NA_LITTLE_ENDIAN      
	if ( bitwiseNOT ) result = ~result;

	* outputPtr = result ;

	pCode += 5;
      }
      break;

    case PCIT::ENCODE_NXX:
       {
	 PTR_DEF_ASSIGN(char, tgt, 0 );
	 PTR_DEF_ASSIGN(char, src, 2 );
	 DEF_ASSIGN(Int32, length, 4 );
	 DEF_ASSIGN(Int32, desc, 5 );
	 if ( desc ) 
	  {
	    for (Int32 k = 0; k < length; k++)
	      tgt[k] = (char)(~(src[k]));
	  }
	else
	  {
	    str_cpy_all( tgt, src, length );
	  }
	pCode += 6;
      }
    break;

    case PCIT::ENCODE_DECS:
      {
	PTR_DEF_ASSIGN(char, tgt, 0 );
	PTR_DEF_ASSIGN(char, src, 2 );
	DEF_ASSIGN(Int32, length, 4 );
	DEF_ASSIGN(Int32, desc, 5 );
	if (src[0] & 0200) // negative
	  {
	    if ( desc )
	      {
		str_cpy_all(tgt, src, length );
	      }
	    else
	      {
		for (Int32 k = 0; k < length; k++)
		  tgt[k] = (char)(~(src[k]));
	      }
	  }
	else // positive
	  {
	    if ( desc ) 
	      {
		str_cpy_all(tgt, src, length );
		tgt[0] = (char)(~(src[0] | 0200));

		for (Int32 k = 1; k < length; k++)
		  tgt[k] = (char)(~(tgt[k]));
	      }
	    else
	      {
		str_cpy_all(tgt, src, length );

		tgt[0] |= 0200;
	      }
	  }
	
	pCode += 6;
      }
    break;

    case PCIT::DECODE_MASCII_MBIN16S_IBIN32S:
      {
	PTR_DEF_ASSIGN(Int16, outputPtr, 0 );
	PTR_DEF_ASSIGN(Int16, resultPtr, 2 );
	DEF_ASSIGN(Int32, bitwiseNOT , 4 );
	Int16 result = *resultPtr;

	if ( bitwiseNOT ) result = ~result;

#ifdef NA_LITTLE_ENDIAN
	result = reversebytes((UInt16)result);
#endif // NA_LITTLE_ENDIAN      

	result ^= 0x8000;

	* outputPtr = result ;

	pCode += 5;
      }
      break;

    case PCIT::DECODE_MASCII_MBIN16U_IBIN32S:
      {
	PTR_DEF_ASSIGN(Int16, outputPtr, 0 );
	PTR_DEF_ASSIGN(Int16, resultPtr, 2 );
	DEF_ASSIGN(Int32, bitwiseNOT , 4 );
	Int16 result = *resultPtr;

	if ( bitwiseNOT ) result = ~result;

#ifdef NA_LITTLE_ENDIAN
	result = reversebytes((UInt16)result);
#endif // NA_LITTLE_ENDIAN      

	* outputPtr = result ;

	pCode += 5;
      }
      break;

    case PCIT::DECODE_MASCII_MBIN32S_IBIN32S:
      {
	PTR_DEF_ASSIGN(Int32, outputPtr, 0 );
	PTR_DEF_ASSIGN(Int32, resultPtr, 2 );
	DEF_ASSIGN(Int32, bitwiseNOT , 4 );
	Int32 result = *resultPtr;

	if ( bitwiseNOT ) result = ~result;

#ifdef NA_LITTLE_ENDIAN
	result = reversebytes((UInt32)result);
#endif // NA_LITTLE_ENDIAN      

	result ^= 0x80000000;

	* outputPtr = result ;

	pCode += 5;
      }
    break;

    case PCIT::DECODE_MASCII_MBIN32U_IBIN32S:
      {
	PTR_DEF_ASSIGN(Int32, outputPtr, 0 );
	PTR_DEF_ASSIGN(Int32, resultPtr, 2 );
	DEF_ASSIGN(Int32, bitwiseNOT , 4 );
	Int32 result = *resultPtr;

	if ( bitwiseNOT ) result = ~result;

#ifdef NA_LITTLE_ENDIAN
	result = reversebytes((UInt32)result);
#endif // NA_LITTLE_ENDIAN      

	* outputPtr = result ;

	pCode += 5;
      }
    break;

    case PCIT::DECODE_MASCII_MBIN64S_IBIN32S:
      {
	PTR_DEF_ASSIGN(Int64, outputPtr, 0 );
	PTR_DEF_ASSIGN(Int64, resultPtr, 2 );
	DEF_ASSIGN(Int32, bitwiseNOT , 4 );
	Int64 result = *resultPtr;

	if ( bitwiseNOT ) result = ~result;

#ifdef NA_LITTLE_ENDIAN
	result = reversebytes(result);
#endif // NA_LITTLE_ENDIAN      

//SQ_LINUX #ifndef NA_HSC
	result ^= 0x8000000000000000LL;
	* outputPtr = result ;

	pCode += 5;
      }
      break;

    case PCIT::DECODE_NXX:
       {
	 PTR_DEF_ASSIGN(char, tgt, 0 );
	 PTR_DEF_ASSIGN(char, src, 2 );
	 DEF_ASSIGN(Int32, length, 4 );
	 DEF_ASSIGN(Int32, desc, 5 );
	 if ( desc ) 
	  {
	    for (Int32 k = 0; k < length; k++)
	      tgt[k] = (char)(~(src[k]));
	  }
	else
	  {
	    str_cpy_all( tgt, src, length );
	  }
	pCode += 6;
      }
    break;

    case PCIT::DECODE_DECS:
      {
	PTR_DEF_ASSIGN(char, tgt, 0 );
	PTR_DEF_ASSIGN(char, src, 2 );
	DEF_ASSIGN(Int32, length, 4 );
	DEF_ASSIGN(Int32, desc, 5 );

	if (desc)
	  {
	    for (Int32 k = 0; k < length; k++)
	      tgt[k] = (char)(~(src[k]));
	  }

	if (NOT(src[0] & 0200)) 
	  {
	    for (Lng32 i = 0; i < length; i++)
	      tgt[i] = ~src[i];
	  } 
	else 
	  {
	    if (tgt != src)
	      str_cpy_all(tgt, src, length);
	    tgt[0] &= ~0200;
	  }

	pCode += 6;
      }
    break;

    case PCIT::BRANCH_INDIRECT_MBIN32S:
    {
      PTR_DEF_ASSIGN(Int32, srcPtr, 0 );
      pCode += (Int64)*srcPtr;
      break;
    }
    
    case PCIT::BRANCH:
    {
      DEF_ASSIGN(Int64, branchOffset, 0 );
      pCode += branchOffset ;
      break;
    }
    case PCIT::BRANCH_AND:
      {
        // on 64-bit the first 2 operands are pointers
	PTR_DEF_ASSIGN(Int32, tgtPtr, 2 * PCODEBINARIES_PER_PTR );
	PTR_DEF_ASSIGN(Int32, srcPtr, 2 + 2 * PCODEBINARIES_PER_PTR );
	Int32 src = *srcPtr;

        if (src == 0)
          {
	    DEF_ASSIGN_PTR(Int64, branchOffset, 0 );
	    *tgtPtr = 0;
	    pCode += branchOffset;
          }
        else
          {
	    * tgtPtr = src ;
            pCode += 4 + PCODEBINARIES_PER_PTR + PCODEBINARIES_PER_PTR;
          }
      }
    break;

    case PCIT::BRANCH_AND_CNT:
      {
	PTR_DEF_ASSIGN(Int32, tgtPtr, 2 );
	PTR_DEF_ASSIGN(Int32, srcPtr, 4 );
	Int32 src = *srcPtr;

        // Increment seen counter
        pCode[6]++;

        // Enable runtime opts if seen count equals trigger count
        enableRuntimeOpts = enableRuntimeOpts | (pCode[6] == pCode[1]);

        if (src == 0)
          {
	    DEF_ASSIGN(Int64, branchOffset, 0 );
            pCode[7]++;  // Increment taken count
	    * tgtPtr = 0;
	    pCode += branchOffset;
          }
        else
          {
	    * tgtPtr = src;
            pCode += 8;
          }
      }
    break;

    case PCIT::BRANCH_OR:
      {
        // on 64-bit the first 2 operands are pointers
	PTR_DEF_ASSIGN(Int32, tgtPtr, 2 * PCODEBINARIES_PER_PTR );
	PTR_DEF_ASSIGN(Int32, srcPtr, 2 + 2 * PCODEBINARIES_PER_PTR );
	Int32 src = *srcPtr;

        if (src == 1)
          {
	    DEF_ASSIGN_PTR(Int64, branchOffset, 0 );
	    * tgtPtr = 1;
	    pCode += branchOffset;
          }
        else
          {
	    * tgtPtr = src ;
            pCode += 4 + 2 * PCODEBINARIES_PER_PTR;
          }
      }
    break;

    case PCIT::BRANCH_OR_CNT:
      {
	PTR_DEF_ASSIGN(Int32, tgtPtr, 2 );
	PTR_DEF_ASSIGN(Int32, srcPtr, 4 );
	Int32 src = *srcPtr;

        // Increment seen counter
        pCode[6]++;

        // Enable runtime opts if seen count equals trigger count
        enableRuntimeOpts = enableRuntimeOpts | (pCode[6] == pCode[1]);

        if (src == 1)
          {
	    DEF_ASSIGN(Int64, branchOffset, 0 );
            pCode[7]++;  // Increment taken count
	    * tgtPtr = 1;
	    pCode += branchOffset;
          }
        else
          {
	    * tgtPtr = src;
            pCode += 8;
          }
      }
    break;

    case PCIT::RANGE_LOW_S64S64:
    {
      DEF_ASSIGN(Lng32, op, RANGE_INST_LEN );  // the next op
      PTR_DEF_ASSIGN(Int64, valPtr, 0 );
      PTR_TO_PCODE(Int64, minvalPtr, 2 );

      if ( *valPtr < *minvalPtr )
	{
	  goto Error1_; 
	}

      pCode += RANGE_INST_LEN;

      if (op != PCIT::RANGE_HIGH_S64S64) {
        break;
      }

      pCode++;
      //
      // Do NOT break here...
      // The next instruction is a matching RANGE_HIGH
    }

    case PCIT::RANGE_HIGH_S64S64:
    {
      PTR_DEF_ASSIGN(Int64, valPtr, 0 );
      PTR_TO_PCODE(Int64, maxvalPtr, 2 );
      if ( *valPtr > *maxvalPtr )
        {
	  goto Error1_;
        }
      pCode += RANGE_INST_LEN;
      break;
    }
    case PCIT::RANGE_LOW_S32S64:
    {
      DEF_ASSIGN(Lng32, op, RANGE_INST_LEN );  // the next op
      PTR_DEF_ASSIGN(Int32, valPtr, 0 );
      PTR_TO_PCODE(Int64, minvalPtr, 2 );

      if ( *valPtr < *minvalPtr )
	{
	  goto Error1_; 
	}

      pCode += RANGE_INST_LEN; 

      if (op != PCIT::RANGE_HIGH_S32S64) {
        break;
      }

      pCode++;
      //
      // Do NOT break here...
      // The next instruction is a matching RANGE_HIGH
    }

    case PCIT::RANGE_HIGH_S32S64:
    {
      PTR_DEF_ASSIGN(Int32, valPtr, 0 );
      PTR_TO_PCODE(Int64, maxvalPtr, 2 );
      if ( *valPtr > *maxvalPtr )
        {
	  goto Error1_;
        }
      pCode += RANGE_INST_LEN;
      break;
    }
    case PCIT::RANGE_LOW_U32S64:
    {
      DEF_ASSIGN(Lng32, op, RANGE_INST_LEN );  // the next op
      PTR_DEF_ASSIGN(UInt32, valPtr, 0 );
      PTR_TO_PCODE(Int64, minvalPtr, 2 );

      if ( *valPtr < *minvalPtr )
        {
	  goto Error1_;
        }

      pCode += RANGE_INST_LEN;

      if (op != PCIT::RANGE_HIGH_U32S64) {
        break;
      }

      pCode++;
      //
      // Do NOT break here...
      // The next instruction is a matching RANGE_HIGH
    }

    case PCIT::RANGE_HIGH_U32S64:
    {
      PTR_DEF_ASSIGN(UInt32, valPtr, 0 );
      PTR_TO_PCODE(Int64, maxvalPtr, 2 );

      if ( *valPtr > *maxvalPtr )
        {
	  goto Error1_;
        }
      pCode += RANGE_INST_LEN;
      break;
    }
    case PCIT::RANGE_LOW_S16S64:
    {
      DEF_ASSIGN(Lng32, op, RANGE_INST_LEN );  // the next op
      PTR_DEF_ASSIGN(short, valPtr, 0 );
      PTR_TO_PCODE(Int64, minvalPtr, 2 );

      if ( *valPtr < *minvalPtr )
	{
	  goto Error1_;
	}

      pCode += RANGE_INST_LEN;

      if (op != PCIT::RANGE_HIGH_S16S64) {
        break;
      }

      pCode++;
      //
      // Do NOT break here...
      // The next instruction is a matching RANGE_HIGH
    }

    case PCIT::RANGE_HIGH_S16S64:
    {
      PTR_DEF_ASSIGN(short, valPtr, 0 );
      PTR_TO_PCODE(Int64, maxvalPtr, 2 );
      if ( *valPtr > *maxvalPtr )
        {
          goto Error1_;
        }
      pCode += RANGE_INST_LEN;
      break;
    }  

    case PCIT::RANGE_LOW_U16S64:
    {
      DEF_ASSIGN(Lng32, op, RANGE_INST_LEN );  // the next op
      PTR_DEF_ASSIGN(unsigned short, valPtr, 0 );
      PTR_TO_PCODE(Int64, minvalPtr, 2 );

      if ( *valPtr < *minvalPtr )
        {
	  goto Error1_;
        }

      pCode += RANGE_INST_LEN;

      if (op != PCIT::RANGE_HIGH_U16S64) {
        break;
      }

      pCode++;
      //
      // Do NOT break here...
      // The next instruction is a matching RANGE_HIGH
    }

    case PCIT::RANGE_HIGH_U16S64:
    {
      PTR_DEF_ASSIGN(unsigned short, valPtr, 0 );
      PTR_TO_PCODE(Int64, maxvalPtr, 2 );

      if ( *valPtr > *maxvalPtr )
        {
	  goto Error1_;
        }
      pCode += RANGE_INST_LEN;
      break;
    }
    case PCIT::REPLACE_NULL_MATTR3_MBIN32S:
    case PCIT::REPLACE_NULL_MATTR3_MBIN32U:
    case PCIT::REPLACE_NULL_MATTR3_MBIN16S: 
    case PCIT::REPLACE_NULL_MATTR3_MBIN16U:
    {
      PTR_DEF_ASSIGN(char, target, 0 );
      PTR_DEF_ASSIGN(char, bitmap, 2 );
      DEF_ASSIGN(UInt16, idx, 4 );
      char *source;
      DEF_ASSIGN(Int32, length , 9 );

      if ( ExpTupleDesc::isNullValue( bitmap, idx ) )
      {
	PTR_DEF_ASSIGN(char, nlres, 7 );
	source = nlres;
      }
      else
      {
	PTR_DEF_ASSIGN(char, notnlres, 5 );
	source = notnlres;
      }
        
      str_cpy_all(target, source, length);
      pCode += 10;
     }
     break;

    case PCIT::ADD_MFLT64_MFLT64_MFLT64:
    {
      double flt64_0;
      PTR_DEF_ASSIGN(double, result, 0 );
      PTR_DEF_ASSIGN(double, op1, 2 );
      PTR_DEF_ASSIGN(double, op2, 4 );
      flt64_0 = MathReal64Add( *op1, *op2, &ov );
      if (ov)
      {
        goto Error1_; // overflow
      }

      * result = flt64_0;

      pCode += 6;
      break;
    }

    case PCIT::SUB_MFLT64_MFLT64_MFLT64:
    {
      double flt64_0;
      PTR_DEF_ASSIGN(double, result, 0 );
      PTR_DEF_ASSIGN(double, op1, 2 );
      PTR_DEF_ASSIGN(double, op2, 4 );
      flt64_0 = MathReal64Sub( *op1, *op2, &ov );
      if (ov) {
        goto Error1_;
      }

      * result = flt64_0;

      pCode += 6;
      break;
    }

    case PCIT::MUL_MFLT64_MFLT64_MFLT64:
    {
      double flt64_0;
      PTR_DEF_ASSIGN(double, result, 0 );
      PTR_DEF_ASSIGN(double, op1, 2 );
      PTR_DEF_ASSIGN(double, op2, 4 );
      flt64_0 = MathReal64Mul( *op1, *op2, &ov );
      if (ov) {
        goto Error1_;
      }

      * result = flt64_0;

      pCode += 6;
      break;
    }

    case PCIT::DIV_MFLT64_MFLT64_MFLT64:
    {
      double flt64_0;
      PTR_DEF_ASSIGN(double, result, 0 );
      PTR_DEF_ASSIGN(double, op1, 2 );
      PTR_DEF_ASSIGN(double, op2, 4 );
      flt64_0 = MathReal64Div( *op1, *op2, &ov );
      if (ov) {
        goto Error1_;
      }

      * result = flt64_0;

      pCode += 6;
      break;
    }
    
    case PCIT::RANGE_MFLT64:
    {
      double flt64_1;

      flt64_1 = *((double*)(stack[pCode[0]] + pCode[1]));
      // If floating point value is NAN, then return overflow result
      if (flt64_1 != flt64_1)
        {
          goto Error1_;
      }
      pCode += 2;
      break;
    }

    case PCIT::PROFILE:
      getPCodeObject()->profileCounts()[pCode[0]]++;
      pCode++;
      break;

    case PCIT::NE_MBIN32S_MFLT32_MFLT32:
    {
      // NOT EQUAL TO ("<>") operation  
      PTR_DEF_ASSIGN(float, fltPtr1, 2 );
      PTR_DEF_ASSIGN(float, fltPtr2, 4 );
      PTR_DEF_ASSIGN(Int32, result, 0 );

      * result = *fltPtr1 != *fltPtr2 ;

      pCode += 6;
      break;
    }
    case PCIT::NE_MBIN32S_MFLT64_MFLT64:
    {
      // NOT EQUAL TO ("<>") operation  
      PTR_DEF_ASSIGN(double, dblPtr1, 2 );
      PTR_DEF_ASSIGN(double, dblPtr2, 4 );
      PTR_DEF_ASSIGN(Int32, result, 0 );

      * result = *dblPtr1 != *dblPtr2 ;

      pCode += 6;
      break;
    }

    case PCIT::GT_MBIN32S_MFLT32_MFLT32:
    {
      // GREATER THAN (">") operation  
      PTR_DEF_ASSIGN(float, fltPtr1, 2 );
      PTR_DEF_ASSIGN(float, fltPtr2, 4 );
      PTR_DEF_ASSIGN(Int32, result, 0 );

      * result = *fltPtr1 > *fltPtr2 ;

      pCode += 6;
      break;
    }
    case PCIT::GT_MBIN32S_MFLT64_MFLT64:
    {
      // GREATER THAN (">") operation  
      PTR_DEF_ASSIGN(double, dblPtr1, 2 );
      PTR_DEF_ASSIGN(double, dblPtr2, 4 );
      PTR_DEF_ASSIGN(Int32, result, 0 );

      * result = *dblPtr1 > *dblPtr2 ;

      pCode += 6;
      break;
    }

    case PCIT::GE_MBIN32S_MFLT32_MFLT32:
    {
      // GREATER THAN OR EQUAL TO (">=") operation  
      PTR_DEF_ASSIGN(float, fltPtr1, 2 );
      PTR_DEF_ASSIGN(float, fltPtr2, 4 );
      PTR_DEF_ASSIGN(Int32, result, 0 );

      * result = *fltPtr1 >= *fltPtr2 ;

      pCode += 6;
      break;
    }
    case PCIT::GE_MBIN32S_MFLT64_MFLT64:
    {
      // GREATER THAN OR EQUAL TO (">=") operation  
      PTR_DEF_ASSIGN(double, dblPtr1, 2 );
      PTR_DEF_ASSIGN(double, dblPtr2, 4 );
      PTR_DEF_ASSIGN(Int32, result, 0 );

      * result = *dblPtr1 >= *dblPtr2 ;

      pCode += 6;
      break;
    }

    case PCIT::EQ_MBIN32S_MFLT32_MFLT32:
    {
      // EQUAL TO ("=") operation  
      PTR_DEF_ASSIGN(float, fltPtr1, 2 );
      PTR_DEF_ASSIGN(float, fltPtr2, 4 );
      PTR_DEF_ASSIGN(Int32, result, 0 );

      * result = *fltPtr1 == *fltPtr2 ;

      pCode += 6;
      break;
    }
    case PCIT::EQ_MBIN32S_MFLT64_MFLT64:
    {
      // EQUAL TO ("=") operation  
      PTR_DEF_ASSIGN(double, dblPtr1, 2 );
      PTR_DEF_ASSIGN(double, dblPtr2, 4 );
      PTR_DEF_ASSIGN(Int32, result, 0 );

      * result = *dblPtr1 == *dblPtr2 ;

      pCode += 6;
      break;
    }

    case PCIT::LE_MBIN32S_MFLT32_MFLT32:
    {
      // LESS THAN OR EQUAL TO ("<=") operation  
      PTR_DEF_ASSIGN(float, fltPtr1, 2 );
      PTR_DEF_ASSIGN(float, fltPtr2, 4 );
      PTR_DEF_ASSIGN(Int32, result, 0 );

      * result = *fltPtr1 <= *fltPtr2 ;

      pCode += 6;
      break;
    }
    case PCIT::LE_MBIN32S_MFLT64_MFLT64:
    {
      // LESS THAN OR EQUAL TO ("<=") operation  
      PTR_DEF_ASSIGN(double, dblPtr1, 2 );
      PTR_DEF_ASSIGN(double, dblPtr2, 4 );
      PTR_DEF_ASSIGN(Int32, result, 0 );

      * result = *dblPtr1 <= *dblPtr2 ;

      pCode += 6;
      break;
    }

    case PCIT::LT_MBIN32S_MFLT32_MFLT32:
    {
      // LESS THAN ("<") operation  
      PTR_DEF_ASSIGN(float, fltPtr1, 2 );
      PTR_DEF_ASSIGN(float, fltPtr2, 4 );
      PTR_DEF_ASSIGN(Int32, result, 0 );

      * result = *fltPtr1 < *fltPtr2 ;

      pCode += 6;
      break;
    }
    case PCIT::LT_MBIN32S_MFLT64_MFLT64:
    {
      // LESS THAN ("<") operation  
      PTR_DEF_ASSIGN(double, dblPtr1, 2 );
      PTR_DEF_ASSIGN(double, dblPtr2, 4 );
      PTR_DEF_ASSIGN(Int32, result, 0 );

      * result = *dblPtr1 < *dblPtr2 ;

      pCode += 6;
      break;
    }

    case PCIT::NULLIFZERO_MPTR32_MATTR3_MPTR32_IBIN32S:
    // copies in value from src to target, then sets / clears null if need be
    {
      PTR_DEF_ASSIGN(char, tgt, 0 );
      PTR_DEF_ASSIGN(char, tgtNull, 2 );
      PTR_DEF_ASSIGN(char, src, 5 );
      DEF_ASSIGN(Int16, indx, 4 );
      DEF_ASSIGN(Int32, srcLen, 7 );

      NABoolean resultIsNull = TRUE;
      for (Int32 i=0; i < srcLen; i++)
      {
        tgt[i] = src[i];
        if (src[i] != 0) {
          resultIsNull = FALSE;
        }
      }

      if (resultIsNull)
	ExpTupleDesc::setNullValue(tgtNull, indx);
      else
	ExpTupleDesc::clearNullValue(tgtNull, indx);

      pCode += 8;

      break;
    }

    case PCIT::GENFUNC_PCODE_1:
      {
	switch (pCode[0])
	  {
          // Obsolete
	  case ITM_NULLIFZERO:
	    {
	      PTR_DEF_ASSIGN(char, tgt, 1 );
	      PTR_DEF_ASSIGN(char, tgtNull, 3 );
	      PTR_DEF_ASSIGN(char, src, 6 );
	      DEF_ASSIGN(Int32, tgtNullIndicatorLen, 5 );
	      DEF_ASSIGN(Int32, srcLen, 8 );
	      NABoolean resultIsNull = TRUE;
	      for (Int32 i = 0; i < srcLen; i++)
		{
		  tgt[i] = src[i];
		  if (src[i] != 0)
		    {
		      resultIsNull = FALSE;
		    }
		}

	      if (resultIsNull)
                str_pad(tgtNull, tgtNullIndicatorLen, '\377');
              else
                str_pad(tgtNull, tgtNullIndicatorLen, 0);

	      pCode += 9;
	    }
	  break;

	  case ITM_RANDOMNUM:
	    {
	      DEF_ASSIGN(Int32, seed, 8 );
	      PTR_DEF_ASSIGN(UInt32, resultPtr, 1 );
	      seed++;
	      if (seed < 0)  // numeric overflow ?
		seed = seed + INT_MAX;
	      if (seed < 1) seed = 1; // in case seed == -1 or zero
	      * resultPtr = seed; 
	      pCode[8] = seed; // assign temp value back
	      pCode += 9;
	    }
	  break;

	  default:
	    goto Error2_;
	  }
      }
    break;

    case PCIT::GENFUNC_MBIN8_MBIN8_MBIN8_IBIN32S_IBIN32S:
      {
	switch (pCode[0])
	  {
	  case ITM_CONCAT:
	    {
	      PTR_DEF_ASSIGN(char, tgt, 1 );
	      PTR_DEF_ASSIGN(char, op1, 3 );
	      PTR_DEF_ASSIGN(char, op2, 5 );
	      DEF_ASSIGN(Int32, length1, 7 );
	      DEF_ASSIGN(Int32, length2, 8 );

	      str_cpy_all(tgt, op1, length1);
	      str_cpy_all(&tgt[length1], op2, length2);
	    }
	  pCode += 9;
	  break;

	  // bitand, bitor, bitxor done for int32 or Int64 operands
	  // and result. This has been validated during pcode gen for
	  // this operation.
	  case ITM_BITAND:
	    {
	      DEF_ASSIGN(Int32, oper, 7 );
	      if ( oper == REC_BIN32_UNSIGNED )
	      {
		PTR_DEF_ASSIGN(UInt32, result, 1 );
		PTR_DEF_ASSIGN(UInt32, op1, 3 );
		PTR_DEF_ASSIGN(UInt32, op2, 5 );

		* result = *op1 & *op2 ;
	      }
	      else if ( oper == REC_BIN32_SIGNED )
	      {
		PTR_DEF_ASSIGN(Int32, result, 1 );
		PTR_DEF_ASSIGN(Int32, op1, 3 );
		PTR_DEF_ASSIGN(Int32, op2, 5 );

		* result = *op1 & *op2 ;
	      }
	      else 
	      {
		PTR_DEF_ASSIGN(Int64, result, 1 );
		PTR_DEF_ASSIGN(Int64, op1, 3 );
		PTR_DEF_ASSIGN(Int64, op2, 5 );

		* result = *op1 & *op2 ;
	      }
		
	      pCode += 9;
	    }
	  break;

	  case ITM_BITOR:
	    {
	      DEF_ASSIGN(Int32, oper, 7 );
	      if ( oper == REC_BIN32_UNSIGNED )
	      {
		PTR_DEF_ASSIGN(UInt32, result, 1 );
		PTR_DEF_ASSIGN(UInt32, op1, 3 );
		PTR_DEF_ASSIGN(UInt32, op2, 5 );

		* result = *op1 | *op2 ;
	      }
	      else if ( oper == REC_BIN32_SIGNED )
	      {
		PTR_DEF_ASSIGN(Int32, result, 1 );
		PTR_DEF_ASSIGN(Int32, op1, 3 );
		PTR_DEF_ASSIGN(Int32, op2, 5 );

		* result = *op1 | *op2 ;
	      }
	      else 
	      {
		PTR_DEF_ASSIGN(Int64, result, 1 );
		PTR_DEF_ASSIGN(Int64, op1, 3 );
		PTR_DEF_ASSIGN(Int64, op2, 5 );

		* result = *op1 | *op2 ;
	      }
		
	      pCode += 9;
	    }
	  break;

	  case ITM_BITXOR:
	    {
	      DEF_ASSIGN(Int32, oper, 7 );
	      if ( oper == REC_BIN32_UNSIGNED )
	      {
		PTR_DEF_ASSIGN(UInt32, result, 1 );
		PTR_DEF_ASSIGN(UInt32, op1, 3 );
		PTR_DEF_ASSIGN(UInt32, op2, 5 );

		* result = *op1 ^ *op2 ;
	      }
	      else if ( oper == REC_BIN32_SIGNED )
	      {
		PTR_DEF_ASSIGN(Int32, result, 1 );
		PTR_DEF_ASSIGN(Int32, op1, 3 );
		PTR_DEF_ASSIGN(Int32, op2, 5 );

		* result = *op1 ^ *op2 ;
	      }
	      else 
	      {
		PTR_DEF_ASSIGN(Int64, result, 1 );
		PTR_DEF_ASSIGN(Int64, op1, 3 );
		PTR_DEF_ASSIGN(Int64, op2, 5 );

		* result = *op1 ^ *op2 ;
	      }
		
	      pCode += 9;
	    }
	  break;

	  case ITM_BITNOT:
	    {
	      DEF_ASSIGN(Int32, oper, 7 );
	      if ( oper == REC_BIN32_UNSIGNED )
	      {
		PTR_DEF_ASSIGN(UInt32, result, 1 );
		PTR_DEF_ASSIGN(UInt32, op1, 3 );

		* result = ~ *op1 ;
	      }
	      else if ( oper == REC_BIN32_SIGNED )
	      {
		PTR_DEF_ASSIGN(Int32, result, 1 );
		PTR_DEF_ASSIGN(Int32, op1, 3 );

		* result =  ~ *op1 ;
	      }
	      else 
	      {
		PTR_DEF_ASSIGN(Int64, result, 1 );
		PTR_DEF_ASSIGN(Int64, op1, 3 );

		* result = ~ *op1 ;
	      }
		
	      pCode += 9;
	    }
	  break;

	  default:
	    goto Error2_;
	  }
      }
    break;

    case PCIT::GENFUNC_MATTR5_MATTR5_IBIN32S:         // upper, lower, trim
    case PCIT::GENFUNC_MATTR5_MATTR5_MBIN32S_IBIN32S: // repeat
      {
        Int32 srcLen = 0, tgtLen = 0, i = 0;
	BASE_PTR_DEF_ASSIGN(char, tgt, 0 );
	BASE_PTR_DEF_ASSIGN(char, src, 5 );

	DEF_ASSIGN(Int32, tgtOffset, 1 );
	DEF_ASSIGN(Int32, tgtVoaOffset, 2 );

        // VOA offsets should always be used in order.
        if(tgtVoaOffset > 0) {
          assert(tgtVoaOffset > lastVoaOffset);
          lastVoaOffset = tgtVoaOffset;
        }

	DEF_ASSIGN(Int32, comboLen1, 4 );
	DEF_ASSIGN(Int32, comboLen2, 9 );
        char* comboPtr1 = (char*)&comboLen1;
        char* comboPtr2 = (char*)&comboLen2;
      
        Int16 tgtNullIndLen = (Int16)comboPtr1[0];
        Int16 tgtVCIndLen   = (Int16)comboPtr1[1];
        Int16 srcNullIndLen = (Int16)comboPtr2[0];
        Int16 srcVCIndLen   = (Int16)comboPtr2[1];
                  
	DEF_ASSIGN(Int32, offset, 6 );
	DEF_ASSIGN(Int32, voaOffset, 7 );

        src += ExpTupleDesc::getVarOffset(src,           // atp_
                                          offset, 
                                          voaOffset, 
	                                  srcVCIndLen,   // vcIndLen
                                          srcNullIndLen  // nullIndLen
                                         ); 
	if (srcVCIndLen > 0)
        {
          srcLen = ExpTupleDesc::getVarLength(src, srcVCIndLen);
        }
	else
	{
	  srcLen = pCode[8];
        }      

        // advance to beginning of data        
        src += srcVCIndLen;

	DEF_ASSIGN(Int32, opRepeat, 12 );
	DEF_ASSIGN(Int32, opx, 10 );

        Int32 subOpc = (pCodeOpc == PCIT::GENFUNC_MATTR5_MATTR5_MBIN32S_IBIN32S)
	  ? opRepeat : opx ;
        
        switch (subOpc) {

	  case ITM_UPPER:
          case ITM_LOWER:
	  {

            tgt += ExpTupleDesc::getTgtVarOffset( tgt,
                                                  tgtOffset,
                                                  tgtVoaOffset,
                                                  tgtVCIndLen,
                                                  tgtNullIndLen,
                                                  varOffset,
                                                  srcLen
                                               );
            if (tgtVCIndLen > 0) 
            {
              ExpTupleDesc::setVarLength(tgt, srcLen, tgtVCIndLen); 
              tgt += tgtVCIndLen;
            }
              
            for (Int32 i = 0; i < srcLen; i++)
	      tgt[i] = (subOpc==ITM_UPPER) ? TOUPPER(src[i]) : TOLOWER(src[i]);
              
	    pCode += 11;
	    break;
	  }

	  case ITM_RTRIM:
	  case ITM_LTRIM:
	  case ITM_TRIM:
	    {     
	      // Find how many leading characters in operand 2 correspond 
	      // to the trim character.
	      Lng32 len0 = srcLen;
	      Lng32 start = 0;   
	      
	      if (subOpc == ITM_LTRIM || subOpc == ITM_TRIM)
		{
		  while ((start < srcLen) && 
			 (src[start] == ' ')
			 )
		    {
		      start++;
		      len0--;
		    }
		}

	      // Find how many trailing characters in operand 2 correspond 
	      // to the trim character.
	      Lng32 end = srcLen;
	      if (subOpc == ITM_RTRIM || subOpc == ITM_TRIM)
		{
		  while ((end > (start)) && 
			 (src[end-1] == ' ')
			 )
		    {
		      end--;
		      len0--;
		    }
		}

              tgt += ExpTupleDesc::getTgtVarOffset( tgt,
                                                    tgtOffset,     // tgt offset
                                                    tgtVoaOffset,  // tgt voa offset
                                                    tgtVCIndLen,
                                                    tgtNullIndLen,
                                                    varOffset,
                                                    len0
                                                  );
              if (tgtVCIndLen > 0) 
              {
                ExpTupleDesc::setVarLength(tgt, len0, tgtVCIndLen); 
                tgt += tgtVCIndLen;
              }
              
	      if (len0 > 0)
	        str_cpy_all(tgt, &src[start], len0);

              pCode += 11;
	    }
	  break;

          case ITM_REPEAT:
            {
	      PTR_DEF_ASSIGN(Int32, repeatCntPtr, 10 );
	      Int32 repeatCnt = * repeatCntPtr;
              UInt32 totalSize = srcLen * repeatCnt;
	      DEF_ASSIGN(Int32, maxTargetLen, 3 );

              // If len is negative or the total bytes to write exceeds the max
              // target len, report an error.
              if ((repeatCnt < 0) || (repeatCnt * srcLen > maxTargetLen))
                goto Error1_;

              tgt += ExpTupleDesc::getTgtVarOffset( tgt,
                                                    tgtOffset,
                                                    tgtVoaOffset,
                                                    tgtVCIndLen,
                                                    tgtNullIndLen,
                                                    varOffset,
                                                    totalSize
                                                  );
              if (tgtVCIndLen > 0) 
              {
                ExpTupleDesc::setVarLength(tgt, totalSize, tgtVCIndLen); 
                tgt += tgtVCIndLen;
              }
              
              for (i=0; i < repeatCnt; i++) {
                str_cpy_all(tgt, src, srcLen);
                tgt += srcLen;
              }
              
              pCode += 13;

              break;
            }
        }

        break;
    }

    case PCIT::HASH2_DISTRIB:
      {
	PTR_DEF_ASSIGN(UInt32, resultPtr, 0 );
	PTR_DEF_ASSIGN(UInt32, hashValPtr, 2 );
	PTR_DEF_ASSIGN(UInt32, numPartsPtr, 4 );

	*resultPtr = (UInt32)((Int64)*hashValPtr * (Int64)*numPartsPtr >> 32);

        pCode += 6;
      }
      break;


    case PCIT::OFFSET_IPTR_IPTR_MBIN32S_MBIN64S_MBIN64S:
      {
	PTR_DEF_ASSIGN(Int32, indexPtr, 2 * PCODEBINARIES_PER_PTR);
	Int32 index = * indexPtr;
  
        // Lookup the indexed row in the history buffer. Compute pointers
        // to the attribute data, null indicator, and varchar indicator.
        //
        Int64 *srcData = NULL;

        {
          char *(*getRow)(void*,Int32,NABoolean,Lng32,Int32&);
          Int32 rc;

          getRow = (char *(*)(void*,Int32,NABoolean,Lng32,Int32&) )
                     GetPCodeBinaryAsPtr(pCode, 0);

          char *row = (*(getRow))((void *) GetPCodeBinaryAsPtr(pCode, PCODEBINARIES_PER_PTR),
                        index, TRUE, 0, rc);
          if(rc)
            {
              diagsArea = atp1->getDiagsArea();
              ExRaiseSqlError(heap_, &diagsArea, EXE_HISTORY_BUFFER_TOO_SMALL);
              if(diagsArea != atp1->getDiagsArea())
                atp1->setDiagsArea(diagsArea);
              return ex_expr::EXPR_ERROR;
            }

          if(row) 
            {
              srcData = (Int64 *)(row + pCode[5 + 2 * PCODEBINARIES_PER_PTR]);
            }
        }

	PTR_DEF_ASSIGN(Int64, dstData, 2 + 2 * PCODEBINARIES_PER_PTR);

        *dstData = (srcData ? *srcData : 0);

        pCode += 6 + 2 * PCODEBINARIES_PER_PTR;
      }
      break;

    case PCIT::OFFSET_IPTR_IPTR_IBIN32S_MBIN64S_MBIN64S:
      {
	DEF_ASSIGN(Int32, index, 2 * PCODEBINARIES_PER_PTR);
  
        // Lookup the indexed row in the history buffer. Compute pointers
        // to the attribute data, null indicator, and varchar indicator.
        //
        Int64 *srcData = NULL;

        {
          char *(*getRow)(void*,Int32,NABoolean,Lng32,Int32&) ;
          Int32 rc;
          getRow = (char *(*)(void*,Int32,NABoolean,Lng32,Int32&) )
                    GetPCodeBinaryAsPtr(pCode, 0);
          char *row = (*(getRow))(
                        (void *) GetPCodeBinaryAsPtr(pCode, PCODEBINARIES_PER_PTR),
                        index, TRUE, 0, rc);
          if(rc)
            {
              diagsArea = atp1->getDiagsArea();
              ExRaiseSqlError(heap_, &diagsArea, EXE_HISTORY_BUFFER_TOO_SMALL);
              if(diagsArea != atp1->getDiagsArea())
                atp1->setDiagsArea(diagsArea);
              return ex_expr::EXPR_ERROR;
            }

          if(row) 
            {
              srcData = (Int64 *)(row + pCode[4 + 2 * PCODEBINARIES_PER_PTR]);
            }
        }

	PTR_DEF_ASSIGN(Int64, dstData, 1 + 2 * PCODEBINARIES_PER_PTR);

        *dstData = (srcData ? *srcData : 0);

        pCode += 5 + 2 * PCODEBINARIES_PER_PTR;
      }
      break;

    case PCIT::COMP_MBIN32S_MBIGS_MBIGS_IBIN32S_IBIN32S:
    {
      PTR_DEF_ASSIGN(Int32, result, 0 );
      PTR_DEF_ASSIGN(UInt16,  src1, 2 );
      PTR_DEF_ASSIGN(UInt16,  src2, 4 );
      DEF_ASSIGN(Int32, len, 6 );
      Int32 len16 = len >> 1;

      // Pull out what type of comparison (e.g. ITM_EQUAL) to perform.
      DEF_ASSIGN(Int32, op, 7 );

      Int32 compCode = 1; // Assume comparison is EQ

      // Extract signs.
      char src1Sign = BIGN_GET_SIGN(src1, len);
      char src2Sign = BIGN_GET_SIGN(src2, len);

      // Clear sign bits
      BIGN_CLR_SIGN(src1, len);
      BIGN_CLR_SIGN(src2, len);

      // If the signs aren't equal, then we only need to check that both src
      // values are not 0 - otherwise we can clearly say what the result of
      // the comparison should be

      if (src1Sign != src2Sign) {
        for (Int32 i=0; i < len16; i++) {
          if ((src1[i] != 0) || (src2[i] != 0)) {
            compCode = (src1Sign == 0) ? 2 : 0;
            break;
          }
        }
      }
      else {
        // Both signs are different, so find out where the difference is
        for (Int32 i=len16-1; i >= 0; i--) {
          if (src1[i] == src2[i])
            continue;

          // Here lies the difference.  Return 0, 1, or 2 for compCode, 
          // depending on how src1[i] compares to src2[i]

          compCode = (src1[i] > src2[i]) ? ((src1Sign) ? 0 : 2)
                                         : ((src1Sign) ? 2 : 0);
          break;
        }
      }

      // Reset sign bits
      if (src1Sign)
        BIGN_SET_SIGN(src1, len);

      if (src2Sign)
        BIGN_SET_SIGN(src2, len);

      // Assign result
      *result = compTable[op - ITM_EQUAL][compCode];

      pCode += 8;
      break;
    }

    case PCIT::MOVE_MBIGS_MBIGS_IBIN32S_IBIN32S:
    {
      Int32 i;

      DEF_ASSIGN(Int32, tgtLength, 4);
      DEF_ASSIGN(Int32, srcLength, 5);

      PTR_DEF_ASSIGN(char, tgt, 0 );
      PTR_DEF_ASSIGN(char, src, 2 );

      // Get length in terms of double-words
      Int32 tgtLength16 = tgtLength >> 1;
      Int32 srcLength16 = srcLength >> 1;

      // Get source sign bit and then temporarily clear it
      char srcSign = BIGN_GET_SIGN(src, srcLength);
      BIGN_CLR_SIGN(src, srcLength);

      // If src value is too big for tgt, report overflow
      for (; srcLength16 > tgtLength16; srcLength16--) {
        if (((Int16*)src)[srcLength16 - 1] != 0) {
          // Reset source sign bit before reporting error
          if (srcSign)
            BIGN_SET_SIGN(src, srcLength);
          goto Error1_;
        }
      }

      // Only clear out tgt bits if move won't do it for you.
      if (tgtLength > srcLength)
        for (i=0; i < tgtLength16; i++)
          ((Int16*)tgt)[i] = 0;

      // Copy over shorts from bignum src
      for (i=0; i < srcLength16; i++)
        ((UInt16*)tgt)[i] = ((UInt16*)src)[i];

      if (srcSign) {
        BIGN_SET_SIGN(src, srcLength);
        BIGN_SET_SIGN(tgt, tgtLength);
      }

      pCode += 6;
      break;
    }

    case PCIT::MOVE_MBIGS_MBIN16S_IBIN32S:
    case PCIT::MOVE_MBIGS_MBIN32S_IBIN32S:
    case PCIT::MOVE_MBIGS_MBIN64S_IBIN32S:
    {
      Int32 i;

      DEF_ASSIGN(Int32, tgtLength, 4 );
      Int32 tgtLength16 = tgtLength >> 1;
      PTR_DEF_ASSIGN(UInt16,  tgt, 0 );
      PTR_DEF_ASSIGN(Int64, src, 2 );
      Int64* tgt64 = (Int64*)tgt;


      Int64 srcVal;

      if (pCodeOpc == PCIT::MOVE_MBIGS_MBIN64S_IBIN32S)
        srcVal = *src;
      else if (pCodeOpc == PCIT::MOVE_MBIGS_MBIN32S_IBIN32S)
        srcVal = *((Int32*)(src));
      else
        srcVal = *((Int16*)(src));

      NABoolean isNeg = FALSE;

      for (i=0; i < tgtLength16; i++)
        tgt[i] = 0;

      if (srcVal < 0) {
        srcVal = -srcVal;
        isNeg = TRUE;
      }

      *tgt64 = srcVal;

#ifndef NA_LITTLE_ENDIAN
      UInt16 temp1 = tgt[0];
      UInt16 temp2 = tgt[1];
      tgt[0] = tgt[3];
      tgt[1] = tgt[2];
      tgt[2] = temp2;
      tgt[3] = temp1;
#endif

      if (isNeg)
        BIGN_SET_SIGN(tgt, tgtLength);

      pCode += 5;
      break;
    }

    case PCIT::MOVE_MBIN64S_MBIGS_IBIN32S:
    {
      Int32 i;

      DEF_ASSIGN(Int32, srcLength, 4);
      Int32 srcLength16 = srcLength >> 1;

      PTR_DEF_ASSIGN(Int64, tgt, 0 );
      PTR_DEF_ASSIGN(char, src, 2 );


      // Get source sign bit and then temporarily clear it
      char srcSign = BIGN_GET_SIGN(src, srcLength);
      BIGN_CLR_SIGN(src, srcLength);

      for (i=4; i < srcLength16; i++) {
        if (((Int16*)src)[i] != 0) {
          // Reset source sign bit before reporting error
          if (srcSign)
            BIGN_SET_SIGN(src, srcLength);
          goto Error1_;
        }
      }

      *tgt = *((Int64*)src);

#ifndef NA_LITTLE_ENDIAN
      UInt16 temp1 = ((UInt16*)tgt)[0];
      UInt16 temp2 = ((UInt16*)tgt)[1];
      ((UInt16*)tgt)[0] = ((UInt16*)tgt)[3];
      ((UInt16*)tgt)[1] = ((UInt16*)tgt)[2];
      ((UInt16*)tgt)[2] = temp2;
      ((UInt16*)tgt)[3] = temp1;
#endif

      // Reset source sign bit
      if (srcSign)
        BIGN_SET_SIGN(src, srcLength);

      // If bignum was positive but that resulted in the sign bit being set
      // in the 64-bit target, then we overflowed.
      if ((srcSign == 0) && (*tgt < 0))
        goto Error1_;
      else if ((srcSign) && (*tgt < 0) && (*tgt != LLONG_MIN))
        goto Error1_;

      if ((srcSign) && (*tgt != LLONG_MIN))
        *tgt = -(*tgt);

      pCode += 5;
      break;
    }

    case PCIT::MUL_MBIGS_MBIGS_MBIGS_IBIN32S:
    {
      Int32 i, j, pos;
      UInt16 carry;

      PTR_DEF_ASSIGN(UInt16,  tgt, 0 );
      PTR_DEF_ASSIGN(UInt16,  src1, 2 );
      PTR_DEF_ASSIGN(UInt16,  src2, 4 );

      DEF_ASSIGN(Int32, tgtLength, 6 );
      DEF_ASSIGN(Int32, leftLength, 7 );
      DEF_ASSIGN(Int32, rightLength, 8 );

      Int32 leftLength16 = leftLength >> 1;
      Int32 rightLength16 = rightLength >> 1;
      Int32 tgtLength16 = tgtLength >> 1;

      // Get source sign bit and then temporarily clear it
      char src1Sign = BIGN_GET_SIGN(src1, leftLength);
      char src2Sign = BIGN_GET_SIGN(src2, rightLength);

      BIGN_CLR_SIGN(src1, leftLength);
      BIGN_CLR_SIGN(src2, rightLength);

      for (i=0; i < tgtLength16; i++)
        ((Int16*)tgt)[i] = 0;

      while ((leftLength16 > 0) && (src1[leftLength16 - 1] == 0))
        leftLength16--;

      while ((rightLength16 > 0) && (src2[rightLength16 - 1] == 0))
        rightLength16--;

      if ((leftLength16 != 0) && (rightLength16 != 0)) {
        // Multiply shorts - this is because bignum stored this way.
        for (j=0; j < rightLength16; j++) {

          for (i=0, carry=0, pos=j; i < leftLength16; i++, pos++) {
            UInt32 result = (((UInt32)src1[i]) * src2[j]) + tgt[pos] + carry;
            tgt[pos] = (UInt16)(result & 0xffff);
            carry = (UInt16)(result >> 16);
          }

          if (carry)
            tgt[pos] = carry;
        }
      }

      if (src1Sign)
	BIGN_SET_SIGN(src1, leftLength);

      if (src2Sign)
	BIGN_SET_SIGN(src2, rightLength);

      if (src1Sign != src2Sign)
        BIGN_SET_SIGN(tgt, tgtLength);

      pCode += 9;

      break;
    }

    case PCIT::SUM_MATTR3_MATTR3_IBIN32S_MBIGS_MBIGS_IBIN32S:
    case PCIT::ADD_MBIGS_MBIGS_MBIGS_IBIN32S:
    case PCIT::SUB_MBIGS_MBIGS_MBIGS_IBIN32S:
    {
      UInt16 *tgt, *src1, *src2;
      NABoolean performAdd = TRUE;
      UInt16 carry = 0;
      Int32 length;
      Int32 i;

      if (pCodeOpc == PCIT::SUM_MATTR3_MATTR3_IBIN32S_MBIGS_MBIGS_IBIN32S)
      {
	PTR_DEF_ASSIGN(UInt16,  tgtPtr, 7 );
        src1 = tgt = tgtPtr ;
	PTR_DEF_ASSIGN(UInt16,  src2Ptr, 9 );
	src2 = src2Ptr;
	DEF_ASSIGN(Int32,lenVal, 11);
	length = lenVal;
	DEF_ASSIGN(Int32, isNullable, 6 );

	if ( isNullable )
        {
          NABoolean isNull;

	  PTR_DEF_ASSIGN(Int16, tgtNull, 0 );
	  PTR_DEF_ASSIGN(Int16, srcNull, 3 );
	  DEF_ASSIGN(Int16, indxTgt, 2 );
	  DEF_ASSIGN(Int16, indxSrc, 5 );

          isNull =  indxSrc == -1  ?  *srcNull != 0  :
	    ExpAlignedFormat::isNullValue((char*)srcNull, indxSrc) ;

          if (isNull) {
            pCode += 12;
            break;
          }

          isNull =  indxTgt == -1  ?  *tgtNull != 0  :
	    ExpAlignedFormat::isNullValue((char*)tgtNull, indxTgt );

          if (isNull) {
	    if ( indxTgt == -1 )
              *tgtNull = 0;
            else
	      ExpAlignedFormat::clearNullBit((char*)tgtNull, indxTgt);

            str_pad((char*)tgt, length, 0);
          }
        }

        pCode += 5; // Re-position to align with ADD/SUB instruction.
      }
      else
      {
	PTR_DEF_ASSIGN(UInt16, tgtPtr, 0 );
	PTR_DEF_ASSIGN(UInt16, src1Ptr, 2 );
	PTR_DEF_ASSIGN(UInt16, src2Ptr, 4 );
	tgt = tgtPtr; src1 = src1Ptr; src2 = src2Ptr;
	DEF_ASSIGN(Int32,lenVal, 6);
	length = lenVal;
      }

      Int32 length16 = length >> 1;

      // Get source sign bits
      char src1Sign = BIGN_GET_SIGN(src1, length);
      char src2Sign = BIGN_GET_SIGN(src2, length);

      char* origSrc1 = (char*)src1;
      char* origSrc2 = (char*)src2;

      char origSrc1Sign = src1Sign;
      char origSrc2Sign = src2Sign;

      // Temporarily clear sign bits
      BIGN_CLR_SIGN(src1, length);
      BIGN_CLR_SIGN(src2, length);

      if (pCodeOpc == PCIT::SUB_MBIGS_MBIGS_MBIGS_IBIN32S) {
        if (src1Sign == src2Sign) {
          performAdd = FALSE;

          // We want to distribute the SUB operation into the signs of the
          // source operand so that everything is normalized as if we were
          // just doing an ADD and the source operands carried the sign.
          src2Sign = (src2Sign == 0) ? MSB_SET_MSK : 0;
        }
      }
      else {
        if (src1Sign != src2Sign)
          performAdd = FALSE;
      }

      NABoolean notEqual = FALSE; // assuming src1 equals src2 for sub
      if (performAdd)
      {
        // Add shorts - this is because bignum stored this way.
        for (i=0; i < length16; i++) {
          UInt32 result = (UInt32)src1[i] + src2[i] + carry;
          tgt[i] = (UInt16)(result & 0xffff);
          carry = (UInt16)(result >> 16);
        }
      }
      else
      {
        // Determine which source is bigger
        for (i = length16-1; i >= 0; i--) {
          // Skip equality
          if (src1[i] == src2[i])
            continue;

          notEqual = TRUE;
          if (src1[i] < src2[i]) {
            // swap src1 and src2 along with their signs so the result is
            // positive and the src1Sign would be the result sign
            UInt16* temp = src1; src1 = src2; src2 = temp;
            char tempSign = src1Sign; src1Sign = src2Sign; src2Sign = tempSign;
          }

          break;
        }

        // Sub shorts - this is because bignum stored this way.
        for (i=0; i < length16; i++) {
          Int32 result = (Int32)src1[i] - src2[i] + (Int16)carry;
          tgt[i] = (UInt16) (result + (Int32)0x10000) & 0xffff;
          carry = (result < 0) ? -1 : 0;
        }
      }

      if (origSrc1Sign)
        BIGN_SET_SIGN(origSrc1, length);

      if (origSrc2Sign)
        BIGN_SET_SIGN(origSrc2, length);

      // Set target sign - will always be src1Sign unless target is 0
      if (src1Sign && (performAdd || notEqual)) {
        BIGN_SET_SIGN(tgt, length);
      } else {
        BIGN_CLR_SIGN(tgt, length);
      }

      // Report overflow
      if (carry != 0)
        goto Error1_;

      pCode += 7;
      break;
    }

    case PCIT::SWITCH_MBIN32S_MBIN64S_MPTR32_IBIN32S_IBIN32S:
    {
      PTR_DEF_ASSIGN(UInt32, result, 0 );
      PTR_DEF_ASSIGN(Int64, src, 2 );
      DEF_ASSIGN(UInt32, flags, 7 );
      NABoolean isInList = flags & 0x01;
      DEF_ASSIGN(Int32, size, 6 );
      Int32 i;

      //
      // Pointers to tables representing 64-bit values in IN-list and 32-bit
      // pc-relative offsets for then clauses of case statement.  Tables look
      // as follows:
      //
      // In-list:  val1, val2, ..., valN
      // Case:     val1, val2, ..., valN, pcOff1, pcOff2, ..., pcOffN, pcOffDflt
      //

      PTR_DEF_ASSIGN(Int64, vals, 4 );
      Long* pcOffs = (Long*)(&vals[size]);  // i.e. the jump table


      // Assume no match
      Int32 compCode = 0;

      UInt32  hashVal = ExHDPHash::hash8((char*)src, ExHDPHash::NO_FLAGS);
      UInt32  index   = hashVal % size;

      // Compare value at index, if element at index is valid.
      for (i=0; (i < 4) && (vals[index] != PCodeCfg::INVALID_INT64); i++) {
        // Compare values to ensure match, then return TRUE if match found.
        if (vals[index] == *src) {
          compCode = 1;
          break;
        }

        // Assuming the next element is not at the end of the table, keep
        // trying for at most 4 times in total.
        if (++index >= (UInt32)size)
          break;
      }

      // Get jump table location, using default case if item not found
      if (!isInList)
        compCode = ((compCode == 0) ? pcOffs[size] : pcOffs[index]);

      *result = compCode;

      pCode += 8;
      break;
    }

    case PCIT::SWITCH_MBIN32S_MATTR5_MPTR32_IBIN32S_IBIN32S:
    {
      PTR_DEF_ASSIGN(UInt32, result, 0 );
      DEF_ASSIGN(UInt32, flags, 10 );
      NABoolean isInList = flags & 0x01;
      NABoolean ignoreSpaces = flags & 0x02;
      DEF_ASSIGN(Int32, size, 9 );
      Int32 compCode     = -1;  // Assume no match
      Int32 i;

      //
      // Pointer to table representing constant strings in IN-list and 32-bit
      // pc-relative offsets for then clauses of case statement.  Tables look
      // as follows:
      //
      // In-list:  [len1, off1], [len2, off2], ..., [lenN, offN]
      // Case:     [len1, off1], [len2, off2], ..., [lenN, offN],
      //             pcOff1, pcOff2, ..., pcOffDflt
      //

      PTR_DEF_ASSIGN(Int32, table, 7 );
      Long *pcOffs = (isInList)? NULL: (Long*)&(table[size<<1]);
        


      DEF_ASSIGN(Int32, offset, 3 ); 
      DEF_ASSIGN(Int32, voaOffset, 4 ); 
      DEF_ASSIGN(Int32, comboLen1, 6 ); 
      char* comboPtr1    = (char*)&comboLen1;
      Int16 srcNullIndLen = (Int16)comboPtr1[0];
      Int16 srcVCIndLen   = (Int16)comboPtr1[1];

      DEF_ASSIGN(UInt32, len1, 5 );
      BASE_PTR_DEF_ASSIGN(char, src1, 2 );

      if (srcVCIndLen > 0) {
        src1 += ExpTupleDesc::getVarOffset(src1,
                                           offset,
                                           voaOffset,
                                           srcVCIndLen,   // vcIndLen
                                           srcNullIndLen  // nullIndLen
                                          );

        len1 = ExpTupleDesc::getVarLength(src1, srcVCIndLen);
        src1 += srcVCIndLen;
      }
      else {
        src1 += offset; 
      }

      // skip trailing blanks if asked to
      if (!ignoreSpaces)
        while ((len1 > 0) && (src1[len1-1] == ' '))
          len1--;

      UInt32 hashVal = ExHDPHash::hash(src1, ExHDPHash::NO_FLAGS, len1);
      UInt32 index   = (hashVal % size) << 1;

      // Compare value at index, if element at index is valid.
      for (i=0; (i < 4) && (table[index] != PCodeCfg::INVALID_INT32); i++) {
        UInt32 len2 = table[index];
        char* src2  = (char*)(stack[1] + table[index + 1]);
        compCode = ((len1 != len2) || memcmp(src1, src2, len1));

        // If match is false, try next entry in table (at most 4 checks).
        if ((compCode == 0) || ((Int32)(index + 2) >= (size << 1)))
          break;

        index += 2;
      }

      if (compCode == 0)  // match
        *result = (isInList) ? 1 : pcOffs[(index >> 1)];
      else  // taking default
        *result = (isInList) ? 0 : pcOffs[size];

      pCode += 11;
      break;
    }

  case PCIT::NULL_VIOLATION_MBIN16U_MBIN16U:
  {
    PTR_DEF_ASSIGN(Int16, tmp, 0 );
    if ( *tmp != 0 )
    {
      // Raise an "assigning a null value to a NOT NULL".
      diagsArea = atp1->getDiagsArea();
      ExRaiseSqlError(getHeap(), &diagsArea, 
        EXE_ASSIGNING_NULL_TO_NOT_NULL);
      if(diagsArea != atp1->getDiagsArea())
        atp1->setDiagsArea(diagsArea);

      return ex_expr::EXPR_ERROR;
    }
    pCode += 2;
    // Do NOT break here...
    // The first null has been processed above, so fall through to 
    // process the second null.
    // These two cases belong together...
  }
  case PCIT::NULL_VIOLATION_MBIN16U:
  {
    PTR_DEF_ASSIGN(Int16, tmp, 0 );
    if ( *tmp != 0 )
    {
      // Raise an "assigning a null value to a NOT NULL".
      diagsArea = atp1->getDiagsArea();
      ExRaiseSqlError(getHeap(), &diagsArea, 
        EXE_ASSIGNING_NULL_TO_NOT_NULL);
      if(diagsArea != atp1->getDiagsArea())
        atp1->setDiagsArea(diagsArea);
      return ex_expr::EXPR_ERROR;
    }
    pCode += 2;
    break;
  }
  case PCIT::NULL_TEST_MBIN32S_MATTR5_IBIN32S_IBIN32S:
    {
      // if the flag is set, operand is an indirect varchar and must 
      // use voaOffset to get to the nullIndicator. 
      // The flag will not be set for aligned format. 
      DEF_ASSIGN(Int16, idx, 6 );
      DEF_ASSIGN(Int32, flag1, 7 );
      DEF_ASSIGN(Int32, flag2, 8 );
      DEF_ASSIGN(Int32, val, 3 );
      PTR_DEF_ASSIGN(Int32, ptr, 0 );
      UInt32 pCode3 = flag1 == 1 ? *((Int32*)(stack[pCode[2]] + pCode[4]))
                                 :  val;
 
      NABoolean srcNull =
        ExpTupleDesc::isNullValue((char*)(stack[pCode[2]]+pCode3), idx, 
				  (ExpTupleDesc::TupleDataFormat)pCode[5]);
      
      if ( srcNull && flag2 != 0 ) *ptr = 1;
      else if ( !srcNull && flag2 == 0 ) *ptr = 1;
      else *ptr = 0 ;
      pCode += 9;
      break;
    }

    case PCIT::END:
      return retCode;

    case PCIT::NOP:
      break;

    default:
      assert(pCodeOpc == -1);
      goto Error2_;
    };
  };
  
					    Error1_:
  return reportOverflowError(atp1, pCodeOpcPtr, pCode, stack);
					    
					    Error2_:
  diagsArea = atp1->getDiagsArea();
  ExRaiseSqlError(heap_, &diagsArea, EXE_INTERNAL_ERROR);
  if(diagsArea != atp1->getDiagsArea())
    atp1->setDiagsArea(diagsArea);
  return ex_expr::EXPR_ERROR;
}

/**
*** This routine is only called when a divide by zero or overflow occurred
*** during expression evaluation in evalPCode().  Any time a new pCode
*** instruction is inserted which could result in such an exception, this
*** routine needs to be modified.  The pCode pointer passed in is assumed to
*** be at the first operand position passed the opcode.
**/
ex_expr::exp_return_type ex_expr_base::reportOverflowError(
					      atp_struct *atp1, 
					      PCodeBinary* pCodeOpcPtr,
					      PCodeBinary* pCode,
					      Long* stack)
{
  ComDiagsArea *diagsArea = atp1->getDiagsArea();

  char* op1;
  char* op2;
  ExeErrorCode ovfl;
  Int32 instr;

  // Retrieve the pCode opcode associated with this failure.  Because certain
  // instructions fall into others during expression evaluation, we need to be
  // careful to assign instr as is expected when reporting the error.

  if (*pCodeOpcPtr == PCIT::SUM_MATTR3_MATTR3_IBIN32S_MBIN64S_MBIN64S)
    instr = PCIT::SUM_MBIN64S_MBIN64S;
  else if (*pCodeOpcPtr == PCIT::SUM_MATTR3_MATTR3_IBIN32S_MFLT64_MFLT64)
    instr = PCIT::SUM_MFLT64_MFLT64;
  else if (*pCodeOpcPtr == PCIT::SUM_MATTR3_MATTR3_IBIN32S_MBIGS_MBIGS_IBIN32S)
    instr = PCIT::ADD_MBIGS_MBIGS_MBIGS_IBIN32S;
  else
    instr = *(pCode-1);

  switch (instr) {
    case PCIT::ADD_MBIGS_MBIGS_MBIGS_IBIN32S:
    case PCIT::SUB_MBIGS_MBIGS_MBIGS_IBIN32S:
    case PCIT::ADD_MBIN64S_MBIN64S_MBIN64S:
    case PCIT::ADD_MBIN64S_MBIN32S_MBIN64S:
    case PCIT::SUB_MBIN64S_MBIN64S_MBIN64S:
    case PCIT::MUL_MBIN64S_MBIN64S_MBIN64S:
    case PCIT::ADD_MFLT64_MFLT64_MFLT64:
    case PCIT::SUB_MFLT64_MFLT64_MFLT64:
    case PCIT::MUL_MFLT64_MFLT64_MFLT64:
      op1 = ((char*)(stack[pCode[2]] + pCode[3]));
      op2 = ((char*)(stack[pCode[4]] + pCode[5]));
      ovfl = EXE_NUMERIC_OVERFLOW;

      break;

    case PCIT::SUM_MBIN64S_MBIN64S:
    case PCIT::SUM_MFLT64_MFLT64:
      op1 = ((char*)(stack[pCode[0]] + pCode[1]));
      op2 = ((char*)(stack[pCode[2]] + pCode[3]));
      ovfl = EXE_NUMERIC_OVERFLOW;

      break;

    case PCIT::DIV_MBIN64S_MBIN64S_MBIN64S:
    case PCIT::DIV_MBIN64S_MBIN64S_MBIN64S_ROUND:
      op1 = ((char*)(stack[pCode[2]] + pCode[3]));
      op2 = ((char*)(stack[pCode[4]] + pCode[5]));

      if (*((Int64*)(stack[pCode[4]] + pCode[5])) == 0) {
        ovfl = EXE_DIVISION_BY_ZERO;
      }
      else {
        ovfl = EXE_NUMERIC_OVERFLOW;
      }

      break;

    case PCIT::DIV_MFLT64_MFLT64_MFLT64:
      op1 = ((char*)(stack[pCode[2]] + pCode[3]));
      op2 = ((char*)(stack[pCode[4]] + pCode[5]));

      if (*((double *)(stack[pCode[4]] + pCode[5])) == 0) {
        ovfl = EXE_DIVISION_BY_ZERO;
      }
      else {
        ovfl = EXE_NUMERIC_OVERFLOW;
      }

      break;

    case PCIT::RANGE_MFLT64:
      op1 = ((char*)(stack[pCode[0]] + pCode[1]));
      op2 = NULL;
      ovfl = EXE_NUMERIC_OVERFLOW;
      break;

    case PCIT::RANGE_LOW_S64S64:
      op1 = ((char*)(stack[pCode[0]] + pCode[1]));
      op2 = (char*)(&pCode[2]);

      if (((*((Int64*)(stack[pCode[0]]+pCode[1]))) < 0) &&
          ((*(Int64*)&pCode[2]) >= 0))
      { // conversion of -ve num to unsigned field
        ovfl = EXE_UNSIGNED_OVERFLOW;
      }
      else {
        ovfl = EXE_NUMERIC_OVERFLOW;
      }

      break;

    case PCIT::RANGE_LOW_S32S64:
      op1 = ((char*)(stack[pCode[0]] + pCode[1]));
      op2 = (char*)(&pCode[2]);

      if (((*((Int32*)(stack[pCode[0]]+pCode[1]))) < 0) &&
          ((*(Int64*)&pCode[2]) >= 0))
      { // conversion of -ve num to unsigned field
        ovfl = EXE_UNSIGNED_OVERFLOW;
      }
      else {
        ovfl = EXE_NUMERIC_OVERFLOW;
      }

      break;

    case PCIT::RANGE_LOW_U32S64:
    case PCIT::RANGE_LOW_U16S64:
    case PCIT::RANGE_HIGH_S64S64:
    case PCIT::RANGE_HIGH_S32S64:
    case PCIT::RANGE_HIGH_U32S64:
    case PCIT::RANGE_HIGH_S16S64:
    case PCIT::RANGE_HIGH_U16S64:
      op1 = ((char*)(stack[pCode[0]] + pCode[1]));
      op2 = (char*)(&pCode[2]);
      ovfl = EXE_NUMERIC_OVERFLOW;

      break;

    case PCIT::RANGE_LOW_S16S64:
      op1 = ((char*)(stack[pCode[0]] + pCode[1]));
      op2 = (char*)(&pCode[2]);

      if (((*((short*)(stack[pCode[0]]+pCode[1]))) < 0) &&
          ((*(Int64*)&pCode[2]) >= 0))
      { // conversion of -ve num to unsigned field
        ovfl = EXE_UNSIGNED_OVERFLOW;
      }
      else {
        ovfl = EXE_NUMERIC_OVERFLOW;
      }

      break;

    case PCIT::MOVE_MBIN64S_MBIGS_IBIN32S:
      op2 = ((char*)(stack[pCode[2]] + pCode[3]));
      ExRaiseDetailSqlError(getHeap(), &diagsArea, EXE_NUMERIC_OVERFLOW, op2,
                            pCode[4], REC_NUM_BIG_SIGNED, 0,
                            REC_BIN64_SIGNED, 0);
      if(diagsArea != atp1->getDiagsArea())
        atp1->setDiagsArea(diagsArea);
      return ex_expr::EXPR_ERROR;
      break;

    case PCIT::MOVE_MBIGS_MBIGS_IBIN32S_IBIN32S:
      op2 = ((char*)(stack[pCode[2]] + pCode[3]));
      ExRaiseDetailSqlError(getHeap(), &diagsArea, EXE_NUMERIC_OVERFLOW, op2,
                            pCode[5], REC_NUM_BIG_SIGNED, 0,
                            REC_NUM_BIG_SIGNED,0);
      if(diagsArea != atp1->getDiagsArea())
        atp1->setDiagsArea(diagsArea);
      return ex_expr::EXPR_ERROR;
      break;

    case PCIT::GENFUNC_MATTR5_MATTR5_MBIN32S_IBIN32S:
      op1 = ((char*)(stack[pCode[10]] + pCode[11]));
      op2 = ((char*)(stack[pCode[10]] + pCode[11]));
      ovfl = EXE_NUMERIC_OVERFLOW;
      break;

    case PCIT::CONCAT_MATTR5_MATTR5_MATTR5:
      ExRaiseFunctionSqlError(getHeap(), &diagsArea, EXE_STRING_OVERFLOW,FALSE);
      return ex_expr::EXPR_ERROR;

    default:
      ExRaiseSqlError(heap_,
                      &diagsArea,
                      EXE_INTERNAL_ERROR);

      if(diagsArea != atp1->getDiagsArea())
        atp1->setDiagsArea(diagsArea);
      return ex_expr::EXPR_ERROR;
  }

  ExRaiseDetailSqlError(getHeap(),
                        &diagsArea,
                        ovfl,
                        (PCIT::Instruction)instr,
                        op1,
                        op2);

  if(diagsArea != atp1->getDiagsArea())
    atp1->setDiagsArea(diagsArea);
  return ex_expr::EXPR_ERROR;
}

ex_expr::exp_return_type ex_clause::eval(char * /*op_data*/[],
					 CollHeap*,
					 ComDiagsArea**)
{
  // default eval method does nothing and returns OK
  return ex_expr::EXPR_OK;
};

ex_expr::exp_return_type AggrExpr::initializeAggr(atp_struct * atp)
{
  if (initExpr_)
    {
      if (initExpr_->eval(atp, atp) == ex_expr::EXPR_ERROR)
	return ex_expr::EXPR_ERROR;
    }

  ex_clause *clause = getClauses();
  while (clause)
    {
      if (clause->getType() == ex_clause::AGGREGATE_TYPE)
	{
	  if (((ex_aggregate_clause *)clause)->init() == ex_expr::EXPR_ERROR)
	    return ex_expr::EXPR_ERROR;
	}
      
      clause = clause->getNextClause();
    }

  return ex_expr::EXPR_OK;
}

ex_expr::exp_return_type AggrExpr::finalizeAggr(atp_struct * /*atp*/)
{
  return ex_expr::EXPR_OK;
}

ex_expr::exp_return_type AggrExpr::finalizeNullAggr(atp_struct * atp)
{
  if (finalNullExpr_)
    return finalNullExpr_->eval(atp, atp);
  else
    return ex_expr::EXPR_OK;
}


-- this code also will return back from line #871 on the first conversion clause error instead of continuing to the next clause. -- it will also not work correctly if getPCodeMode() is not set.